def performClumpingSingleThread(inputImage, clumpsImage, tmpDIR='tmp', width=2000, height=2000, gdalformat='KEA'): """ Clump the input image using a tiled processing chain allowing large images to be clumped more quickly. :param inputImage: the input image to be clumped. :param clumpsImage: the output clumped image. :param tmpDIR: the temporary directory where intermediate files will be written (default is 'tmp'). Directory will be created and deleted if does not exist. :param width: int for width of the image tiles used for processing (Default = 2000). :param height: int for height of the image tiles used for processing (Default = 2000). :param gdalformat: string with the GDAL image format for the output image (Default = KEA). NOTE. KEA is used as intermediate format internally and therefore needs to be available. """ createdTmp = False if not os.path.exists(tmpDIR): os.makedirs(tmpDIR) createdTmp = True rsgisUtils = rsgislib.RSGISPyUtils() uidStr = rsgisUtils.uidGenerator() dataType = rsgisUtils.getRSGISLibDataTypeFromImg(inputImage) baseName = os.path.splitext(os.path.basename(inputImage))[0] + "_" + uidStr imgTilesDIR = os.path.join(tmpDIR, "imgtiles_" + uidStr) tilesClumpsDIR = os.path.join(tmpDIR, "imgclumpstiles_" + uidStr) tilesImgBase = os.path.join(imgTilesDIR, baseName) initMergedClumps = os.path.join(tmpDIR, "MergedInitClumps_" + uidStr + ".kea") if not os.path.exists(imgTilesDIR): os.makedirs(imgTilesDIR) if not os.path.exists(tilesClumpsDIR): os.makedirs(tilesClumpsDIR) imageutils.createTiles(inputImage, tilesImgBase, int(width), int(height), 0, False, 'KEA', dataType, 'kea') imageTiles = glob.glob(tilesImgBase + "*") for tile in imageTiles: tilBaseName = os.path.splitext(os.path.basename(tile))[0] clumpedTile = os.path.join(tilesClumpsDIR, tilBaseName + '_clumps.kea') segmentation.clump(tile, clumpedTile, 'KEA', True, 0, True) clumpTiles = glob.glob(os.path.join(tilesClumpsDIR, '*_clumps.kea')) print("Create Blank Image") imageutils.createCopyImage(inputImage, initMergedClumps, 1, 0, 'KEA', rsgislib.TYPE_32UINT) print("Merge Tiles into Blank Image") segmentation.mergeClumpImages(clumpTiles, initMergedClumps, True) print("Merge Tile Boundaries") segmentation.mergeEquivClumps(initMergedClumps, clumpsImage, gdalformat, ['PixelVal']) shutil.rmtree(imgTilesDIR) shutil.rmtree(tilesClumpsDIR) os.remove(initMergedClumps) if createdTmp: shutil.rmtree(tmpDIR)
def performTiledImgMultiFilter(inputImg, outputImgs, filterInsts, dataType=None, gdalformat='KEA', tmpDIR='tmp', width=2000, height=2000, nCores=-1): """ This function will perform the filtering using multiple filters of an input image where the input image will be tiled and the tiles executed on multiple processing cores. This function is primarily of use for larger images or when using very large filter windows otherwise the over head of tiling and mosaicking are not worth it. :param inputImg: is the file name and path for the input image file. :param outputImgs: is a list of file names and paths for the output image files - Note, must be the same length as filterInsts. :param filterInsts: is a list of filter instances of the classes available within rsgislib.imagefilter.tiledfilter - Note, must be the same length as filterInsts. :param datatype: is the output image data type (e.g., rsgislib.TYPE_32FLOAT; Default is None). If None then data type of input image is used. :param gdalformat: string with the GDAL image format for the output image (Default = KEA). NOTE. KEA is used as intermediate format internally and therefore needs to be available. :param tmpDIR: the temporary directory where intermediate files will be written (default is 'tmp'). Directory will be created and deleted if does not exist. :param width: int for width of the image tiles used for processing (Default = 2000). :param height: int for height of the image tiles used for processing (Default = 2000). :param nCores: is an int specifying the number of cores to be used for clumping processing. Example:: import rsgislib from rsgislib.imagefilter import tiledfilter from rsgislib import imageutils inputImage = 'LandsatImg.kea' outputImages = ['LandsatImgMedianFilter.kea', 'LandsatImgNormVarFilter.kea'] filters = [tiledfilter.RSGISMedianFilter(7, "KEA", rsgislib.TYPE_16UINT), tiledfilter.RSGISNormVarFilter(7, "KEA", rsgisUtils.getRSGISLibDataTypeFromImg(inputImage))] tiledfilter.performTiledImgMultiFilter(inputImage, outputImages, filters, width=2000, height=2000) imageutils.popImageStats(outputImage, usenodataval=False, nodataval=0, calcpyramids=True) """ if (len(outputImgs) != len(filterInsts)): raise rsgislib.RSGISPyException( 'The same number of filters and output images need to be provided.' ) numFilters = len(outputImgs) rsgisUtils = rsgislib.RSGISPyUtils() createdTmp = False if not os.path.exists(tmpDIR): os.makedirs(tmpDIR) createdTmp = True if nCores <= 0: nCores = rsgisUtils.numProcessCores() uidStr = rsgisUtils.uidGenerator() if dataType == None: dataType = rsgisUtils.getRSGISLibDataTypeFromImg(inputImg) baseName = os.path.splitext(os.path.basename(inputImg))[0] + "_" + uidStr imgTilesDIR = os.path.join(tmpDIR, "imgTiles_" + uidStr) tilesFilterDIR = os.path.join(tmpDIR, "imgFilterTiles_" + uidStr) tilesImgBase = os.path.join(imgTilesDIR, baseName) if not os.path.exists(imgTilesDIR): os.makedirs(imgTilesDIR) first = True tileOverlap = 0 for filterInst in filterInsts: tmpOverlap = math.ceil(filterInst.getFilterHSize()) if first: tileOverlap = tmpOverlap first = False elif tmpOverlap > tileOverlap: tileOverlap = tmpOverlap imageutils.createTiles(inputImg, tilesImgBase, int(width), int(height), int(tileOverlap), False, 'KEA', rsgisUtils.getRSGISLibDataTypeFromImg(inputImg), 'kea') imageTiles = glob.glob(tilesImgBase + "*.kea") for i in range(numFilters): filterInst = filterInsts[i] outputImg = outputImgs[i] if not os.path.exists(tilesFilterDIR): os.makedirs(tilesFilterDIR) filterImgsVals = [] for tile in imageTiles: tileBaseName = os.path.splitext(os.path.basename(tile))[0] filterTile = os.path.join(tilesFilterDIR, tileBaseName + '_filter.kea') filterImgsVals.append([tile, filterTile, filterInst]) with Pool(nCores) as p: p.map(_performFilteringFunc, filterImgsVals) imgFilterTiles = glob.glob(os.path.join(tilesFilterDIR, "*_filter.kea")) numOutBands = rsgisUtils.getImageBandCount(inputImg) imageutils.createCopyImage(inputImg, outputImg, numOutBands, 0, gdalformat, dataType) imageutils.includeImagesWithOverlap(outputImg, imgFilterTiles, int(filterInst.getFilterHSize())) shutil.rmtree(tilesFilterDIR) shutil.rmtree(imgTilesDIR) if createdTmp: shutil.rmtree(tmpDIR)
def performUnionClumpingMultiProcess(inputImage, refImg, clumpsImage, tmpDIR='tmp', width=2000, height=2000, gdalformat='KEA', nCores=-1): """ Clump and union with the reference image the input image using a tiled processing chain allowing large images to be clumped more quickly. :param inputImage: the input image to be clumped. :param refImg: the reference image which the union is undertaken with (typically an existing classification) :param clumpsImage: the output clumped image. :param tmpDIR: the temporary directory where intermediate files will be written (default is 'tmp'). Directory will be created and deleted if does not exist. :param width: int for width of the image tiles used for processing (Default = 2000). :param height: int for height of the image tiles used for processing (Default = 2000). :param gdalformat: string with the GDAL image format for the output image (Default = KEA). NOTE. KEA is used as intermediate format internally and therefore needs to be available. :param nCores: is an int specifying the number of cores to be used for clumping processing. """ createdTmp = False if not os.path.exists(tmpDIR): os.makedirs(tmpDIR) createdTmp = True if nCores <= 0: nCores = multiprocessing.cpu_count() rsgisUtils = rsgislib.RSGISPyUtils() uidStr = rsgisUtils.uidGenerator() dataType = rsgisUtils.getRSGISLibDataTypeFromImg(inputImage) baseName = os.path.splitext(os.path.basename(inputImage))[0] + "_" + uidStr imgTilesDIR = os.path.join(tmpDIR, "imgtiles_" + uidStr) tilesClumpsDIR = os.path.join(tmpDIR, "imgclumpstiles_" + uidStr) tilesImgBase = os.path.join(imgTilesDIR, baseName) initMergedClumps = os.path.join(tmpDIR, "MergedInitClumps_" + uidStr + ".kea") if not os.path.exists(imgTilesDIR): os.makedirs(imgTilesDIR) if not os.path.exists(tilesClumpsDIR): os.makedirs(tilesClumpsDIR) imageutils.createTiles(inputImage, tilesImgBase, int(width), int(height), 0, False, 'KEA', dataType, 'kea') imageTiles = glob.glob(tilesImgBase + "*") clumpImgsVals = [] for tile in imageTiles: tilBaseName = os.path.splitext(os.path.basename(tile))[0] clumpedTile = os.path.join(tilesClumpsDIR, tilBaseName + '_clumps.kea') clumpImgsVals.append([tile, refImg, clumpedTile]) with Pool(nCores) as p: p.map(unionClumpImgFunc, clumpImgsVals) clumpTiles = glob.glob(os.path.join(tilesClumpsDIR, '*_clumps.kea')) print("Create Blank Image") imageutils.createCopyImage(inputImage, initMergedClumps, 1, 0, 'KEA', rsgislib.TYPE_32UINT) print("Merge Tiles into Blank Image") segmentation.mergeClumpImages(clumpTiles, initMergedClumps, True) print("Merge Tile Boundaries") segmentation.mergeEquivClumps(initMergedClumps, clumpsImage, gdalformat, ['ClumpVal_1', 'ClumpVal_2']) shutil.rmtree(imgTilesDIR) shutil.rmtree(tilesClumpsDIR) os.remove(initMergedClumps) if createdTmp: shutil.rmtree(tmpDIR)