def attribute_segments(listInputs): dataStack = listInputs[0]# data with values habFile = listInputs[1] # data with habitat codes clumpsFile = listInputs[2] # segments # Populate with stats, so it can be read for the RAT rastergis.populateStats(dataStack) rastergis.populateStats(clumpsFile) rastergis.populateStats(habFile) ratutils.populateImageStats(dataStack, clumpsFile, calcMean=True) # Convert training data to RAT!!! codeStats = [] #list() codeStats.append(rastergis.BandAttStats(band=1, minField='Class')) rastergis.populateRATWithStats(habFile, habFile, codeStats) # Attribute segments with class: yes, so I can compare later !! rastergis.strClassMajority(clumpsFile, habFile, 'Class', 'Class', False)
def populateSegmentsMeanStdDev(inputImage, clumpsImg, colNamePrefix, bandlist, bandnames): """ A function to populate mean and standard deviation values as columns within the attribute table for a single band image. """ # Create an empty list bandStats = [] # Define the statistics to be calculated for the band and the field names # If the input image had mulitple image bands for which you wished to # calculate statistics you need to duplicate this line and change the # band number and field names. #colNamePrefix = 'h'+colNamePrefix for i in range(len(bandlist)): # bandStats.append(rastergis.BandAttStats(band=bandlist[i], minField = colNamePrefix+bandnames[i]+'_Min', maxField = colNamePrefix+bandnames[i]+'_Max', meanField=colNamePrefix+bandnames[i]+'_Mean', stdDevField=colNamePrefix+bandnames[i]+'_StdDev', medianField=colNamePrefix+bandnames[i]+'_Median')) bandStats.append(rastergis.BandAttStats(band=bandlist[i], minField = colNamePrefix+bandnames[i]+'_Min', maxField = colNamePrefix+bandnames[i]+'_Max', meanField=colNamePrefix+bandnames[i]+'_Mean', stdDevField=colNamePrefix+bandnames[i]+'_StdDev')) # Run the RSGISLib command with the input parameters. rastergis.populateRATWithStats(inputImage, clumpsImg, bandStats)
def segmentation(imagery_files, config): dev_mode = config['dev_mode'] for element in imagery_files: inputImage_difference = imagery_files[element][0] inputImage_post = imagery_files[element][1] inputImage_color = inputImage_post nameFile = (element) + "_segmented" clumpsFile = config['k_means_segmentation']['output'][ 'segments'] + nameFile + '.kea' # Run segmentation_file.py algorithm segutils.runShepherdSegmentation( inputImage_difference, clumpsFile, tmpath=config['k_means_segmentation']['temps']['shepherd'], numClusters=config['k_means_segmentation']['params'] ['numClusters'], minPxls=config['k_means_segmentation']['params']['minPxls'], distThres=config['k_means_segmentation']['params']['distThres'], bands=[1], sampling=config['k_means_segmentation']['params']['sampling'], kmMaxIter=config['k_means_segmentation']['params']['kmMaxIter']) # Features extraction and computation of statistical measures # Feature from Image difference bs = [rastergis.BandAttStats(band=1, meanField='ratio_rg_change')] rastergis.populateRATWithStats(inputImage_difference, clumpsFile, bs) bs = [rastergis.BandAttStats(band=2, meanField='ndvi_change')] rastergis.populateRATWithStats(inputImage_difference, clumpsFile, bs) bs = [rastergis.BandAttStats(band=3, meanField='brightness_change')] rastergis.populateRATWithStats(inputImage_difference, clumpsFile, bs) # Feature from post_image bs = [ rastergis.BandAttStats(band=1, meanField='B4'), rastergis.BandAttStats(band=2, meanField='B3'), rastergis.BandAttStats(band=3, meanField='B2'), rastergis.BandAttStats(band=4, meanField='B8'), rastergis.BandAttStats(band=5, meanField='ndvi'), rastergis.BandAttStats(band=6, maxField='slope_max', meanField='slope_mean'), rastergis.BandAttStats(band=7, meanField='mean_height', minField='min_height', maxField='max_height'), rastergis.BandAttStats(band=8, meanField='nd_stdDev'), rastergis.BandAttStats(band=12, meanField='gndvi'), rastergis.BandAttStats(band=13, meanField='brightness') ] rastergis.populateRATWithStats(inputImage_color, clumpsFile, bs) add_Coordinates(clumpsFile) if dev_mode: input_training = imagery_files[element][2] add_Training(clumpsFile, input_training, config) reading_tables(clumpsFile, element, nameFile, config['k_means_segmentation']['output']['tables'], config)
# Check if KEA file exists or needs creating - assume if it exists it has the attribute table already if os.path.exists(outKEAFile) == False: # Rasterize polygon using gdal print('Creating raster') rasterizeCommand = ['gdal_rasterize', '-of', outFormat, '-ot', 'UInt32', '-tr', outXRes, outYRes, '-a', 'MUKEY', inSHPFile, outKEAFile] subprocess.call(rasterizeCommand) # Convert to RAT and add entry 'mukey' using RSGISLib rastergis.populateStats(outKEAFile, True, True) stats2Calc = [rastergis.BandAttStats(band=1, minField='mukey')] rastergis.populateRATWithStats(outKEAFile, outKEAFile, stats2Calc) # Iterate through column names for outColName in args.colname: # Set up name for standard raster file outRasterImage = inSHPFile.replace('.shp', '_raster_' + outColName + '.' + outExt) # Get field from dictionary outColNum = cHorizonFields[outColName.strip()] # JOIN ATTRIBUTES FROM TEXT FILE print('Adding ' + outColName + ' (column ' + str(outColNum) + ') to RAT') # Open SSURGO text files componentFileName = os.path.join(inDIRName, 'tabular', 'comp.txt') chorizonFileName = os.path.join(inDIRName, 'tabular', 'chorizon.txt')
import rsgislib from rsgislib import rastergis ############################################################################################## write stats from texture image to RAT from clumps clumps='S1B_20170728_stack_lee_clip_clumps2.kea' texture='S1B_20170728_stack_lee_clip_txt9.kea' bs = [] bs.append(rastergis.BandAttStats(band=2, minField='VHtxtMin', maxField='VHtxtb1Max', meanField='VHtxtMean', sumField='VHtxtSum', stdDevField='VHtxtStdDev')) rastergis.populateRATWithStats(texture, clumps, bs)
def colour_SM_image(inimage, colourimage, max_value=0.5, band=1): """ Colour image """ try: import rsgislib from rsgislib import imagecalc from rsgislib.imagecalc import BandDefn from rsgislib import rastergis except ImportError: raise ImportError("Could not import RSGISLib, required" " to colour image") if max_value == 0.5: # Add class field: bandDefns = [] bandDefns.append(BandDefn('SM', inimage, band)) expression = [] expression.append('0.00') expression.append('(SM > 0.00) && (SM <= 0.05)? 1 : 0') expression.append('(SM > 0.05) && (SM <= 0.10)? 2 : 0') expression.append('(SM > 0.10) && (SM <= 0.15)? 3 : 0') expression.append('(SM > 0.15) && (SM <= 0.20)? 4 : 0') expression.append('(SM > 0.20) && (SM <= 0.25)? 5 : 0') expression.append('(SM > 0.25) && (SM <= 0.30)? 6 : 0') expression.append('(SM > 0.30) && (SM <= 0.35)? 7 : 0') expression.append('(SM > 0.35) && (SM <= 0.40)? 8 : 0') expression.append('(SM > 0.40) && (SM <= 0.45)? 9 : 0') expression.append('(SM > 0.45) && (SM <= 0.50)? 10 : 0') gdalformat = get_gdal_format(colourimage) datatype = rsgislib.TYPE_8INT temp_dir = tempfile.mkdtemp(prefix='soilscape_upscaling') colourbase = os.path.basename(colourimage) colourbase, colourext = os.path.splitext(colourbase) colour = [] for i in range(11): colour.append( os.path.join(temp_dir, "{}_{}{}".format(colourbase, i + 1, colourext))) imagecalc.bandMath(colour[i], expression[i], gdalformat, datatype, bandDefns) bandDefns = [] for i in range(11): SMclass = 'SM' + str(i) bandDefns.append(BandDefn(SMclass, colour[i], 1)) if i == 0: expression = SMclass else: expression = expression + '+' + SMclass imagecalc.bandMath(colourimage, expression, gdalformat, datatype, bandDefns) shutil.rmtree(temp_dir) # Populate stats (converts to RAT): rastergis.populateStats(colourimage, False, False, True, ratband=1) # Add class field: bandStats = [] bandStats.append(rastergis.BandAttStats(band=1, maxField="SMclass")) rastergis.populateRATWithStats(colourimage, colourimage, bandStats, ratband=1) field = 'SMclass' classcolours = {} colourCat = collections.namedtuple('ColourCat', ['red', 'green', 'blue', 'alpha']) for i in range(11): classcolours[i] = colourCat(red=0, green=0, blue=0, alpha=255) classcolours[0] = colourCat(red=0, green=0, blue=0, alpha=255) classcolours[1] = colourCat(red=165, green=0, blue=38, alpha=255) classcolours[2] = colourCat(red=215, green=48, blue=39, alpha=255) classcolours[3] = colourCat(red=244, green=109, blue=67, alpha=255) classcolours[4] = colourCat(red=253, green=174, blue=97, alpha=255) classcolours[5] = colourCat(red=254, green=224, blue=144, alpha=255) classcolours[6] = colourCat(red=224, green=243, blue=248, alpha=255) classcolours[7] = colourCat(red=171, green=217, blue=233, alpha=255) classcolours[8] = colourCat(red=116, green=173, blue=209, alpha=255) classcolours[9] = colourCat(red=69, green=117, blue=180, alpha=255) classcolours[10] = colourCat(red=49, green=54, blue=149, alpha=255) rastergis.colourClasses(colourimage, field, classcolours) else: raise ValueError('Failed to find colours for specified max_value')
def createMinDataTiles(inputImage, outshp, outclumpsFile, width, height, validDataThreshold, maskIntersect=None, offset=False, force=True, tmpdir='tilestemp', inImgNoDataVal=0.0): """ A function to create a tiling for an input image where each tile has a minimum amount of valid data. Where: :param inputImage: is a string for the image to be tiled :param outshp: is a string for the output shapefile the tiling will be written to (if None a shapefile won't be outputted). :param outclumpsFile: is a string for the output image file containing the tiling :param width: is an int for the width of the tiles :param height: is an int for the height of the tiles :param validDataThreshold: is a float (0-1) with the proportion of valid data needed within a tile. :param force: is a boolean (default True) to delete the output shapefile if it already exists. :param tmpdir: is a string with a temporary directory for temp outputs to be stored (they will be deleted). if tmpdir doesn't exist it will be created and then deleted during the processing. :param inImgNoDataVal: is a float for providing the input image no data value (Default: 0.0) """ tmpPresent = True if not os.path.exists(tmpdir): print("WARNING: tmpdir directory does not exist so creating it...") os.makedirs(tmpdir) tmpPresent = False inImgBaseName = os.path.splitext(os.path.basename(inputImage))[0] tileClumpsImage = os.path.join(tmpdir, inImgBaseName + '_tilesimg.kea') segmentation.generateRegularGrid(inputImage, tileClumpsImage, 'KEA', width, height, offset) rastergis.populateStats(tileClumpsImage, True, True) if not maskIntersect == None: bs = [] bs.append(rastergis.BandAttStats(band=1, maxField='Mask')) rastergis.populateRATWithStats(maskIntersect, tileClumpsImage, bs) ratDS = gdal.Open(tileClumpsImage, gdal.GA_Update) MaskField = rat.readColumn(ratDS, "Mask") Selected = numpy.zeros_like(MaskField, dtype=int) Selected[MaskField == inImgNoDataVal] = 1 rat.writeColumn(ratDS, "Selected", Selected) ratDS = None tileClumpsImageDropClumps = os.path.join( tmpdir, inImgBaseName + '_tilesimgdropped.kea') segmentation.dropSelectedClumps(tileClumpsImage, tileClumpsImageDropClumps, 'KEA', 'Selected') os.remove(tileClumpsImage) tileClumpsImage = tileClumpsImageDropClumps rastergis.populateRATWithPropValidPxls(inputImage, tileClumpsImage, "ValidPxls", inImgNoDataVal) ratDS = gdal.Open(tileClumpsImage, gdal.GA_Update) ValidPxls = rat.readColumn(ratDS, "ValidPxls") Selected = numpy.zeros_like(ValidPxls, dtype=int) NoDataClumps = numpy.zeros_like(ValidPxls, dtype=int) Selected[ValidPxls < validDataThreshold] = 1 NoDataClumps[ValidPxls == 0] = 1 Selected[ValidPxls == 0] = 0 rat.writeColumn(ratDS, "Selected", Selected) rat.writeColumn(ratDS, "NoDataClumps", NoDataClumps) ratDS = None segmentation.mergeSegments2Neighbours(tileClumpsImage, inputImage, outclumpsFile, 'KEA', "Selected", "NoDataClumps") if not outshp is None: tilesDS = gdal.Open(outclumpsFile, gdal.GA_ReadOnly) tilesDSBand = tilesDS.GetRasterBand(1) dst_layername = os.path.splitext(os.path.basename(outshp))[0] #print(dst_layername) drv = ogr.GetDriverByName("ESRI Shapefile") if force and os.path.exists(outshp): drv.DeleteDataSource(outshp) dst_ds = drv.CreateDataSource(outshp) dst_layer = dst_ds.CreateLayer(dst_layername, srs=None) gdal.Polygonize(tilesDSBand, tilesDSBand, dst_layer, -1, [], callback=None) tilesDS = None dst_ds = None if not tmpPresent: shutil.rmtree(tmpdir, ignore_errors=True) else: os.remove(tileClumpsImage)