def isBandAllZeroes(filename, band=0): """ Checks the specified band within a file to see if it is all zeroes. band should be 0 based. Returns True if all zeroes, False otherwise. This function firstly checks the stats if present and uses this and assumes that they are correct. If they are not present, then the band is read and the values determined. """ info = fileinfo.ImageFileStats(filename) maxVal = info[band].max if maxVal is not None: # we have valid stats return maxVal == 0 # otherwise read the thing with rios infiles = applier.FilenameAssociations() infiles.input = filename outfiles = applier.FilenameAssociations() otherArgs = applier.OtherInputs() otherArgs.nonZeroFound = False otherArgs.band = band applier.apply(riosAllZeroes, infiles, outfiles, otherArgs) return not otherArgs.nonZeroFound
def makeSaturationMask(fmaskConfig, radiancefile, outMask): """ Checks the radianceFile and creates a mask with 1's where there is saturation in one of more visible bands. 0 otherwise. The fmaskConfig parameter should be an instance of :class:`fmask.config.FmaskConfig`. This is used to determine which bands are visible. This mask is advisible since the whiteness test Eqn 2. and Equation 6 are affected by saturated pixels and may determine a pixel is not cloud when it is. The format of outMask will be the current RIOS default format. It is assumed that the input radianceFile has values in the range 0-255 and saturated pixels are set to 255. """ inputs = applier.FilenameAssociations() inputs.radiance = radiancefile outputs = applier.FilenameAssociations() outputs.mask = outMask otherargs = applier.OtherInputs() otherargs.radianceBands = fmaskConfig.bands controls = applier.ApplierControls() controls.progress = cuiprogress.GDALProgressBar() applier.apply(riosSaturationMask, inputs, outputs, otherargs, controls=controls)
def runCorrection(insigma, inlinc, inpix, outsigma, thetaref=39.0, nFactor=1.0, filterSize=None): controls = applier.ApplierControls() # Set up input images infiles = applier.FilenameAssociations() infiles.insigma = insigma infiles.inlinc = inlinc infiles.inpix = inpix # Set up output image outfiles = applier.FilenameAssociations() outfiles.outimage = outsigma # Set format for output image outControls = getOutDriver(outsigma) # Set options controls.setOutputDriverName(outControls['gdalFormat']) controls.setCreationOptions(outControls['gdalCOOptions']) controls.setCalcStats(outControls['calcStats']) # Set up parameters otherargs = applier.OtherInputs() otherargs.thetaref = thetaref otherargs.nFactor = nFactor otherargs.filterSize = filterSize # Run correction controls.progress = cuiprogress.CUIProgressBar() applier.apply(castelCorrection, infiles, outfiles, otherargs, controls=controls)
def makeTOAReflectance(infile, mtlFile, anglesfile, outfile): """ Main routine - does the calculation The eqn for TOA reflectance, p, is p = pi * L * d^2 / E * cos(theta) d = earthSunDistance(date) L = image pixel (radiance) E = exoatmospheric irradiance for the band, and theta = solar zenith angle. Assumes infile is radiance values in DN from USGS. mtlFile is the .mtl file. outfile will be created in the default format that RIOS is configured to use and will be top of atmosphere reflectance values *10000. Also assumes that the angles image file is scaled as radians*100, and has layers for satAzimuth, satZenith, sunAzimuth, sunZenith, in that order. """ mtlInfo = config.readMTLFile(mtlFile) spaceCraft = mtlInfo['SPACECRAFT_ID'] date = mtlInfo['DATE_ACQUIRED'] date = date.replace('-', '') inputs = applier.FilenameAssociations() inputs.infile = infile inputs.angles = anglesfile outputs = applier.FilenameAssociations() outputs.outfile = outfile otherinputs = applier.OtherInputs() otherinputs.earthSunDistance = earthSunDistance(date) otherinputs.earthSunDistanceSq = otherinputs.earthSunDistance * otherinputs.earthSunDistance otherinputs.esun = ESUN_LOOKUP[spaceCraft] gains, offsets = readGainsOffsets(mtlInfo) otherinputs.gains = gains otherinputs.offsets = offsets otherinputs.anglesToRadians = 0.01 otherinputs.outNull = 32767 imginfo = fileinfo.ImageInfo(infile) otherinputs.inNull = imginfo.nodataval[0] controls = applier.ApplierControls() if platform.system() in ["Linux", "Darwin"]: controls.setNumThreads(multiprocessing.cpu_count()) controls.setJobManagerType("multiprocessing") controls.progress = cuiprogress.GDALProgressBar() controls.setStatsIgnore(otherinputs.outNull) controls.setCalcStats(False) applier.apply(riosTOA, inputs, outputs, otherinputs, controls=controls) # Explicitly set the null value in the output ds = gdal.Open(outfile, gdal.GA_Update) for i in range(ds.RasterCount): ds.GetRasterBand(i + 1).SetNoDataValue(otherinputs.outNull)
def main(): metadataFile = sys.argv[1] imgFile = sys.argv[2] toaFile = sys.argv[3] d = float(sys.argv[4]) outfile = "%s_envi.exp" % (metadataFile.split('.')[0]) if os.path.exists(toaFile): os.remove(toaFile) (calFactors, solarZenithAngle, eSun, layerNames) = getParams(metadataFile) infiles = applier.FilenameAssociations() outfiles = applier.FilenameAssociations() otherargs = applier.OtherInputs() controls = applier.ApplierControls() infiles.raw = imgFile outfiles.toaFile = toaFile otherargs.calFactors = calFactors otherargs.solarZenithAngle = solarZenithAngle otherargs.pi = 3.14159265358979323846 otherargs.d = d otherargs.eSun = eSun info = fileinfo.ImageInfo(imgFile) xMin = np.floor(info.xMin) xMax = np.ceil(info.xMax) yMin = np.floor(info.yMin) yMax = np.ceil(info.yMax) proj = info.projection transform = info.transform xRes = info.xRes yRes = info.yRes otherargs.outNull = 0 print(otherargs.outNull) controls.setStatsIgnore(otherargs.outNull) controls.setOutputDriverName('GTiff') controls.setCreationOptions(['COMPRESS=LZW']) controls.setCreationOptions(['BIGTIFF=IF_SAFER']) pixgrid = pixelgrid.PixelGridDefn(geotransform=transform, xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, xRes=xRes, yRes=yRes, projection=proj) print(pixgrid) controls.setReferencePixgrid(pixgrid) controls.setLayerNames(layerNames) controls.setWindowXsize(20) controls.setWindowYsize(20) progress = cuiprogress.GDALProgressBar() controls.setProgress(progress) applier.apply(doTOA, infiles, outfiles, otherargs, controls=controls)
def run(data): # Load the machine learning estimators (greenEstimator,nonGreenEstimator,bareEstimator) = load_estimators() # Read in the FC ML Models otherargs = applier.OtherInputs() otherargs.greenEstimator = greenEstimator otherargs.nonGreenEstimator = nonGreenEstimator otherargs.bareEstimator = bareEstimator # Setup file name associations infiles = applier.FilenameAssociations() outfiles = applier.FilenameAssociations() # Loop for each image for feature in data.get("features"): print("Found GeoJSON feature:\n%s" % feature) # Find the filename rel_image_path = feature["properties"].get(AOICLIPPED) print("Processing %s" % rel_image_path) infiles.nbar = "/tmp/input/%s" % rel_image_path outfiles.fc = os.path.splitext("/tmp/output/%s" % rel_image_path)[0] + "_fc.tif" # Set up processing controls controls = applier.ApplierControls() controls.setStatsIgnore(0) controls.setOutputDriverName("GTIFF") controls.setCreationOptions(["COMPRESS=DEFLATE", "ZLEVEL=9", "BIGTIFF=YES", "TILED=YES", "INTERLEAVE=BAND", "NUM_THREADS=ALL_CPUS"]) # Run the model applier.apply(unmixfc, infiles, outfiles, otherargs, controls=controls) print("Feature has an FC image at %s" % outfiles.fc) return data
def makeAnglesImage(templateimg, outfile, nadirLine, extentSunAngles, satAzimuth, imgInfo): """ Make a single output image file of the sun and satellite angles for every pixel in the template image. """ imgInfo = fileinfo.ImageInfo(templateimg) infiles = applier.FilenameAssociations() outfiles = applier.FilenameAssociations() otherargs = applier.OtherInputs() controls = applier.ApplierControls() infiles.img = templateimg outfiles.angles = outfile (ctrLat, ctrLong) = getCtrLatLong(imgInfo) otherargs.R = localRadius(ctrLat) otherargs.nadirLine = nadirLine otherargs.xMin = imgInfo.xMin otherargs.xMax = imgInfo.xMax otherargs.yMin = imgInfo.yMin otherargs.yMax = imgInfo.yMax otherargs.extentSunAngles = extentSunAngles otherargs.satAltitude = 705000 # Landsat nominal altitude in metres otherargs.satAzimuth = satAzimuth otherargs.radianScale = 100 # Store pixel values as (radians * radianScale) controls.setStatsIgnore(500) applier.apply(makeAngles, infiles, outfiles, otherargs, controls=controls)
def run(): """ Run the test """ allOK = True riostestutils.reportStart(TESTNAME) ramp1 = 'ramp1.img' ramp2 = 'ramp2.img' riostestutils.genRampImageFile(ramp1) # Second file is same as first, but shifted 100 pixels right and down. xLeft = riostestutils.DEFAULT_XLEFT + OFFSET_2ND_IMAGE yTop = riostestutils.DEFAULT_YTOP - OFFSET_2ND_IMAGE riostestutils.genRampImageFile(ramp2, xLeft=xLeft, yTop=yTop) # Set up some RIOS calls infiles = applier.FilenameAssociations() outfiles = applier.FilenameAssociations() otherargs = applier.OtherInputs() controls = applier.ApplierControls() # Simplest check. Can we get back the coordinates from a single input file. infiles.img = ramp1 otherargs.tstPixList = [] otherargs.centresList = [] applier.apply(getCoords, infiles, outfiles, otherargs, controls=controls) ok = checkCoords('1 file, overlap=0', otherargs, TSTPIX_1FILE_NOOVERLAP, CENTRES_1FILE_NOOVERLAP) if not ok: allOK = False # Single input file, with an overlap set otherargs.tstPixList = [] otherargs.centresList = [] controls.setOverlap(OLAP) applier.apply(getCoords, infiles, outfiles, otherargs, controls=controls) ok = checkCoords('1 file, overlap=2', otherargs, TSTPIX_1FILE_OVERLAP2, CENTRES_1FILE_OVERLAP2) if not ok: allOK = False # Two input files, with an overlap set infiles.img = [ramp1, ramp2] otherargs.tstPixList = [] otherargs.centresList = [] controls.setOverlap(OLAP) applier.apply(getCoords, infiles, outfiles, otherargs, controls=controls) ok = checkCoords('2 files, overlap=2', otherargs, TSTPIX_2FILE_OVERLAP2, CENTRES_2FILE_OVERLAP2) if not ok: allOK = False # Clean up for filename in [ramp1, ramp2]: os.remove(filename) if allOK: riostestutils.report(TESTNAME, "Passed") return allOK
def update_uid_image(uid_img, chng_img, nxt_scr5_img, clrsky_img, obs_day_since_base, tmp_uid_tile): from rios import applier try: import tqdm progress_bar = rsgislib.TQDMProgressBar() except: from rios import cuiprogress progress_bar = cuiprogress.GDALProgressBar() infiles = applier.FilenameAssociations() infiles.uid_img = uid_img infiles.chng_img = chng_img infiles.nxt_scr5_img = nxt_scr5_img infiles.clrsky_img = clrsky_img outfiles = applier.FilenameAssociations() outfiles.uid_img_out = tmp_uid_tile otherargs = applier.OtherInputs() otherargs.obs_day_since_base = obs_day_since_base aControls = applier.ApplierControls() aControls.progress = progress_bar aControls.omitPyramids = True aControls.calcStats = False def _update_uid_img(info, inputs, outputs, otherargs): """ This is an internal rios function """ uid_img_arr = numpy.array(inputs.uid_img, dtype=numpy.uint32, copy=True) start_year = inputs.uid_img[0] chng_feats = inputs.chng_img[0] new_chng_pxls = numpy.zeros_like(start_year) new_chng_pxls[(start_year == 0) & (chng_feats == 1)] = 1 chng_scr5_year = inputs.uid_img[4] new_scr5_pxls = numpy.zeros_like(chng_scr5_year) new_scr5_pxls[(chng_scr5_year == 0) & (inputs.nxt_scr5_img[0] == 1)] = 1 uid_img_arr[0, new_chng_pxls == 1] = 1970 uid_img_arr[1, new_chng_pxls == 1] = otherargs.obs_day_since_base uid_img_arr[2, inputs.clrsky_img[0] == 1] = 1970 uid_img_arr[3, inputs.clrsky_img[0] == 1] = otherargs.obs_day_since_base uid_img_arr[4, new_scr5_pxls == 1] = 1970 uid_img_arr[5, new_scr5_pxls == 1] = otherargs.obs_day_since_base outputs.uid_img_out = uid_img_arr applier.apply(_update_uid_img, infiles, outfiles, otherargs, controls=aControls)
def calcImgsPxlMode(inputImgs, outputImg, gdalformat, no_data_val=0): """ Function which calculates the mode of a group of images. Warning, this function can be very slow. Use rsgislib.imagecalc.imagePixelColumnSummary :param inputImgs: the list of images :param outputImg: the output image file name and path (will be same dimensions as the input) :param gdalformat: the GDAL image file format of the output image file. """ import scipy.stats from rios import applier rsgis_utils = rsgislib.RSGISPyUtils() datatype = rsgis_utils.getRSGISLibDataTypeFromImg(inputImgs[0]) numpyDT = rsgis_utils.getNumpyDataType(datatype) try: import tqdm progress_bar = rsgislib.TQDMProgressBar() except: from rios import cuiprogress progress_bar = cuiprogress.GDALProgressBar() infiles = applier.FilenameAssociations() infiles.images = inputImgs outfiles = applier.FilenameAssociations() outfiles.outimage = outputImg otherargs = applier.OtherInputs() otherargs.no_data_val = no_data_val otherargs.numpyDT = numpyDT aControls = applier.ApplierControls() aControls.progress = progress_bar aControls.drivername = gdalformat aControls.omitPyramids = True aControls.calcStats = False def _applyCalcMode(info, inputs, outputs, otherargs): """ This is an internal rios function """ image_data = numpy.concatenate(inputs.images, axis=0).astype(numpy.float32) image_data[image_data == otherargs.no_data_val] = numpy.nan mode_arr, count_arr = scipy.stats.mode(image_data, axis=0, nan_policy='omit') outputs.outimage = mode_arr.astype(otherargs.numpyDT) applier.apply(_applyCalcMode, infiles, outfiles, otherargs, controls=aControls)
def predict_for_date(date, input_path, output_path, output_driver='KEA', num_processes=1): """Main function to generate the predicted image. Given an input image containing per-band model coefficients, outputs a multi-band predicted image over the same area. Opening/closing of files, generation of blocks and use of multiprocessing is all handled by RIOS. date: The date to predict in YYYY-MM-DD format. input_path: Path to the input image generated by get_model_coeffs.py. output_path: Path for the output image. output_driver: Short driver name for GDAL, e.g. KEA, GTiff. num_processes: Number of concurrent processes to use.""" # Create object to hold input files infile = applier.FilenameAssociations() infile.coeff_img = input_path # Create object to hold output file outfile = applier.FilenameAssociations() outfile.output_img = output_path # ApplierControls object holds details on how processing should be done app = applier.ApplierControls() # Set output file type app.setOutputDriverName(output_driver) # Use Python's multiprocessing module app.setJobManagerType('multiprocessing') app.setNumThreads(num_processes) # Convert provided date to ordinal ordinal_date = datetime.strptime(date, '%Y-%m-%d').toordinal() # Additional arguments - have to be passed as a single object other_args = applier.OtherInputs() other_args.date_to_predict = ordinal_date # Get band names try: input_img = fileinfo.ImageInfo(infile.coeff_img) except: sys.exit('Could not find input image.') layer_names = np.unique([name.split('_')[0] for name in input_img.lnames]) app.setLayerNames(layer_names) applier.apply(gen_prediction, infile, outfile, otherArgs=other_args, controls=app)
def run(): """ Run the test """ riostestutils.reportStart(TESTNAME) # Create a multi-band file with some data in it. tstfile = 'multilayer.img' numBands = 5 ds = riostestutils.createTestFile(tstfile, numBands=numBands) onelayerArr = riostestutils.genRampArray() lyrList = [] for i in range(numBands): lyr = (onelayerArr + 1) band = ds.GetRasterBand(i + 1) band.WriteArray(lyr) lyrList.append(lyr) del ds stack = numpy.array(lyrList) # Sum of all pixels in bands 2 & 4 layerList = [2, 4] correctSum = sum([(stack[i - 1].astype(numpy.float64)).sum() for i in layerList]) # Now do it using RIOS infiles = applier.FilenameAssociations() outfiles = applier.FilenameAssociations() otherargs = applier.OtherInputs() controls = applier.ApplierControls() infiles.img = tstfile controls.selectInputImageLayers(layerList) otherargs.total = 0 # We will use this to check the number of layers being read otherargs.numLayers = len(layerList) otherargs.numLayersIsOK = True applier.apply(doSum, infiles, outfiles, otherargs, controls=controls) if correctSum != otherargs.total: riostestutils.report( TESTNAME, "Totals do not match: %s != %s" % (correctSum, otherargs.total)) ok = False else: riostestutils.report(TESTNAME, "Passed") ok = True os.remove(tstfile) return ok
def apply_gain_to_img(input_img, output_img, gdal_format, gain, np_dtype, in_no_data, out_no_data): """ Apply a gain scale factor to an input image and save as an integer dataset. :param input_img: Input image file :param output_img: Output image file :param gdal_format: GDAL image format for output image :param gain: scale factor to be applied to the input image :param np_dtype: the numpy datatype for the output data (e.g., numpy.int16 or numpy.uint16) :param in_no_data: the input image no data value :param out_no_data: the no data value to be used for the output image """ try: import tqdm progress_bar = TQDMProgressBar() except: progress_bar = cuiprogress.GDALProgressBar() def _apply_img_gain(info, inputs, outputs, otherargs): # Internal Function... out_img_arr = numpy.zeros_like(inputs.image, dtype=otherargs.np_dtype) out_img_arr[...] = numpy.around((inputs.image * otherargs.gain), 0) out_img_arr[inputs.image == otherargs.in_no_data] = otherargs.out_no_data outputs.outimage = out_img_arr infiles = applier.FilenameAssociations() infiles.image = input_img outfiles = applier.FilenameAssociations() outfiles.outimage = output_img otherargs = applier.OtherInputs() otherargs.gain = gain otherargs.np_dtype = np_dtype otherargs.in_no_data = in_no_data otherargs.out_no_data = out_no_data aControls = applier.ApplierControls() aControls.progress = progress_bar aControls.drivername = gdal_format aControls.omitPyramids = True aControls.calcStats = False if gdal_format == 'GTIFF': aControls.creationoptions = GTIFF_CREATION_OPTS applier.apply(_apply_img_gain, infiles, outfiles, otherargs, controls=aControls)
def calcWSG84PixelArea(img, out_img, scale=10000, gdalformat='KEA'): """ A function which calculates the area (in metres) of the pixel projected in WGS84. :param img: input image, for which the per-pixel area will be calculated. :param out_img: output image file. :param scale: scale the output area to unit of interest. Scale=10000(Ha), Scale=1(sq m), Scale=1000000(sq km), Scale=4046.856(Acre), Scale=2590000(sq miles), Scale=0.0929022668(sq feet) """ import rsgislib.tools from rios import applier try: import tqdm progress_bar = rsgislib.TQDMProgressBar() except: from rios import cuiprogress progress_bar = cuiprogress.GDALProgressBar() rsgis_utils = rsgislib.RSGISPyUtils() x_res, y_res = rsgis_utils.getImageRes(img) infiles = applier.FilenameAssociations() infiles.img = img outfiles = applier.FilenameAssociations() outfiles.outimage = out_img otherargs = applier.OtherInputs() otherargs.x_res = x_res otherargs.y_res = y_res otherargs.scale = float(scale) aControls = applier.ApplierControls() aControls.progress = progress_bar aControls.drivername = gdalformat aControls.omitPyramids = False aControls.calcStats = False def _calcPixelArea(info, inputs, outputs, otherargs): xBlock, yBlock = info.getBlockCoordArrays() x_res_arr = numpy.zeros_like(yBlock, dtype=float) x_res_arr[...] = otherargs.x_res y_res_arr = numpy.zeros_like(yBlock, dtype=float) y_res_arr[...] = otherargs.y_res x_res_arr_m, y_res_arr_m = rsgislib.tools.degrees_to_metres( yBlock, x_res_arr, y_res_arr) outputs.outimage = numpy.expand_dims( (x_res_arr_m * y_res_arr_m) / otherargs.scale, axis=0) applier.apply(_calcPixelArea, infiles, outfiles, otherargs, controls=aControls)
def call_min_max_filter(infile, outfile, min=-1, max=1, block_size=512, n_threads=5): """ Function caller to min_max_filter which set values below the minimum or above the maximum to nan Args: infile: full path to the input file outfile: full path to the output file min: minimum allowed value max: maximum allowed value block_size: block size for RIOS block wise processing n_threads: number of threads Returns: GeoTiff with extreme values set to nan """ # inputs inputs = applier.FilenameAssociations() inputs.image = infile # parameters otherargs = applier.OtherInputs() otherargs.min = min otherargs.max = max # controls controls = applier.ApplierControls() controls.setWindowXsize(block_size) controls.setWindowYsize(block_size) controls.progress = cuiprogress.CUIProgressBar() controls.setOutputDriverName("GTiff") controls.setCreationOptions(["COMPRESS=NONE"]) controls.setCreationOptions(["INTERLEAVE=PIXEL"]) # parallelization currently not working due to issues with pickeling if n_threads > 1: # parallel.jobmanager.getAvailableJobManagerTypes() controls.setNumThreads(n_threads) controls.setJobManagerType('subproc') # output file outfiles = applier.FilenameAssociations() outfiles.outimage = outfile applier.apply(min_max_filter, inputs, outfiles, otherargs, controls=controls)
def findminclumpval(clumpsImg, valsImg, valBand, out_col): import rsgislib.rastergis import rsgislib.rastergis.ratutils from rios import applier import numpy try: import tqdm progress_bar = rsgislib.TQDMProgressBar() except: from rios import cuiprogress progress_bar = cuiprogress.GDALProgressBar() n_clumps = rsgislib.rastergis.getRATLength(clumpsImg) min_vals = numpy.zeros(n_clumps, dtype=int) infiles = applier.FilenameAssociations() infiles.clumpsImg = clumpsImg infiles.valsImg = valsImg outfiles = applier.FilenameAssociations() otherargs = applier.OtherInputs() otherargs.min_vals = min_vals otherargs.valBand = valBand - 1 aControls = applier.ApplierControls() aControls.progress = progress_bar aControls.omitPyramids = True aControls.calcStats = False def _findMinVals(info, inputs, outputs, otherargs): """ This is an internal rios function """ unqClumpVals = numpy.unique(inputs.clumpsImg) clumpValsFlat = inputs.clumpsImg.flatten() for clump in unqClumpVals: pxl_vals = inputs.valsImg[otherargs.valBand].flatten()[ clumpValsFlat == clump] pxl_vals = pxl_vals[pxl_vals > 0] if pxl_vals.shape[0] > 0: clump_min_val = pxl_vals.min() if otherargs.min_vals[clump] == 0: otherargs.min_vals[clump] = clump_min_val else: if clump_min_val < otherargs.min_vals[clump]: otherargs.min_vals[clump] = clump_min_val applier.apply(_findMinVals, infiles, outfiles, otherargs, controls=aControls) rsgislib.rastergis.ratutils.setColumnData(clumpsImg, out_col, min_vals)
def rescale_unmixing_results(input_img, output_img, gdalformat, scale_factor=1000): """ A function which rescales an output from a spectral unmixing (e.g., rsgislib.imagecalc.specunmixing.calc_unconstrained_unmixing) so that negative values are removed and each pixel sums to 1. :param inputImg: Input image with the spectral unmixing result (pixels need to range from 0-1) :param outputImg: Output image with the result of the rescaling (pixel values will be in range 0-1) :param gdalformat: the file format of the output file. """ try: import tqdm progress_bar = rsgislib.TQDMProgressBar() except: progress_bar = cuiprogress.GDALProgressBar() infiles = applier.FilenameAssociations() infiles.image = input_img outfiles = applier.FilenameAssociations() outfiles.outimage = output_img otherargs = applier.OtherInputs() otherargs.scale_factor = scale_factor aControls = applier.ApplierControls() aControls.progress = progress_bar aControls.drivername = gdalformat aControls.omitPyramids = True aControls.calcStats = False def _applyUnmixRescale(info, inputs, outputs, otherargs): """ This is an internal rios function """ inputs.image[inputs.image < 0] = 0 if otherargs.scale_factor == 1: outputs.outimage = numpy.zeros_like(inputs.image, dtype=numpy.float32) else: outputs.outimage = numpy.zeros_like(inputs.image, dtype=numpy.uint16) for idx in range(inputs.image.shape[0]): outputs.outimage[idx] = (inputs.image[idx] / numpy.sum( inputs.image, axis=0)) * otherargs.scale_factor applier.apply(_applyUnmixRescale, infiles, outfiles, otherargs, controls=aControls)
def exec(input_dir, model_filepath, output_filepath): ts_utils.mkdirp(ts_utils.basedir(output_filepath)) images = ts_utils.get_filenames(input_dir, \ filter_prefix='ts_b', filter_suffix='.vrt') model = load_model(model_filepath) infiles = applier.FilenameAssociations() outfiles = applier.FilenameAssociations() otherargs = applier.OtherInputs() otherargs.n_images = len(images) for i in range(0, otherargs.n_images): key = 'img' + str(i) setattr(infiles, key, images[i]) outfiles.result = output_filepath otherargs.model = model def genmap(info, inputs, outputs, otherargs): size_x, size_y = info.getBlockSize() outputs.result = np.empty((1, size_y, size_x), dtype=np.uint16) print("Processing status " + str(info.getPercent()) + "%") input_ts = [] for i in range(0, otherargs.n_images): key = 'img' + str(i) input_img = getattr(inputs, key) input_img = np.transpose(input_img) shape = input_img.shape input_img = input_img.reshape(shape[0] * shape[1], shape[2]) input_ts.append(input_img) input_ts = np.dstack(input_ts) predicted = np.argmax(otherargs.model.predict(input_ts), axis=1).astype(np.uint16) outputs.result = np.transpose( np.reshape(predicted, (size_x, size_y, 1))) controls = applier.ApplierControls() controls.setNumThreads(1) controls.setJobManagerType('multiprocessing') applier.apply(genmap, infiles, outfiles, otherargs, controls=controls)
def calc_ratio_img(vv_img, vh_img, out_img, gdal_format): """ A function which calculates the ratio image of the VV/HV polarisations. :param vv_img: GDAL image with VV polarisation :param vh_img: GDAL image with VH polarisation :param out_img: Output image file. :param gdal_format: Output image file format. """ try: import tqdm progress_bar = TQDMProgressBar() except: progress_bar = cuiprogress.GDALProgressBar() def _apply_calc_pol_ratio(info, inputs, outputs, otherargs): # Internal Function... ratio_img_arr = numpy.where( (numpy.isfinite(inputs.vv_img) & (inputs.vv_img > 0.0) & numpy.isfinite(inputs.vh_img) & (inputs.vh_img > 0.0)), inputs.vv_img / inputs.vh_img, 0.0) ratio_img_arr[numpy.isnan(ratio_img_arr)] = 0.0 ratio_img_arr[numpy.isinf(ratio_img_arr)] = 0.0 outputs.outimage = ratio_img_arr infiles = applier.FilenameAssociations() infiles.vv_img = vv_img infiles.vh_img = vh_img outfiles = applier.FilenameAssociations() outfiles.outimage = out_img otherargs = applier.OtherInputs() aControls = applier.ApplierControls() aControls.progress = progress_bar aControls.drivername = gdal_format aControls.omitPyramids = True aControls.calcStats = False if gdal_format == 'GTIFF': aControls.creationoptions = GTIFF_CREATION_OPTS applier.apply(_apply_calc_pol_ratio, infiles, outfiles, otherargs, controls=aControls) logger.debug("Created ratio output image file: {}".format(out_img))
def calc_valid_msk(input_img, output_img, gdal_format, no_data_val): """ A function to create a valid data mask image. :param input_img: Input image file :param output_img: Output image file :param gdal_format: GDAL image format for output image :param no_data_val: the input image no data value """ try: import tqdm progress_bar = TQDMProgressBar() except: progress_bar = cuiprogress.GDALProgressBar() def _calc_valid_msk(info, inputs, outputs, otherargs): # Internal Function... input_shp = inputs.image.shape outputs.output_img = numpy.zeros((1, input_shp[1], input_shp[2]), dtype=numpy.uint8) for n in range(input_shp[0]): outputs.output_img[0] = numpy.where( inputs.image[n] != otherargs.no_data_val, 1, outputs.output_img[0]) infiles = applier.FilenameAssociations() infiles.image = input_img outfiles = applier.FilenameAssociations() outfiles.output_img = output_img otherargs = applier.OtherInputs() otherargs.no_data_val = no_data_val aControls = applier.ApplierControls() aControls.progress = progress_bar aControls.drivername = gdal_format aControls.omitPyramids = True aControls.calcStats = False if gdal_format == 'GTIFF': aControls.creationoptions = GTIFF_CREATION_OPTS applier.apply(_calc_valid_msk, infiles, outfiles, otherargs, controls=aControls)
def apply_rf_image(in_data_stack, out_image, rf_model, nodata_vals): """ Apply Random Forests model generated by scikit-learn to an input data stack and output image Requires: * in_data_stack - stack of all layers * out_image - output image * rf_model - model produced by scikit-learn * nodata_vals - array with a no-data value for each band Returns the mean and standard deviation of the output (predicted) image. """ # Apply to image infiles = applier.FilenameAssociations() infiles.inimage = in_data_stack outfiles = applier.FilenameAssociations() outfiles.outimage = out_image otherargs = applier.OtherInputs() otherargs.rf = rf_model otherargs.predict_sm = None # Array to store output SM # Pass in list of no data values for each layer otherargs.nodata_vals_list = nodata_vals controls = applier.ApplierControls() controls.setOutputDriverName( upscaling_utilities.get_gdal_format(out_image)) controls.setCalcStats(False) controls.progress = cuiprogress.CUIProgressBar() applier.apply(_rios_apply_rf_image, infiles, outfiles, otherargs, controls=controls) average_sm_predict = otherargs.predict_sm.mean() sd_sm_predict = otherargs.predict_sm.std() return average_sm_predict, sd_sm_predict
def createPlots(imageA, imageB, outPlot, bandA=1, bandB=1, labelA=None, labelB=None, plotMin=None, plotMax=None, scale=1, independentXY=False): controls = applier.ApplierControls() # Set up input images infiles = applier.FilenameAssociations() infiles.imageA = imageA infiles.imageB = imageB outfiles = applier.FilenameAssociations() # Set up parameters otherargs = applier.OtherInputs() otherargs.bandA = bandA - 1 otherargs.bandB = bandB - 1 otherargs.outdataA = numpy.array([], dtype=numpy.float32) otherargs.outdataB = numpy.array([], dtype=numpy.float32) otherargs.scale = scale # Get data print('Extracting data') controls.progress = cuiprogress.CUIProgressBar() # If necessary reproject image B to image A controls.setReferenceImage(infiles.imageA) controls.setResampleMethod('near') applier.apply(getData, infiles, outfiles, otherargs, controls=controls) # Produce plot print('Saving plot') plotData(otherargs.outdataA, otherargs.outdataB, outPlot, labelA, labelB, plotMin, plotMax, independentXY)
def run_s2cloudless(input_img, out_prob_img, out_cloud_msk, gdalformat): """ Function which runs the S2Cloudless methods in 256 x 256 pixel blocks across an image. :param input_img: input sentinel-2 image with all 13 bands. :param output_img: the output image cloud mask :param gdalformat: the GDAL image file format of the output image file. """ s2_pxl_cloud_detect = S2PixelCloudDetector(all_bands=True) infiles = applier.FilenameAssociations() infiles.s2image = input_img outfiles = applier.FilenameAssociations() outfiles.out_prob_img = out_prob_img outfiles.out_cloud_msk = out_cloud_msk otherargs = applier.OtherInputs() otherargs.s2_pxl_cloud_detect = s2_pxl_cloud_detect aControls = applier.ApplierControls() aControls.progress = cuiprogress.CUIProgressBar() aControls.drivername = gdalformat aControls.omitPyramids = True aControls.calcStats = False def _applyS2Cloudless(info, inputs, outputs, otherargs): """ This is an internal rios function """ # Current shape is: [13 x n x m] # Image data needs to be in shape [1 x n x m x 13] s2img_reshp = numpy.expand_dims(numpy.stack([inputs.s2image[0], inputs.s2image[1], inputs.s2image[2], inputs.s2image[3], inputs.s2image[4], inputs.s2image[5], inputs.s2image[6], inputs.s2image[7], inputs.s2image[8], inputs.s2image[9], inputs.s2image[10], inputs.s2image[11], inputs.s2image[12]], axis=2), axis=0) s2img_reshp_toa = s2img_reshp/10000.0 outputs.out_prob_img = otherargs.s2_pxl_cloud_detect.get_cloud_probability_maps(s2img_reshp_toa) outputs.out_cloud_msk = otherargs.s2_pxl_cloud_detect.get_mask_from_prob(outputs.out_prob_img) applier.apply(_applyS2Cloudless, infiles, outfiles, otherargs, controls=aControls)
def findImgCorners(img, imgInfo): """ Find the corners of the data within the given template image Return a numpy array of (x, y) coordinates. The array has 2 columns, for X and Y. Each row is a corner, in the order: top-left, top-right, bottom-left, bottom-right. Uses RIOS to pass through the image searching for non-null data, and find the extremes. Assumes we are working with a full-swathe Landsat image. Each list element is a numpy array of (x, y) """ infiles = applier.FilenameAssociations() outfiles = applier.FilenameAssociations() otherargs = applier.OtherInputs() infiles.img = img otherargs.tl = None otherargs.tr = None otherargs.bl = None otherargs.br = None otherargs.nullVal = imgInfo.nodataval[0] if otherargs.nullVal is None: otherargs.nullVal = 0 applier.apply(findCorners, infiles, outfiles, otherargs) corners = numpy.array([ otherargs.tl, otherargs.tr, otherargs.bl, otherargs.br, ]) return corners
def rescaleUnmixingResults(inputImg, outputImg, gdalformat): """ A function which rescales an output from a spectral unmixing (e.g., rsgislib.imagecalc.conSum1LinearSpecUnmix) so that negative values are removed and each pixel sums to 1. :param inputImg: Input image with the spectral unmixing result (pixels need to range from 0-1) :param outputImg: Output image with the result of the rescaling (pixel values will be in range 0-1) :param gdalformat: the file format of the output file. """ infiles = applier.FilenameAssociations() infiles.image = inputImg outfiles = applier.FilenameAssociations() outfiles.outimage = outputImg otherargs = applier.OtherInputs() aControls = applier.ApplierControls() aControls.progress = cuiprogress.CUIProgressBar() aControls.drivername = gdalformat aControls.omitPyramids = True aControls.calcStats = False def _applyUnmixRescale(info, inputs, outputs, otherargs): """ This is an internal rios function """ inputs.image[inputs.image < 0] = 0 outputs.outimage = numpy.zeros_like(inputs.image, dtype=numpy.float32) for idx in range(inputs.image.shape[0]): outputs.outimage[idx] = inputs.image[idx] / numpy.sum(inputs.image, axis=0) applier.apply(_applyUnmixRescale, infiles, outfiles, otherargs, controls=aControls)
def calcMeanWithRiosApplier(imgfile, vecfile): """ Use RIOS's vector facilities, through the applier, to calculate the mean of the image within the vector """ infiles = applier.FilenameAssociations() outfiles = applier.FilenameAssociations() controls = applier.ApplierControls() otherargs = applier.OtherInputs() infiles.img = imgfile infiles.vec = vecfile controls.setBurnValue(-1) controls.setVectorDatatype(numpy.int16) otherargs.total = 0 otherargs.count = 0 applier.apply(meanWithinVec, infiles, outfiles, otherargs, controls=controls) mean = otherargs.total / otherargs.count return mean
def get_ST_model_coeffs(json_fp, output_fp, gdalformat='KEA', bands=None, num_processes=1, model_type='Lasso', alpha=20, cv=False): """ Main function to run to generate the output image. Given an input JSON file and an output file path, generates a multi-band output image where each pixel contains the model details for that pixel. Opening/closing of files, generation of blocks and use of multiprocessing is all handled by RIOS. :param json_fp: Path to JSON file of date/filepath pairs. :param output_fp: Path for output file. :param gdalformat: Short driver name for GDAL, e.g. KEA, GTiff. :param bands: List of GDAL band numbers to use in the analysis, e.g. [2, 5, 7]. :param num_processes: Number of concurrent processes to use. :param model_type: Either 'Lasso' or 'OLS'. The type of model fitting to use. OLS will be faster, but more likely to overfit. Both types will adjust the number of model coefficients depending on the number of observations. :param alpha: If using Lasso fitting, the alpha value controls the degree of penalization of the coefficients. The lower the value, the closer the model will fit the data. For surface reflectance, a value of around 20 (the default) is usually OK. :param cv: If using Lasso fitting, you can use cross validation to choose the value of alpha by setting cv=True. However, this is not recommended and will substantially increase run time. """ paths = [] dates = [] try: # Open and read JSON file containing date:filepath pairs with open(json_fp) as json_file: image_list = json.load(json_file) for date, img_path in image_list.items(): dates.append(datetime.strptime(date, '%Y-%m-%d').toordinal()) paths.append(img_path) except FileNotFoundError: print('Could not find the provided JSON file.') sys.exit() except json.decoder.JSONDecodeError as e: print('There is an error in the provided JSON file: {}'.format(e)) sys.exit() # Create object to hold input files infiles = applier.FilenameAssociations() infiles.images = paths # Create object to hold output file outfiles = applier.FilenameAssociations() outfiles.outimage = output_fp # ApplierControls object holds details on how processing should be done app = applier.ApplierControls() # Set window size to 1 because we are working per-pixel app.setWindowXsize(1) app.setWindowYsize(1) # Set output file type app.setOutputDriverName(gdalformat) # Set progress try: import tqdm progress_bar = rsgislib.TQDMProgressBar() except: progress_bar = cuiprogress.GDALProgressBar() app.progress = progress_bar # Set that pyramids and statistics are not calculated. app.omitPyramids = True app.calcStats = False # Use Python's multiprocessing module app.setJobManagerType('multiprocessing') app.setNumThreads(num_processes) # Open first image in list to use as a template template_image = fileinfo.ImageInfo(infiles.images[0]) # Get no data value nodata_val = template_image.nodataval[0] if not bands: # No bands specified - default to all num_bands = template_image.rasterCount bands = [i for i in range(1, num_bands + 1)] else: # If a list of bands is provided # Number of bands determines things like the size of the output array num_bands = len(bands) # Need to tell the applier to only use the specified bands app.selectInputImageLayers(bands) # Create list of actual names full_names = [template_image.layerNameFromNumber(i) for i in bands] template_image = None # Set up output layer names based on band numbers layer_names = gen_layer_names(full_names) app.setLayerNames(layer_names) # Additional arguments - have to be passed as a single object other_args = applier.OtherInputs() other_args.dates = dates other_args.num_bands = num_bands other_args.nodata_val = nodata_val other_args.model_type = model_type other_args.alpha = alpha other_args.cv = cv try: applier.apply(gen_per_band_models, infiles, outfiles, otherArgs=other_args, controls=app) except RuntimeError as e: print('There was an error processing the images: {}'.format(e)) print('Do all images in the JSON file exist?')
def apply_sklearn_classifer(classTrainInfo, skClassifier, imgMask, imgMaskVal, imgFileInfo, outputImg, gdalformat, classClrNames=True): """ This function uses a trained classifier and applies it to the provided input image. :param classTrainInfo: dict (where the key is the class name) of rsgislib.classification.ClassSimpleInfoObj objects which will be used to train the classifier (i.e., train_sklearn_classifier()), provide pixel value id and RGB class values. :param skClassifier: a trained instance of a scikit-learn classifier (e.g., use train_sklearn_classifier or train_sklearn_classifer_gridsearch) :param imgMask: is an image file providing a mask to specify where should be classified. Simplest mask is all the valid data regions (rsgislib.imageutils.genValidMask) :param imgMaskVal: the pixel value within the imgMask to limit the region to which the classification is applied. Can be used to create a heirachical classification. :param imgFileInfo: a list of rsgislib.imageutils.ImageBandInfo objects (also used within rsgislib.imageutils.extractZoneImageBandValues2HDF) to identify which images and bands are to be used for the classification so it adheres to the training data. :param outputImg: output image file with the classification. Note. by default a colour table and class names column is added to the image. If an error is produced use HFA or KEA formats. :param gdalformat: is the output image format - all GDAL supported formats are supported. :param classClrNames: default is True and therefore a colour table will the colours specified in classTrainInfo and a ClassName column (from imgFileInfo) will be added to the output file. """ infiles = applier.FilenameAssociations() infiles.imageMask = imgMask numClassVars = 0 for imgFile in imgFileInfo: infiles.__dict__[imgFile.name] = imgFile.fileName numClassVars = numClassVars + len(imgFile.bands) outfiles = applier.FilenameAssociations() outfiles.outimage = outputImg otherargs = applier.OtherInputs() otherargs.classifier = skClassifier otherargs.mskVal = imgMaskVal otherargs.numClassVars = numClassVars otherargs.imgFileInfo = imgFileInfo try: import tqdm progress_bar = rsgislib.TQDMProgressBar() except: progress_bar = cuiprogress.GDALProgressBar() aControls = applier.ApplierControls() aControls.progress = progress_bar aControls.drivername = gdalformat aControls.omitPyramids = True aControls.calcStats = False # RIOS function to apply classifer def _applySKClassifier(info, inputs, outputs, otherargs): """ Internal function for rios applier. Used within applyClassifer. """ outClassVals = numpy.zeros_like(inputs.imageMask, dtype=numpy.uint32) if numpy.any(inputs.imageMask == otherargs.mskVal): outClassVals = outClassVals.flatten() imgMaskVals = inputs.imageMask.flatten() classVars = numpy.zeros( (outClassVals.shape[0], otherargs.numClassVars), dtype=numpy.float) # Array index which can be used to populate the output array following masking etc. ID = numpy.arange(imgMaskVals.shape[0]) classVarsIdx = 0 for imgFile in otherargs.imgFileInfo: imgArr = inputs.__dict__[imgFile.name] for band in imgFile.bands: classVars[..., classVarsIdx] = imgArr[(band - 1)].flatten() classVarsIdx = classVarsIdx + 1 classVars = classVars[imgMaskVals == otherargs.mskVal] ID = ID[imgMaskVals == otherargs.mskVal] predClass = otherargs.classifier.predict(classVars) outClassVals[ID] = predClass outClassVals = numpy.expand_dims(outClassVals.reshape( (inputs.imageMask.shape[1], inputs.imageMask.shape[2])), axis=0) outputs.outimage = outClassVals print("Applying the Classifier") applier.apply(_applySKClassifier, infiles, outfiles, otherargs, controls=aControls) print("Completed") rsgislib.rastergis.populateStats(clumps=outputImg, addclrtab=True, calcpyramids=True, ignorezero=True) if classClrNames: ratDataset = gdal.Open(outputImg, gdal.GA_Update) red = rat.readColumn(ratDataset, 'Red') green = rat.readColumn(ratDataset, 'Green') blue = rat.readColumn(ratDataset, 'Blue') ClassName = numpy.empty_like(red, dtype=numpy.dtype('a255')) for classKey in classTrainInfo: print("Apply Colour to class \'" + classKey + "\'") red[classTrainInfo[classKey].id] = classTrainInfo[classKey].red green[classTrainInfo[classKey].id] = classTrainInfo[classKey].green blue[classTrainInfo[classKey].id] = classTrainInfo[classKey].blue ClassName[classTrainInfo[classKey].id] = classKey rat.writeColumn(ratDataset, "Red", red) rat.writeColumn(ratDataset, "Green", green) rat.writeColumn(ratDataset, "Blue", blue) rat.writeColumn(ratDataset, "ClassName", ClassName) ratDataset = None
print( "Warning: the script used to generate the model couldn't be saved onto datasource." ) elif mode == 'predict': ### TODO: generalize predict process try: model = load_model(fname_acc) print("Loaded model from disk.") except OSError: print( "Error: cannot load model's files! Have you ever perform training?" ) exit(0) infiles = applier.FilenameAssociations() outfiles = applier.FilenameAssociations() otherargs = applier.OtherInputs() infiles.raster = fname_raster outfiles.map = fname_output otherargs.model = model def genmap(info, inputs, outputs, otherargs): size_x, size_y = info.getBlockSize() outputs.map = np.empty((1, size_y, size_x), dtype=np.uint16) inputs.raster = np.transpose(inputs.raster) inputs.raster = inputs.raster.reshape( inputs.raster.shape[0] * inputs.raster.shape[1], inputs.raster.shape[2]) tensor = np.dstack([ inputs.raster, ]) predict = np.argmax(otherargs.model.predict(tensor),
def apply_keras_pixel_classifier(classTrainInfo, keras_cls_mdl, imgMask, imgMaskVal, imgFileInfo, outClassImg, gdalformat, pred_batch_size=32, classClrNames=True): """ This function applies a trained single pixel keras model to an image. The function train_keras_pixel_classifer can be used to train such as model. The output image will contain the hard membership of the predicted class. :param classTrainInfo: dict (where the key is the class name) of rsgislib.classification.ClassInfoObj objects which will be used to train the classifier (i.e., train_keras_pixel_classifer()), provide pixel value id and RGB class values. :param keras_cls_mdl: a trained keras model object, with a input dimensions equivlent to the number of image bands specified in the imgFileInfo input and output layer which provides an output array of the length of the number of classes. :param imgMask: is an image file providing a mask to specify where should be classified. Simplest mask is all the valid data regions (rsgislib.imageutils.genValidMask) :param imgMaskVal: the pixel value within the imgMask to limit the region to which the classification is applied. Can be used to create a heirachical classification. :param imgFileInfo: a list of rsgislib.imageutils.ImageBandInfo objects (also used within rsgislib.imageutils.extractZoneImageBandValues2HDF) to identify which images and bands are to be used for the classification so it adheres to the training data. :param outClassImg: Output image which will contain the hard classification. :param gdalformat: is the output image format - all GDAL supported formats are supported. :param pred_batch_size: the batch size used for the classification. :param classClrNames: default is True and therefore a colour table will the colours specified in ClassInfoObj and a ClassName (from classTrainInfo) column will be added to the output file. """ def _applyKerasPxlClassifier(info, inputs, outputs, otherargs): outClassIdVals = numpy.zeros_like(inputs.imageMask, dtype=numpy.uint16) if numpy.any(inputs.imageMask == otherargs.mskVal): n_pxls = inputs.imageMask.shape[1] * inputs.imageMask.shape[2] outClassIdVals = outClassIdVals.flatten() imgMaskVals = inputs.imageMask.flatten() classVars = numpy.zeros((n_pxls, otherargs.numClassVars), dtype=numpy.float) # Array index which can be used to populate the output array following masking etc. ID = numpy.arange(imgMaskVals.shape[0]) classVarsIdx = 0 for imgFile in otherargs.imgFileInfo: imgArr = inputs.__dict__[imgFile.name] for band in imgFile.bands: classVars[..., classVarsIdx] = imgArr[(band - 1)].flatten() classVarsIdx = classVarsIdx + 1 classVars = classVars[imgMaskVals == otherargs.mskVal] ID = ID[imgMaskVals == otherargs.mskVal] preds_idxs = numpy.argmax(otherargs.classifier.predict( classVars, batch_size=otherargs.pred_batch_size), axis=1) preds_cls_ids = numpy.zeros_like(preds_idxs, dtype=numpy.uint16) for cld_id, idx in zip(otherargs.cls_id_lut, numpy.arange(0, len(otherargs.cls_id_lut))): preds_cls_ids[preds_idxs == idx] = cld_id outClassIdVals[ID] = preds_cls_ids outClassIdVals = numpy.expand_dims(outClassIdVals.reshape( (inputs.imageMask.shape[1], inputs.imageMask.shape[2])), axis=0) outputs.outclsimage = outClassIdVals infiles = applier.FilenameAssociations() infiles.imageMask = imgMask numClassVars = 0 for imgFile in imgFileInfo: infiles.__dict__[imgFile.name] = imgFile.fileName numClassVars = numClassVars + len(imgFile.bands) n_classes = len(classTrainInfo) cls_id_lut = numpy.zeros(n_classes) for clsname in classTrainInfo: if classTrainInfo[clsname].id >= n_classes: raise ( "ClassInfoObj '{}' id ({}) is not consecutive starting from 0." .format(clsname, classTrainInfo[clsname].id)) cls_id_lut[classTrainInfo[clsname].id] = classTrainInfo[clsname].out_id outfiles = applier.FilenameAssociations() outfiles.outclsimage = outClassImg otherargs = applier.OtherInputs() otherargs.classifier = keras_cls_mdl otherargs.pred_batch_size = pred_batch_size otherargs.mskVal = imgMaskVal otherargs.numClassVars = numClassVars otherargs.imgFileInfo = imgFileInfo otherargs.n_classes = n_classes otherargs.cls_id_lut = cls_id_lut try: import tqdm progress_bar = rsgislib.TQDMProgressBar() except: progress_bar = cuiprogress.GDALProgressBar() aControls = applier.ApplierControls() aControls.progress = progress_bar aControls.drivername = gdalformat aControls.omitPyramids = True aControls.calcStats = False print("Applying the Classifier") applier.apply(_applyKerasPxlClassifier, infiles, outfiles, otherargs, controls=aControls) print("Completed Classification") if classClrNames: rsgislib.rastergis.populateStats(outClassImg, addclrtab=True, calcpyramids=True, ignorezero=True) ratDataset = gdal.Open(outClassImg, gdal.GA_Update) red = rat.readColumn(ratDataset, 'Red') green = rat.readColumn(ratDataset, 'Green') blue = rat.readColumn(ratDataset, 'Blue') ClassName = numpy.empty_like(red, dtype=numpy.dtype('a255')) ClassName[...] = "" for classKey in classTrainInfo: print("Apply Colour to class \'" + classKey + "\'") red[classTrainInfo[classKey].out_id] = classTrainInfo[classKey].red green[classTrainInfo[classKey]. out_id] = classTrainInfo[classKey].green blue[classTrainInfo[classKey]. out_id] = classTrainInfo[classKey].blue ClassName[classTrainInfo[classKey].out_id] = classKey rat.writeColumn(ratDataset, "Red", red) rat.writeColumn(ratDataset, "Green", green) rat.writeColumn(ratDataset, "Blue", blue) rat.writeColumn(ratDataset, "ClassName", ClassName) ratDataset = None