コード例 #1
0
ファイル: testrat.py プロジェクト: gillins/rios
def run():
    """
    Run tests of the rios.rat functions
    """
    riostestutils.reportStart(TESTNAME)
    allOK = True

    imgfile = 'test.img'
    ratValues = makeTestFile(imgfile)
    nValues = len(ratValues)

    columnList = [("Int32", numpy.int32), ("Float32", numpy.float32),
                  ("Unicode", numpy.dtype('U10'))]
    # Only test old string type for python 2
    if sys.version_info.major < 3:
        columnList.append(("String", numpy.dtype('S10')))

    allOK = True
    for (colName, arrayDtype) in columnList:
        # Write the array into the file, with the given datatype
        ratValues_type = ratValues.astype(arrayDtype)
        rat.writeColumn(imgfile, colName, ratValues_type)

        # Read it back, and check that the values are the same
        ratValues_fromFile = rat.readColumn(imgfile, colName)[:nValues].astype(
            ratValues.dtype)
        if not (ratValues_fromFile == ratValues).all():
            riostestutils.report(TESTNAME,
                                 "Value mis-match for column %s" % (colName))
            allOK = False

    if os.path.exists(imgfile):
        os.remove(imgfile)

    if allOK:
        riostestutils.report(TESTNAME, "Passed")

    return allOK
コード例 #2
0
def collapseClasses(inputFile):
    ratDataset = gdal.Open(inputFile, gdal.GA_Update)
    Red = rat.readColumn(ratDataset, "Red")
    Green = rat.readColumn(ratDataset, "Green")
    Blue = rat.readColumn(ratDataset, "Blue")
    
    # Water
    Red[0] = 135
    Green[0] = 206
    Blue[0] = 255
    
    # Land
    Red[1] = 34
    Green[1] = 139
    Blue[1] = 34
    
    rat.writeColumn(ratDataset, "Red", Red)
    rat.writeColumn(ratDataset, "Green", Green)
    rat.writeColumn(ratDataset, "Blue", Blue)
コード例 #3
0
def applyClassifer(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 ClassInfoObj objects which will be used to train the classifier (i.e., trainClassifier()), provide pixel value id and RGB class values.
:param skClassifier: a trained instance of a scikit-learn classifier (e.g., use trainClassifier or findClassifierParametersAndTrain)
: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.

    """
    if not haveRIOS:
        raise Exception(
            "The rios module is required for this function could not be imported\n\t"
            + riosErr)

    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

    aControls = applier.ApplierControls()
    aControls.progress = cuiprogress.CUIProgressBar()
    aControls.drivername = gdalformat
    aControls.omitPyramids = True
    aControls.calcStats = False
    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
# Train CSV classifier
print('define clf')
#clf= svm.OneClassSVM(kernel='rbf',nu=0.2,gamma='auto',verbose=False)
clf = svm.OneClassSVM(kernel='poly', nu=0.25, gamma='auto', verbose=True)

print('fit clf')
clf.fit(X_train, y_train)

# Set NaN values to 0
X = np.where(np.isfinite(X), X, 0)

# Apply classification
print('apply classification ')
predictClass = clf.predict(X[:, 0:-1])

# Write out data to RAT
print('write RAT')
rat.writeColumn(ratDataset, 'predictClass', predictClass)
ratDataset = None

outimage = 'S1B_IW_GRDH_1SDV_20170704T165718_Sigma0_stack_lee3_testAOI2_grid_clumps100_classified_polynu02shrnk.tif'
outimage = 'S1B_IW_GRDH_1SDV_20170704T165718_Sigma0_stack_lee3_testAOI2_grid_clumps100_classified_ploynu025.tif'
gdalformat = 'GTiff'
datatype = rsgislib.TYPE_8INT
fields = ['predictClass']
print('export cols')
rastergis.exportCols2GDALImage(clumps, outimage, gdalformat, datatype, fields)

os.system('afplay /System/Library/Sounds/Tink.aiff')
os.system('afplay /System/Library/Sounds/Tink.aiff')
コード例 #5
0
ファイル: classkeraspxl.py プロジェクト: timebridge/rsgislib
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
コード例 #6
0
                        if (chorizon[chorizonCOKEYCol] == cokey) and (chorizon[outColNum] != ''):
                            if chorizon[chorizonHZNAMECol] == 'H1':
                                outColH1[i] = chorizon[outColNum]
                            elif chorizon[chorizonHZNAMECol] == 'H2':
                                outColH2[i] = chorizon[outColNum]
                            elif chorizon[chorizonHZNAMECol] == 'H3':
                                outColH3[i] = chorizon[outColNum]
                            elif chorizon[chorizonHZNAMECol] == 'H4':
                                outColH4[i] = chorizon[outColNum]
                            elif chorizon[chorizonHZNAMECol] == 'H5':
                                outColH5[i] = chorizon[outColNum]
                            elif chorizon[chorizonHZNAMECol] == 'H6':
                                outColH6[i] = chorizon[outColNum]
                    break
    
    rat.writeColumn(outKEAFile, outColName + '_H1', outColH1)
    rat.writeColumn(outKEAFile, outColName + '_H2', outColH2)
    rat.writeColumn(outKEAFile, outColName + '_H3', outColH3)
    rat.writeColumn(outKEAFile, outColName + '_H4', outColH4)
    rat.writeColumn(outKEAFile, outColName + '_H5', outColH5)
    rat.writeColumn(outKEAFile, outColName + '_H6', outColH6)

    if args.raster:
        # Create a list of out column names (attribute and height)
        outColNamesList = ['{}_H{}'.format(outColName, i) for i in range(1, 7)]
        rastergis.exportCols2GDALImage(outKEAFile, outRasterImage,
                                       outFormat, rsgislib.TYPE_32FLOAT,
                                       outColNamesList)
        print('Saved raster to: {}'.format(outRasterImage))

コード例 #7
0
                     if (chorizon[chorizonCOKEYCol] == cokey) and (chorizon[outColNum] != ''):
                         if chorizon[chorizonHZNAMECol] == 'H1':
                             outColH1[i] = chorizon[outColNum]
                         elif chorizon[chorizonHZNAMECol] == 'H2':
                             outColH2[i] = chorizon[outColNum]
                         elif chorizon[chorizonHZNAMECol] == 'H3':
                             outColH3[i] = chorizon[outColNum]
                         elif chorizon[chorizonHZNAMECol] == 'H4':
                             outColH4[i] = chorizon[outColNum]
                         elif chorizon[chorizonHZNAMECol] == 'H5':
                             outColH5[i] = chorizon[outColNum]
                         elif chorizon[chorizonHZNAMECol] == 'H6':
                             outColH6[i] = chorizon[outColNum]
                 break
 
 rat.writeColumn(outKEAFile, outColName + '_H1', outColH1)
 rat.writeColumn(outKEAFile, outColName + '_H2', outColH2)
 rat.writeColumn(outKEAFile, outColName + '_H3', outColH3)
 rat.writeColumn(outKEAFile, outColName + '_H4', outColH4)
 rat.writeColumn(outKEAFile, outColName + '_H5', outColH5)
 rat.writeColumn(outKEAFile, outColName + '_H6', outColH6)
 
 # Create RSGISLib script to convert to standard raster
 outRSGISText = '''<rsgis:commands xmlns:rsgis="http://www.rsgislib.org/xml/">
     <rsgis:command algor="rastergis" option="exportcols2raster" clumps="{0}" output="{1}" format="{2}" datatype="Float32" >
         <rsgis:field name="{3}_H1" />
         <rsgis:field name="{3}_H2" />
         <rsgis:field name="{3}_H3" />
         <rsgis:field name="{3}_H4" />
         <rsgis:field name="{3}_H5" />
         <rsgis:field name="{3}_H6" />
コード例 #8
0
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)
コード例 #9
0
def collapseClasses(inputFile, lcdbColName, outputColName):
    ratDataset = gdal.Open(inputFile, gdal.GA_Update)
    lcdbCol = rat.readColumn(ratDataset, lcdbColName)

    outClassesCol = np.zeros_like(lcdbCol)

    # 0 Undefined
    UNDEFINED = 0
    # 1 High Producing Exotic Herbaceous
    HIGH_PRODUCING_EXOTIC_HERBACEOUS = 1
    # 2 Tall Tussock Grassland
    TALL_TUSSOCK_GRASSLAND = 2
    # 3 Other Herbaceous
    OTHER_HERBACEOUS = 3
    # 4 Scrub
    SCRUB = 4
    # 5 Indigenous Forest
    INDIGENOUS_FOREST = 5
    # 6 Exotic Forest
    EXOTIC_FOREST = 6
    # 7 Other Woody
    OTHER_WOODY = 7
    # 8 Sub Alpine Scrubland
    SUB_ALPINE_SCRUBLAND = 8
    # 9 Built Up
    BUILT_UP = 9
    # 10 Bare Ground
    BARE_GROUND = 10
    # 11 Water
    WATER = 11
    # 12 Perminant Snow and Ice
    PERMINANT_SNOW_ICE = 12

    # Undefined -> UNDEFINED
    outClassesCol = np.where(lcdbCol == 0, UNDEFINED, outClassesCol)
    # Built-up Area (settlement) -> BUILT_UP
    outClassesCol = np.where(lcdbCol == 1, BUILT_UP, outClassesCol)
    # Urban Parkland/Open Space -> OTHER_HERBACEOUS
    outClassesCol = np.where(lcdbCol == 2, OTHER_HERBACEOUS, outClassesCol)
    # Transport Infrastructure -> BUILT_UP
    outClassesCol = np.where(lcdbCol == 5, BUILT_UP, outClassesCol)
    # Surface Mines and Dumps -> BARE_GROUND
    outClassesCol = np.where(lcdbCol == 6, BARE_GROUND, outClassesCol)
    # Coastal Sand and Gravel -> BARE_GROUND
    outClassesCol = np.where(lcdbCol == 10, BARE_GROUND, outClassesCol)
    # River and Lakeshore Gravel and Rock -> BARE_GROUND
    outClassesCol = np.where(lcdbCol == 11, BARE_GROUND, outClassesCol)
    # Landslide -> BARE_GROUND
    outClassesCol = np.where(lcdbCol == 12, BARE_GROUND, outClassesCol)
    # Alpine Gravel and Rock -> BARE_GROUND
    outClassesCol = np.where(lcdbCol == 13, BARE_GROUND, outClassesCol)
    # Permanent Snow and Ice -> PERMINANT_SNOW_ICE
    outClassesCol = np.where(lcdbCol == 14, PERMINANT_SNOW_ICE, outClassesCol)
    # Alpine Grass/Herbfield -> OTHER_HERBACEOUS
    outClassesCol = np.where(lcdbCol == 15, OTHER_HERBACEOUS, outClassesCol)
    # Lake and Pond -> WATER
    outClassesCol = np.where(lcdbCol == 20, WATER, outClassesCol)
    # River -> WATER
    outClassesCol = np.where(lcdbCol == 21, WATER, outClassesCol)
    # Estuarine Open Water -> WATER
    outClassesCol = np.where(lcdbCol == 22, WATER, outClassesCol)
    # Short-rotation Cropland -> HIGH_PRODUCING_EXOTIC_HERBACEOUS
    outClassesCol = np.where(lcdbCol == 30, HIGH_PRODUCING_EXOTIC_HERBACEOUS,
                             outClassesCol)
    # Cultivation -> BARE_GROUND
    outClassesCol = np.where(lcdbCol == 31, BARE_GROUND, outClassesCol)
    # Orchard Vineyard & Other Perennial Crops -> HIGH_PRODUCING_EXOTIC_HERBACEOUS
    outClassesCol = np.where(lcdbCol == 33, HIGH_PRODUCING_EXOTIC_HERBACEOUS,
                             outClassesCol)
    # High Producing Exotic Grassland -> HIGH_PRODUCING_EXOTIC_HERBACEOUS
    outClassesCol = np.where(lcdbCol == 40, HIGH_PRODUCING_EXOTIC_HERBACEOUS,
                             outClassesCol)
    # Low Producing Grassland -> OTHER_HERBACEOUS
    outClassesCol = np.where(lcdbCol == 41, OTHER_HERBACEOUS, outClassesCol)
    # Tall Tussock Grassland -> TALL_TUSSOCK_GRASSLAND
    outClassesCol = np.where(lcdbCol == 43, TALL_TUSSOCK_GRASSLAND,
                             outClassesCol)
    # Depleted Grassland -> OTHER_HERBACEOUS
    outClassesCol = np.where(lcdbCol == 44, OTHER_HERBACEOUS, outClassesCol)
    # Herbaceous Freshwater Vegetation -> OTHER_HERBACEOUS
    outClassesCol = np.where(lcdbCol == 45, OTHER_HERBACEOUS, outClassesCol)
    # Herbaceous Saline Vegetation -> OTHER_HERBACEOUS
    outClassesCol = np.where(lcdbCol == 46, OTHER_HERBACEOUS, outClassesCol)
    # Flaxland -> OTHER_HERBACEOUS
    outClassesCol = np.where(lcdbCol == 47, OTHER_HERBACEOUS, outClassesCol)
    # Fernland -> OTHER_HERBACEOUS
    outClassesCol = np.where(lcdbCol == 50, OTHER_HERBACEOUS, outClassesCol)
    # Gorse and/or Broom -> SCRUB
    outClassesCol = np.where(lcdbCol == 51, SCRUB, outClassesCol)
    # Manuka and/or Kanuka -> SCRUB
    outClassesCol = np.where(lcdbCol == 52, SCRUB, outClassesCol)
    # Broadleaved Indigenous Hardwoods -> INDIGENOUS_FOREST
    outClassesCol = np.where(lcdbCol == 54, INDIGENOUS_FOREST, outClassesCol)
    # Sub Alpine Shrubland -> SUB_ALPINE_SCRUBLAND
    outClassesCol = np.where(lcdbCol == 55, SUB_ALPINE_SCRUBLAND,
                             outClassesCol)
    # Mixed Exotic Shrubland -> SCRUB
    outClassesCol = np.where(lcdbCol == 56, SCRUB, outClassesCol)
    # Matagouri or Grey Scrub -> SCRUB
    outClassesCol = np.where(lcdbCol == 58, SCRUB, outClassesCol)
    # Forest - Harvested -> BARE_GROUND
    outClassesCol = np.where(lcdbCol == 64, BARE_GROUND, outClassesCol)
    # Deciduous Hardwoods -> OTHER_WOODY
    outClassesCol = np.where(lcdbCol == 68, OTHER_WOODY, outClassesCol)
    # Indigenous Forest -> INDIGENOUS_FOREST
    outClassesCol = np.where(lcdbCol == 69, INDIGENOUS_FOREST, outClassesCol)
    # Mangroves -> OTHER_WOODY
    outClassesCol = np.where(lcdbCol == 70, OTHER_WOODY, outClassesCol)
    # Exotic Forest -> EXOTIC_FOREST
    outClassesCol = np.where(lcdbCol == 71, EXOTIC_FOREST, outClassesCol)

    rat.writeColumn(ratDataset, outputColName, outClassesCol)
コード例 #10
0
ファイル: classsklearn.py プロジェクト: timebridge/rsgislib
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
コード例 #11
0
NewColName = 'Mask1'

#######################################################
if not os.path.exists(SegImg):
    sys.exit('Error: Could not find the segmented image.')

ratDataset = gdal.Open(SegImg, 1)  # read the image in read-write mode.
RefCol = rat.readColumn(
    ratDataset, 'Alpha')  # read an existing RAT pythocolumn to get size.

Ones = np.ones_like(RefCol, dtype='uint8')  # create an array of ones.
del RefCol

Ones[0] = 0  # assign zero to the first clump because it contains no data.

rat.writeColumn(ratDataset, NewColName, Ones)  # write numpy array to RAT.
del Ones, ratDataset
print('Done.')

ref = 'S1B_IW_GRDH_1SDV_20170423T165655_Sigma0_stack_lee_clumps2_erf_clumptrain_mode_snapped.tif'
mask = 'S1B_IW_GRDH_1SDV_20170423T165655_Sigma0_stack_lee_clumps2_mean.kea'
mask_snap = 'S1B_IW_GRDH_1SDV_20170423T165655_Sigma0_stack_lee_clumps2_mean_snap.kea'
gdalFormat = 'KEA'
rsgislib.imageutils.resampleImage2Match(ref,
                                        mask,
                                        mask_snap,
                                        gdalFormat,
                                        interpMethod='nearestneighbour',
                                        datatype=rsgislib.TYPE_8UINT)

bandDefns = []
コード例 #12
0
def classifyWithinRAT(clumpsImg,
                      classesIntCol,
                      classesNameCol,
                      variables,
                      classifier=RandomForestClassifier(n_estimators=100,
                                                        max_features=3,
                                                        oob_score=True,
                                                        n_jobs=-1),
                      outColInt="OutClass",
                      outColStr="OutClassName",
                      roiCol=None,
                      roiVal=1,
                      classColours=None,
                      preProcessor=None,
                      justFit=False):
    """
A function which will perform a classification within the RAT using a classifier from scikit-learn

:param clumpsImg: is the clumps image on which the classification is to be performed
:param classesIntCol: is the column with the training data as int values
:param classesNameCol: is the column with the training data as string class names
:param variables: is an array of column names which are to be used for the classification
:param classifier: is an instance of a scikit-learn classifier (e.g., RandomForests which is Default)
:param outColInt: is the output column name for the int class representation (Default: 'OutClass')
:param outColStr: is the output column name for the class names column (Default: 'OutClassName')
:param roiCol: is a column name for a column which specifies the region to be classified. If None ignored (Default: None)
:param roiVal: is a int value used within the roiCol to select a region to be classified (Default: 1)
:param classColours: is a python dict using the class name as the key along with arrays of length 3 specifying the RGB colours for the class.
:param preProcessor: is a scikit-learn processors such as sklearn.preprocessing.MaxAbsScaler() which can rescale the input variables independently as read in (Define: None; i.e., not in use).
:param justFit: is a boolean specifying that the classifier should just be fitted to the data and not applied (Default: False; i.e., apply classification)


Example::

    from sklearn.ensemble import ExtraTreesClassifier
    from rsgislib.classification import classratutils
    
    classifier = ExtraTreesClassifier(n_estimators=100, max_features=3, n_jobs=-1, verbose=0)
    
    classColours = dict()
    classColours['Forest'] = [0,138,0]
    classColours['NonForest'] = [200,200,200]
    
    variables = ['GreenAvg', 'RedAvg', 'NIR1Avg', 'NIR2Avg', 'NDVI']
    classifyWithinRAT(clumpsImg, classesIntCol, classesNameCol, variables, classifier=classifier, classColours=classColours)
    
    from sklearn.preprocessing import MaxAbsScaler
    
    # With pre-processor
    classifyWithinRAT(clumpsImg, classesIntCol, classesNameCol, variables, classifier=classifier, classColours=classColours, preProcessor=MaxAbsScaler())

"""
    # Check gdal is available
    if not haveGDALPy:
        raise Exception(
            "The GDAL python bindings required for this function could not be imported\n\t"
            + gdalErr)
    # Check numpy is available
    if not haveNumpy:
        raise Exception(
            "The numpy module is required for this function could not be imported\n\t"
            + numErr)
    # Check rios rat is available
    if not haveRIOSRat:
        raise Exception(
            "The RIOS rat tools are required for this function could not be imported\n\t"
            + riosRatErr)
    # Check scikit-learn RF is available
    if not haveSKLearnRF:
        raise Exception(
            "The scikit-learn random forests tools are required for this function could not be imported\n\t"
            + sklearnRFErr)
    # Check scikit-learn pre-processing is available
    if not haveSKLearnPreProcess:
        raise Exception(
            "The scikit-learn pre-processing tools are required for this function could not be imported\n\t"
            + sklearnPreProcessErr)

    ratDataset = gdal.Open(clumpsImg, gdal.GA_Update)
    numpyVars = []
    for var in variables:
        print("Reading " + var)
        tmpArr = rat.readColumn(ratDataset, var)
        if not preProcessor is None:
            tmpArr = tmpArr.reshape(-1, 1)
            tmpArr = preProcessor.fit_transform(tmpArr)
            tmpArr = tmpArr.reshape(-1)
        numpyVars.append(tmpArr)

    # Read in training classes
    classesInt = rat.readColumn(ratDataset, classesIntCol)
    classesStr = rat.readColumn(ratDataset, classesNameCol)

    roi = None
    if not ((roiCol == None) or (roiCol == "")):
        roi = rat.readColumn(ratDataset, roiCol)

    # Set up output array
    outLabels = numpy.zeros_like(classesInt, dtype=numpy.int16)
    outClassNames = numpy.empty_like(classesInt, dtype=numpy.dtype('a255'))
    ID = numpy.arange(outLabels.shape[0])

    xData = numpy.array(numpyVars)
    xData = xData.transpose()
    xData = numpy.where(numpy.isfinite(xData), xData, 0)

    print("Input data size: {} x {}".format(xData.shape[0], xData.shape[1]))

    trainingData = xData[numpy.isfinite(xData).all(axis=1)]
    classesInt = classesInt[numpy.isfinite(xData).all(axis=1)]
    classesStr = classesStr[numpy.isfinite(xData).all(axis=1)]
    ID = ID[numpy.isfinite(xData).all(axis=1)]

    trainingData = trainingData[classesInt > 0]
    classesStr = classesStr[classesInt > 0]
    classesInt = classesInt[classesInt > 0]

    print("Training data size: {} x {}".format(trainingData.shape[0],
                                               trainingData.shape[1]))

    print('Training Classifier')
    classifier.fit(trainingData, classesInt)

    print('Calc Classifier Accuracy')
    accVal = classifier.score(trainingData, classesInt)
    print('Classifier Score = {}'.format(round(accVal * 100, 2)))

    if not justFit:
        if not roi is None:
            xData = xData[roi == roiVal]
            ID = ID[roi == roiVal]
            print("ROI Subsetted data size: {} x {}".format(
                xData.shape[0], xData.shape[1]))

        predClass = classifier.predict(xData)

        outLabels[ID] = predClass

        print("Writing Columns")
        rat.writeColumn(ratDataset, outColInt, outLabels)

        print("Create and Write Output Class Names")
        classNames = numpy.unique(classesStr)
        classes = numpy.zeros_like(classNames, dtype=numpy.int16)

        i = 0
        classNameIDs = dict()
        for className in classNames:
            classNameStr = str(className.decode())
            if not classNameStr is '':
                classes[i] = classesInt[classesStr == className][0]
                classNameIDs[classNameStr] = classes[i]
                print("Class \'" + classNameStr + "\' has numerical " +
                      str(classes[i]))
                i = i + 1

        outClassNames[...] = ''
        for className in classNameIDs:
            classID = classNameIDs[className]
            outClassNames[outLabels == classID] = className

        rat.writeColumn(ratDataset, outColStr, outClassNames)

        if not classColours is None:
            print("Set Colours")
            red = rat.readColumn(ratDataset, "Red")
            green = rat.readColumn(ratDataset, "Green")
            blue = rat.readColumn(ratDataset, "Blue")

            # Set Background to black
            red[...] = 0
            green[...] = 0
            blue[...] = 0

            # Set colours
            for className in classNameIDs:
                print("Colouring class " + className)
                classID = classNameIDs[className]
                colours = classColours[className]

                red = numpy.where(outLabels == classID, colours[0], red)
                green = numpy.where(outLabels == classID, colours[1], green)
                blue = numpy.where(outLabels == classID, colours[2], blue)

            rat.writeColumn(ratDataset, "Red", red)
            rat.writeColumn(ratDataset, "Green", green)
            rat.writeColumn(ratDataset, "Blue", blue)

    ratDataset = None
コード例 #13
0
                        outSelectCol='NDVISamplingMang',
                        propOfSample=0.1,
                        binWidth=0.01,
                        classColumn='Class',
                        classVal='2')
rastergis.histoSampling(clumps=clumpsImg,
                        varCol='NDVI',
                        outSelectCol='NDVISamplingOther',
                        propOfSample=0.05,
                        binWidth=0.01,
                        classColumn='Class',
                        classVal='3')

print("Open GDAL Dataset")
ratDataset = gdal.Open(clumpsImg, gdal.GA_Update)
HHSamplingWater = rat.readColumn(ratDataset, "HHSamplingWater")
HHSamplingMang = rat.readColumn(ratDataset, "HHSamplingMang")
HHSamplingOther = rat.readColumn(ratDataset, "HHSamplingOther")
NDVISamplingWater = rat.readColumn(ratDataset, "NDVISamplingWater")
NDVISamplingMang = rat.readColumn(ratDataset, "NDVISamplingMang")
NDVISamplingOther = rat.readColumn(ratDataset, "NDVISamplingOther")
Training = numpy.empty_like(HHSamplingWater, dtype=int)
Training[...] = 0
Training = numpy.where(((HHSamplingWater == 1) | (HHSamplingMang == 1) |
                        (HHSamplingOther == 1) | (NDVISamplingWater == 1) |
                        (NDVISamplingMang == 1) | (NDVISamplingOther == 1)), 1,
                       Training)
# Export column to RAT
rat.writeColumn(ratDataset, "Training", Training)
ratDataset = None
コード例 #14
0
def balanceSampleTrainingRandom(clumpsImg, trainCol, outTrainCol, minNoSamples,
                                maxNoSamples):
    """
A function to balance the number of training samples for classification so the number is above
a minimum threshold (minNoSamples) and all equal to the class with the smallest number of samples
unless that is above a set maximum (maxNoSamples).

:param clumpsImg: is a string with the file path to the input image with RAT
:param trainCol: is a string for the name of the input column specifying the training samples (zero is no data)
:param outTrainCol: is a string with the name of the outputted training samples.
:param minNoSamples: is an int specifying the minimum number of training samples for a class (if below threshold class is removed).
:param maxNoSamples: is an int specifiying the maximum number of training samples per class.

"""
    # Check gdal is available
    if not haveGDALPy:
        raise Exception(
            "The GDAL python bindings required for this function could not be imported\n\t"
            + gdalErr)
    # Check numpy is available
    if not haveNumpy:
        raise Exception(
            "The numpy module is required for this function could not be imported\n\t"
            + numErr)
    # Check rios rat is available
    if not haveRIOSRat:
        raise Exception(
            "The RIOS rat tools are required for this function could not be imported\n\t"
            + riosRatErr)

    ratDataset = gdal.Open(clumpsImg, gdal.GA_Update)
    trainColVals = rat.readColumn(ratDataset, trainCol)
    trainColOutVals = numpy.zeros_like(trainColVals)

    classIDs = numpy.unique(trainColVals)
    classIDs = classIDs[classIDs != 0]

    numSampPerClass = []
    print("Number of input samples:")
    for id in classIDs:
        numVals = trainColVals[trainColVals == id].shape[0]
        print("\tClass {} has {} samples.".format(id, numVals))
        numSampPerClass.append(numVals)

    minNumSamples = 0
    first = True
    for i in range(len(numSampPerClass)):
        if numSampPerClass[i] < minNoSamples:
            trainColOutVals[trainColVals == classIDs[i]] = 0
        else:
            if first:
                minNumSamples = numSampPerClass[i]
                first = False
            elif numSampPerClass[i] < minNumSamples:
                minNumSamples = numSampPerClass[i]

    if minNumSamples > maxNoSamples:
        minNumSamples = maxNoSamples

    print("Number of output samples:")
    for i in range(len(numSampPerClass)):
        if numSampPerClass[i] >= minNoSamples:
            indexes = numpy.where(trainColVals == classIDs[i])
            sampleIdx = numpy.random.choice(indexes[0],
                                            minNumSamples,
                                            replace=False)
            trainColOutVals[sampleIdx] = classIDs[i]
        print("\tClass {} has {} samples.".format(
            classIDs[i],
            trainColOutVals[trainColOutVals == classIDs[i]].shape[0]))

    rat.writeColumn(ratDataset, outTrainCol, trainColOutVals)

    ratDataset = None
コード例 #15
0
def clusterWithinRAT(clumpsImg,
                     variables,
                     clusterer=MiniBatchKMeans(n_clusters=8,
                                               init='k-means++',
                                               max_iter=100,
                                               batch_size=100),
                     outColInt="OutCluster",
                     roiCol=None,
                     roiVal=1,
                     clrClusters=True,
                     clrSeed=10,
                     addConnectivity=False,
                     preProcessor=None):
    """
A function which will perform a clustering within the RAT using a clustering algorithm from scikit-learn

:param clumpsImg: is the clumps image on which the classification is to be performed.
:param variables: is an array of column names which are to be used for the clustering.
:param clusterer: is an instance of a scikit-learn clusterer (e.g., MiniBatchKMeans which is Default; Note with 8 clusters).
:param outColInt: is the output column name identifying the clusters (Default: 'OutCluster').
:param roiCol: is a column name for a column which specifies the region to be clustered. If None ignored (Default: None).
:param roiVal: is a int value used within the roiCol to select a region to be clustered (Default: 1).
:param clrClusters: is a boolean specifying whether the colour table should be updated to correspond to the clusters (Default: True).
:param clrSeed: is an integer seeding the random generator used to generate the colours (Default=10; if None provided system time used).
:param addConnectivity: is a boolean which adds a kneighbors_graph to the clusterer (just an option for the AgglomerativeClustering algorithm)
:param preProcessor: is a scikit-learn processors such as sklearn.preprocessing.MaxAbsScaler() which can rescale the input variables independently as read in (Define: None; i.e., not in use).


Example::

    from rsgislib.classification import classratutils
    from sklearn.cluster import DBSCAN
    
    sklearnClusterer = DBSCAN(eps=1, min_samples=50)
    classratutils.clusterWithinRAT('MangroveClumps.kea', ['MinX', 'MinY'], clusterer=sklearnClusterer, outColInt="OutCluster", roiCol=None, roiVal=1, clrClusters=True, clrSeed=10, addConnectivity=False)
    
    # With pre-processor
    from sklearn.preprocessing import MaxAbsScaler
    classratutils.clusterWithinRAT('MangroveClumps.kea', ['MinX', 'MinY'], clusterer=sklearnClusterer, outColInt="OutCluster", roiCol=None, roiVal=1, clrClusters=True, clrSeed=10, addConnectivity=False, preProcessor=MaxAbsScaler())

"""
    # Check gdal is available
    if not haveGDALPy:
        raise Exception(
            "The GDAL python bindings required for this function could not be imported\n\t"
            + gdalErr)
    # Check numpy is available
    if not haveNumpy:
        raise Exception(
            "The numpy module is required for this function could not be imported\n\t"
            + numErr)
    # Check rios rat is available
    if not haveRIOSRat:
        raise Exception(
            "The RIOS rat tools are required for this function could not be imported\n\t"
            + riosRatErr)
    # Check scikit-learn RF is available
    if not haveSKLearnKM:
        raise Exception(
            "The scikit-learn Mini Batch KMeans tools are required for this function could not be imported\n\t"
            + sklearnMBKMErr)
    # Check scikit-learn pre-processing is available
    if not haveSKLearnPreProcess:
        raise Exception(
            "The scikit-learn pre-processing tools are required for this function could not be imported\n\t"
            + sklearnPreProcessErr)

    ratDataset = gdal.Open(clumpsImg, gdal.GA_Update)
    Histogram = rat.readColumn(ratDataset, 'Histogram')
    numpyVars = []
    for var in variables:
        print("Reading " + var)
        tmpArr = rat.readColumn(ratDataset, var)
        if not preProcessor is None:
            tmpArr = tmpArr.reshape(-1, 1)
            tmpArr = preProcessor.fit_transform(tmpArr)
            tmpArr = tmpArr.reshape(-1)
        numpyVars.append(tmpArr)

    roi = None
    if not ((roiCol == None) or (roiCol == "")):
        roi = rat.readColumn(ratDataset, roiCol)

    # Set up output array
    outLabels = numpy.zeros_like(Histogram, dtype=numpy.int16)
    ID = numpy.arange(outLabels.shape[0])

    xData = numpy.array(numpyVars)
    xData = xData.transpose()
    ID = ID[numpy.isfinite(xData).all(axis=1)]
    if not roi is None:
        roi = roi[numpy.isfinite(xData).all(axis=1)]
    xData = xData[numpy.isfinite(xData).all(axis=1)]

    if not roi is None:
        xData = xData[roi == roiVal]
        ID = ID[roi == roiVal]

    print("Input Data Size: {} x {}".format(xData.shape[0], xData.shape[1]))

    if addConnectivity:
        from sklearn.neighbors import kneighbors_graph
        inConnectivity = kneighbors_graph(xData,
                                          n_neighbors=10,
                                          include_self=False)
        clusterer.set_params(**{'connectivity': inConnectivity})

    print('Fit Clusterer')
    outClust = clusterer.fit_predict(xData)

    minClusterID = numpy.min(outClust)
    if minClusterID <= 0:
        minOff = 1 - minClusterID
        outClust = outClust + minOff

    outLabels[ID] = outClust

    print("Writing Columns")
    rat.writeColumn(ratDataset, outColInt, outLabels)

    print("Create and Write Output Class Names")
    clustersIDs = numpy.unique(outClust)

    if clrClusters:
        import random
        random.seed(clrSeed)

        print("Set Colours")
        red = rat.readColumn(ratDataset, "Red")
        green = rat.readColumn(ratDataset, "Green")
        blue = rat.readColumn(ratDataset, "Blue")

        # Set Background to black
        red[...] = 0
        green[...] = 0
        blue[...] = 0

        # Set colours
        for clusterID in clustersIDs:
            print("Colouring cluster: " + str(clusterID))

            red = numpy.where(outLabels == clusterID, random.randint(0, 255),
                              red)
            green = numpy.where(outLabels == clusterID, random.randint(0, 255),
                                green)
            blue = numpy.where(outLabels == clusterID, random.randint(0, 255),
                               blue)

        rat.writeColumn(ratDataset, "Red", red)
        rat.writeColumn(ratDataset, "Green", green)
        rat.writeColumn(ratDataset, "Blue", blue)

    ratDataset = None
コード例 #16
0
print('Calc Accuracy', )
accVal = neigh.score(XTrain, CTrain)
print(' = ', accVal)

# Create array of IDs (to keep track of the original row number)
ID = numpy.arange(Training.shape[0])

# Form array of all columns
XClass = numpy.array([HH, HV, NDVI, NDWI])
XClass = XClass.transpose()

XClass = XClass[numpy.isfinite(XClass).all(axis=1)]
ID = ID[numpy.isfinite(XClass).all(axis=1)]
XClass = XClass[ApplyTo == 1]
ID = ID[ApplyTo == 1]

print('Predicting Classifier')
predClass = neigh.predict(XClass)
#predClassProb = neigh.predict_proba(XClass)
#print(predClass)

print('Create Output Array')
outLabels = numpy.zeros_like(ApplyTo, dtype=numpy.int16)
outLabels[...] = -1
outLabels[ID] = predClass

print("Writing Columns")
rat.writeColumn(ratDataset, "ClassOut", outLabels)

ratDataset = None
コード例 #17
0
def apply_keras_chips_pixel_classifier(classTrainInfo,
                                       keras_cls_mdl,
                                       imgMask,
                                       imgMaskVal,
                                       imgFileInfo,
                                       chip_h_size,
                                       outClassImg,
                                       gdalformat,
                                       pred_batch_size=128,
                                       pred_max_queue_size=10,
                                       pred_workers=1,
                                       pred_use_multiprocessing=False,
                                       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.

For pred_batch_size, pred_max_queue_size, pred_workers and pred_use_multiprocessing options see the keras
documentation https://keras.io/models/model/

: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 chip_h_size: is half the chip size to be extracted (i.e., 10 with output image chips 21x21,
                    10 pixels either size of the one of interest).
:param gdalformat: is the output image format - all GDAL supported formats are supported.
:param pred_batch_size: the batch size used for the classification prediction.
:param pred_max_queue_size: the max queue size used for the classification prediction
:param pred_workers: the number of workers used for the classification prediction
:param pred_use_multiprocessing: whether to use a multiprocessing option for the classification prediction
: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.

    """
    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

    inImgs = list()
    inImgBands = list()

    inImgs.append(imgMask)
    inImgBands.append([1])
    n_img_bands = 0
    for inImgInfo in imgFileInfo:
        inImgs.append(inImgInfo.fileName)
        inImgBands.append(inImgInfo.bands)
        n_img_bands = n_img_bands + len(inImgInfo.bands)
    nImgs = len(imgFileInfo)

    scn_overlap = chip_h_size
    chip_size = (chip_h_size * 2) + 1

    writer = None
    reader = ImageReader(inImgs,
                         windowxsize=200,
                         windowysize=200,
                         overlap=scn_overlap,
                         layerselection=inImgBands)
    for (info, block) in tqdm.tqdm(reader):
        classMskArr = block[0]
        blkShape = classMskArr.shape

        vld_cls_arr = numpy.zeros_like(classMskArr, dtype=int)

        xSize = blkShape[2] - (scn_overlap * 2)
        ySize = blkShape[1] - (scn_overlap * 2)
        xRange = numpy.arange(scn_overlap, scn_overlap + xSize, 1)
        yRange = numpy.arange(scn_overlap, scn_overlap + ySize, 1)
        n_vld_pxls = 0
        for y in yRange:
            for x in xRange:
                if classMskArr[0][y][x] == imgMaskVal:
                    n_vld_pxls = n_vld_pxls + 1
                    vld_cls_arr[0][y][x] = 1

        feat2cls = numpy.zeros([n_vld_pxls, n_img_bands, chip_size, chip_size],
                               dtype=numpy.float32)
        iFeat = 0
        for y in yRange:
            yMin = y - scn_overlap
            yMax = y + scn_overlap + 1
            for x in xRange:
                xMin = x - scn_overlap
                xMax = x + scn_overlap + 1
                if classMskArr[0][y][x] == imgMaskVal:
                    for nImg in range(nImgs):
                        imgBlk = block[nImg + 1][..., yMin:yMax, xMin:xMax]
                        for iBand in range(imgBlk.shape[0]):
                            numpy.copyto(feat2cls[iFeat, iBand],
                                         imgBlk[iBand],
                                         casting='safe')
                        iFeat = iFeat + 1

        preds_idxs = numpy.argmax(keras_cls_mdl.predict(
            feat2cls,
            batch_size=pred_batch_size,
            max_queue_size=pred_max_queue_size,
            workers=pred_workers,
            use_multiprocessing=pred_use_multiprocessing),
                                  axis=1)
        feat2cls = None

        out_cls_arr = numpy.zeros_like(classMskArr, dtype=numpy.uint16)
        out_cls_arr = out_cls_arr.flatten()
        vld_cls_arr = vld_cls_arr.flatten()
        ID = numpy.arange(out_cls_arr.shape[0])
        ID = ID[vld_cls_arr == 1]

        preds_cls_ids = numpy.zeros_like(preds_idxs, dtype=numpy.uint16)
        for cld_id, idx in zip(cls_id_lut, numpy.arange(0, len(cls_id_lut))):
            preds_cls_ids[preds_idxs == idx] = cld_id

        out_cls_arr[ID] = preds_cls_ids
        out_cls_arr = numpy.expand_dims(out_cls_arr.reshape(
            (classMskArr.shape[1], classMskArr.shape[2])),
                                        axis=0)

        if writer is None:
            writer = ImageWriter(outClassImg,
                                 info=info,
                                 firstblock=out_cls_arr,
                                 drivername=gdalformat)
        else:
            writer.write(out_cls_arr)
    writer.close(calcStats=False)

    if classClrNames:
        rsgislib.rastergis.populateStats(outClassImg,
                                         addclrtab=True,
                                         calcpyramids=True,
                                         ignorezero=True)
        max_val = rsgislib.imagecalc.getImageBandMinMax(
            outClassImg, 1, False, 0)[1]
        ratDataset = gdal.Open(outClassImg, gdal.GA_Update)

        max_cls_val = 0
        for classKey in classTrainInfo:
            if classTrainInfo[classKey].out_id > max_cls_val:
                max_cls_val = classTrainInfo[classKey].out_id

        if max_cls_val > max_val:
            red = numpy.random.randint(0, 255, max_cls_val + 1)
            green = numpy.random.randint(0, 255, max_cls_val + 1)
            blue = numpy.random.randint(0, 255, max_cls_val + 1)
        else:
            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
コード例 #18
0
    blueColours = np.where(LCCSs == "B27.A2.B1.C2.D2_XX.B6", 255, blueColours)
    alphaColours = np.where(LCCSs == "B27.A2.B1.C2.D2_XX.B6", 255,
                            alphaColours)

    redColours = np.where(LCCSs == "B27.A2.B2.C2.D2_XX.B6", 0, redColours)
    greenColours = np.where(LCCSs == "B27.A2.B2.C2.D2_XX.B6", 60, greenColours)
    blueColours = np.where(LCCSs == "B27.A2.B2.C2.D2_XX.B6", 250, blueColours)
    alphaColours = np.where(LCCSs == "B27.A2.B2.C2.D2_XX.B6", 255,
                            alphaColours)

    redColours = np.where(LCCSs == "B27.B2.C2.D2_XX.B6", 0, redColours)
    greenColours = np.where(LCCSs == "B27.B2.C2.D2_XX.B6", 10, greenColours)
    blueColours = np.where(LCCSs == "B27.B2.C2.D2_XX.B6", 150, blueColours)
    alphaColours = np.where(LCCSs == "B27.B2.C2.D2_XX.B6", 255, alphaColours)
    return redColours, greenColours, blueColours, alphaColours


# Input file.
fname = "/some/random/file.kea"
ratDataset = gdal.Open(fname, gdal.GA_Update)

print "Import Columns."
LCCSs = rat.readColumn(ratDataset, "LCCS")

print "Classifying Level 4"
red, green, blue, alpha = colourLevel4(LCCSs)
rat.writeColumn(ratDataset, "Red", red)
rat.writeColumn(ratDataset, "Green", green)
rat.writeColumn(ratDataset, "Blue", blue)
rat.writeColumn(ratDataset, "Alpha", alpha)
コード例 #19
0
ファイル: classsklearn.py プロジェクト: timebridge/rsgislib
def perform_voting_classification(skClassifiers,
                                  trainSamplesInfo,
                                  imgFileInfo,
                                  classAreaMask,
                                  classMaskPxlVal,
                                  tmpDIR,
                                  tmpImgBase,
                                  outClassImg,
                                  gdalformat='KEA',
                                  numCores=-1):
    """
A function which will perform a number of classification creating a combined classification by a simple vote.
The classifier parameters can be differed as a list of classifiers is provided (the length of the list is equal
to the number of votes), where the training data is resampled for each classifier. The analysis can be performed
using multiple processing cores.

Where:

:param skClassifiers: a list of classifiers (from scikit-learn), the number of classifiers defined
                      will be equal to the number of votes.
:param trainSamplesInfo: a list of rsgislib.classification.classimgutils.SamplesInfoObj objects used to
                         parameters the classifer and extract training data.
: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 classAreaMask: a mask image which is used to specified the areas of the scene which are to be classified.
:param classMaskPxlVal: is the pixel value within the classAreaMask image for the areas of the image
                        which are to be classified.
:param tmpDIR: a temporary file location which will be created and removed during processing.
:param tmpImgBase: the same name of files written to the tmpDIR
:param outClassImg: the final output image file.
:param gdalformat: the output file format for outClassImg
:param numCores: is the number of processing cores to be used for the analysis (if -1 then all cores on the machine will be used).

Example::

    classVoteTemp = os.path.join(imgTmp, 'ClassVoteTemp')

    imgFileInfo = [rsgislib.imageutils.ImageBandInfo(img2010dB, 'sardb', [1,2]), rsgislib.imageutils.ImageBandInfo(imgSRTM, 'srtm', [1])]
    trainSamplesInfo = []
    trainSamplesInfo.append(SamplesInfoObj(className='Water', classID=1, maskImg=classTrainRegionsMask, maskPxlVal=1, outSampImgFile='WaterSamples.kea', numSamps=500, samplesH5File='WaterSamples_pxlvals.h5', red=0, green=0, blue=255))
    trainSamplesInfo.append(SamplesInfoObj(className='Land', classID=2, maskImg=classTrainRegionsMask, maskPxlVal=2, outSampImgFile='LandSamples.kea', numSamps=500, samplesH5File='LandSamples_pxlvals.h5', red=150, green=150, blue=150))
    trainSamplesInfo.append(SamplesInfoObj(className='Mangroves', classID=3, maskImg=classTrainRegionsMask, maskPxlVal=3, outSampImgFile='MangroveSamples.kea', numSamps=500, samplesH5File='MangroveSamples_pxlvals.h5', red=0, green=153, blue=0))

    skClassifiers = []
    for i in range(5):
        skClassifiers.append(ExtraTreesClassifier(n_estimators=50))

    for i in range(5):
        skClassifiers.append(ExtraTreesClassifier(n_estimators=100))

    for i in range(5):
        skClassifiers.append(ExtraTreesClassifier(n_estimators=50, max_depth=2))

    for i in range(5):
        skClassifiers.append(ExtraTreesClassifier(n_estimators=100, max_depth=2))

    mangroveRegionClassImg = MangroveRegionClass.kea
    classsklearn.perform_voting_classification(skClassifiers, trainSamplesInfo, imgFileInfo, classWithinMask, 1, classVoteTemp, 'ClassImgSample', mangroveRegionClassImg, gdalformat='KEA', numCores=-1)

    """
    def _apply_voting_classifier(inParams):
        """
        Internal function which is used by performVotingClassification
        """

        skClassifier = inParams['skClassifier']
        cTmpDIR = inParams['cTmpDIR']
        classAreaMask = inParams['classAreaMask']
        classMaskPxlVal = inParams['classMaskPxlVal']
        imgFileInfo = inParams['imgFileInfo']
        tmpClassImgOut = inParams['tmpClassImgOut']
        gdalformat = inParams['gdalformat']
        trainSamplesInfo = inParams['trainSamplesInfo']
        rndSeed = inParams['rndSeed']

        classTrainInfo = dict()
        for trainSamples in trainSamplesInfo:
            rsgislib.imageutils.performRandomPxlSampleInMaskLowPxlCount(
                inputImage=trainSamples.maskImg,
                outputImage=os.path.join(cTmpDIR, trainSamples.outSampImgFile),
                gdalformat=gdalformat,
                maskvals=[trainSamples.maskPxlVal],
                numSamples=trainSamples.numSamps,
                rndSeed=rndSeed)
            rsgislib.imageutils.extractZoneImageBandValues2HDF(
                imgFileInfo, os.path.join(cTmpDIR,
                                          trainSamples.outSampImgFile),
                os.path.join(cTmpDIR, trainSamples.samplesH5File),
                trainSamples.maskPxlVal)
            classTrainInfo[trainSamples.className] = ClassSimpleInfoObj(
                id=trainSamples.classID,
                fileH5=os.path.join(cTmpDIR, trainSamples.samplesH5File),
                red=trainSamples.red,
                green=trainSamples.green,
                blue=trainSamples.blue)

        train_sklearn_classifier(classTrainInfo, skClassifier)
        apply_sklearn_classifer(classTrainInfo, skClassifier, classAreaMask,
                                classMaskPxlVal, imgFileInfo, tmpClassImgOut,
                                gdalformat)

    rsgisUtils = rsgislib.RSGISPyUtils()

    if type(skClassifiers) is not list:
        raise rsgislib.RSGISPyException(
            "A list of classifiers must be provided")

    numOfVotes = len(skClassifiers)

    if numCores <= 0:
        numCores = rsgisUtils.numProcessCores()

    tmpPresent = True
    if not os.path.exists(tmpDIR):
        os.makedirs(tmpDIR)
        tmpPresent = False

    outClassImgs = []
    mCoreParams = []
    dirs2DEL = []
    rndGen = random.seed()
    for i in range(numOfVotes):
        cTmpDIR = os.path.join(tmpDIR, str(i))
        if os.path.exists(cTmpDIR):
            shutil.rmtree(cTmpDIR, ignore_errors=True)
        os.makedirs(cTmpDIR)
        dirs2DEL.append(cTmpDIR)

        tmpClassImgOut = os.path.join(tmpDIR,
                                      tmpImgBase + '_' + str(i) + '.kea')
        outClassImgs.append(tmpClassImgOut)
        inParams = dict()
        inParams['skClassifier'] = skClassifiers[i]
        inParams['cTmpDIR'] = cTmpDIR
        inParams['classAreaMask'] = classAreaMask
        inParams['classMaskPxlVal'] = classMaskPxlVal
        inParams['imgFileInfo'] = imgFileInfo
        inParams['tmpClassImgOut'] = tmpClassImgOut
        inParams['gdalformat'] = 'KEA'
        inParams['trainSamplesInfo'] = trainSamplesInfo
        inParams['rndSeed'] = random.randrange(1000)
        mCoreParams.append(inParams)

    # Run processing on multiple cores.
    mProccesPool = Pool(numCores)
    mProccesPool.map(_apply_voting_classifier, mCoreParams)

    # Combine results using MODE.
    rsgislib.imagecalc.calcMultiImgBandStats(outClassImgs, outClassImg,
                                             rsgislib.SUMTYPE_MODE, gdalformat,
                                             rsgislib.TYPE_8UINT, 0, True)
    rsgislib.rastergis.populateStats(clumps=outClassImg,
                                     addclrtab=True,
                                     calcpyramids=True,
                                     ignorezero=True)

    # Colour output classification image.
    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'))

    for trainSample in trainSamplesInfo:
        print("Apply Colour to class \'" + trainSample.className + "\'")
        red[trainSample.classID] = trainSample.red
        green[trainSample.classID] = trainSample.green
        blue[trainSample.classID] = trainSample.blue
        ClassName[trainSample.classID] = trainSample.className

    rat.writeColumn(ratDataset, "Red", red)
    rat.writeColumn(ratDataset, "Green", green)
    rat.writeColumn(ratDataset, "Blue", blue)
    rat.writeColumn(ratDataset, "ClassName", ClassName)
    ratDataset = None

    if not tmpPresent:
        shutil.rmtree(tmpDIR, ignore_errors=True)
    else:
        for cDIR in dirs2DEL:
            shutil.rmtree(cDIR, ignore_errors=True)
コード例 #20
0
#!/usr/bin/env python

import sys
from rios import rat
import numpy

fname = sys.argv[1]

floatdata = numpy.arange(0, 100, dtype=numpy.float)
intdata = numpy.arange(100, 200, dtype=numpy.integer)

rat.writeColumn(fname, "floatstuff", floatdata)
rat.writeColumn(fname, "intstuff", intdata)






コード例 #21
0
def calcClearSkyRegions(cloudsImg, validAreaImg, outputClearSkyMask, outFormat, tmpPath='./tmpClearSky', deleteTmpFiles=True, initClearSkyRegionDist=5000, initClearSkyRegionMinSize=3000, finalClearSkyRegionDist=1000, morphSize=21):
    """
Given a cloud mask, identify the larger extent regions of useful clear-sky regions.

:param cloudsImg: An image with the input mask of the cloud (pixel == 1) and shadow (pixel == 2)
:param validAreaImg: A mask of the image data area (1 = valid and 0 = not-valid; i.e., outside of the data area)
:param outputClearSkyMask: The output mask of the clear sky areas
:param outFormat: The output image format.
:param tmpPath: The path for temporay images produced during the processing to be stored (Default: './tmpClearSky'; Note. all temp files are generated as KEA files).
:param deleteTmpFiles: Boolean as to whether the intermediate files should be deleted following processing (Default: True - delete files).
:param initClearSkyRegionDist: The distance in metres from a cloud/shadow object for the initial identification of clear sky regions (Default: 5000)
:param initClearSkyRegionMinSize: The minimum size (in pixels) of the initial clear sky regions (Default: 3000 pixels)
:param finalClearSkyRegionDist: The distance in metres from a cloud/shadow object for the final boundaries of the clear sky regions (Default: 1000)
:param morphSize: the size of the circular morphological operator used to tidy up the result (Default: 21)

Example::

    import rsgislib.imagecalibration
    cloudsImg = "./Outputs/LS8_20160605_lat52lon261_r24p203_clouds.kea"
    validAreaImg = "./Outputs/LS8_20160605_lat52lon261_r24p203_valid.kea"
    outputMask = "./Outputs/LS8_20160605_lat52lon261_r24p203_openskyvalid.kea"
    tmpPath = "./temp"
    rsgislib.imagecalibration.calcClearSkyRegions(cloudsImg, validAreaImg, outputMask, 'KEA', tmpPath)

"""
    
    import rsgislib
    import rsgislib.imagecalc
    import rsgislib.imageutils
    import rsgislib.segmentation
    import rsgislib.rastergis
    import rsgislib.vectorutils
    import rsgislib.imagemorphology
    import os.path
    import osgeo.gdal as gdal
    from rios import rat
    import numpy
    
    if morphSize % 2 == 0:
        raise rsgislib.RSGISPyException("The size of the morphology operator must be odd.")
    
    baseDataName = os.path.splitext(os.path.basename(cloudsImg))[0]  
    tmpCloudsImgDist2Clouds = os.path.join(tmpPath, baseDataName+"_dist2clouds.kea")
    tmpCloudsImgDist2CloudsNoData = os.path.join(tmpPath, baseDataName+"_dist2clouds_masked.kea")
    tmpInitClearSkyRegions = os.path.join(tmpPath, baseDataName+"initclearsky.kea")
    tmpInitClearSkyRegionsClumps = os.path.join(tmpPath, baseDataName+"initclearskyClumps.kea")
    tmpInitClearSkyRegionsRmSmall = os.path.join(tmpPath, baseDataName+"initclearskyClumpsRMSmall.kea")
    tmpInitClearSkyRegionsFinal = os.path.join(tmpPath, baseDataName+"initclearskyClumpsFinal.kea")
    tmpClearSkyRegionsFullExtent = os.path.join(tmpPath, baseDataName+"clearskyClumpsFullExtent.kea")
    tmpClearSkyRegionsFullExtentClumps = os.path.join(tmpPath, baseDataName+"clearskyClumpsFullExtentClumps.kea")
    tmpClearSkyRegionsFullExtentSelectClumps = os.path.join(tmpPath, baseDataName+"clearskyClumpsFullExtentSelectClumps.kea")
    tmpClearSkyRegionsFullExtentSelectClumpsOpen = os.path.join(tmpPath, baseDataName+"clearskyClumpsFullExtentSelectClumpsOpen.kea")
    tmpClearSkyRegionsFullExtentSelectClumpsOpenClump = os.path.join(tmpPath, baseDataName+"clearskyClumpsFullExtentSelectClumpsOpenClump.kea")
    tmpClearSkyRegionsFullExtentSelectClumpsOpenClumpRMSmall = os.path.join(tmpPath, baseDataName+"clearskyClumpsFullExtentSelectClumpsOpenClumpRMSmall.kea")
    tmpMorphOperator = os.path.join(tmpPath, 'CircularMorphOp.gmtxt')
    
    rsgislib.imagecalc.calcDist2ImgVals(cloudsImg, tmpCloudsImgDist2Clouds, pxlVals=[1,2])
        
    rsgislib.imageutils.maskImage(tmpCloudsImgDist2Clouds, validAreaImg, tmpCloudsImgDist2CloudsNoData, 'KEA', rsgislib.TYPE_32INT, -1, 0)    
            
    rsgislib.imagecalc.imageMath(tmpCloudsImgDist2CloudsNoData, tmpInitClearSkyRegions, 'b1 > '+str(initClearSkyRegionDist), outFormat, rsgislib.TYPE_32UINT)
    
    rsgislib.segmentation.clump(tmpInitClearSkyRegions, tmpInitClearSkyRegionsClumps, 'KEA', False, 0.0, False)
    
    rsgislib.rastergis.populateStats(tmpInitClearSkyRegionsClumps, True, True)
    
    rsgislib.segmentation.rmSmallClumps(tmpInitClearSkyRegionsClumps, tmpInitClearSkyRegionsRmSmall, initClearSkyRegionMinSize, 'KEA')
    
    rsgislib.segmentation.relabelClumps(tmpInitClearSkyRegionsRmSmall, tmpInitClearSkyRegionsFinal, 'KEA', False)
    
    rsgislib.rastergis.populateStats(tmpInitClearSkyRegionsFinal, True, True)
    
    rsgislib.imagecalc.imageMath(tmpCloudsImgDist2CloudsNoData, tmpClearSkyRegionsFullExtent, 'b1 > '+str(finalClearSkyRegionDist), outFormat, rsgislib.TYPE_32UINT)
    
    rsgislib.segmentation.clump(tmpClearSkyRegionsFullExtent, tmpClearSkyRegionsFullExtentClumps, 'KEA', False, 0.0, False)
    
    rsgislib.rastergis.populateStats(tmpClearSkyRegionsFullExtentClumps, True, True)
    
    rsgislib.rastergis.populateRATWithStats(tmpInitClearSkyRegionsFinal, tmpClearSkyRegionsFullExtentClumps, [rsgislib.rastergis.BandAttStats(band=1, maxField='InitRegionInter')])
    
    ratDataset = gdal.Open( tmpClearSkyRegionsFullExtentClumps, gdal.GA_Update )
    InitRegionInter = rat.readColumn(ratDataset, "InitRegionInter")
    ValidClumps = numpy.zeros_like(InitRegionInter, dtype=numpy.dtype('int'))
    ValidClumps[InitRegionInter>0] = 1
    rat.writeColumn(ratDataset, "ValidClumps", ValidClumps)
    ratDataset = None
    
    rsgislib.rastergis.collapseRAT(tmpClearSkyRegionsFullExtentClumps, 'ValidClumps', tmpClearSkyRegionsFullExtentSelectClumps, 'KEA', 1)
    
    rsgislib.rastergis.populateStats(tmpClearSkyRegionsFullExtentSelectClumps, True, True)
    
    rsgislib.imagemorphology.createCircularOp(outputFile=tmpMorphOperator, opSize=morphSize)
    
    rsgislib.imagemorphology.imageOpening(inputImage=tmpClearSkyRegionsFullExtentSelectClumps, outputImage=tmpClearSkyRegionsFullExtentSelectClumpsOpen, tempImage="", morphOperator=tmpMorphOperator, useOpFile=True, opSize=21, gdalformat='KEA', datatype=rsgislib.TYPE_32UINT)
    
    rsgislib.segmentation.clump(tmpClearSkyRegionsFullExtentSelectClumpsOpen, tmpClearSkyRegionsFullExtentSelectClumpsOpenClump, 'KEA', False, 0.0, False)
    
    rsgislib.rastergis.populateStats(tmpClearSkyRegionsFullExtentSelectClumpsOpenClump, True, True)

    rsgislib.segmentation.rmSmallClumps(tmpClearSkyRegionsFullExtentSelectClumpsOpenClump, tmpClearSkyRegionsFullExtentSelectClumpsOpenClumpRMSmall, initClearSkyRegionMinSize, 'KEA')
    
    rsgislib.imagecalc.imageMath(tmpClearSkyRegionsFullExtentSelectClumpsOpenClumpRMSmall, outputClearSkyMask, "b1>0?1:0", outFormat, rsgislib.TYPE_8UINT)
        
    if deleteTmpFiles:
        rsgisUtils = rsgislib.RSGISPyUtils()
        rsgisUtils.deleteFileWithBasename(tmpCloudsImgDist2Clouds)
        rsgisUtils.deleteFileWithBasename(tmpCloudsImgDist2CloudsNoData)
        rsgisUtils.deleteFileWithBasename(tmpInitClearSkyRegions)
        rsgisUtils.deleteFileWithBasename(tmpInitClearSkyRegionsClumps)
        rsgisUtils.deleteFileWithBasename(tmpInitClearSkyRegionsRmSmall)
        rsgisUtils.deleteFileWithBasename(tmpInitClearSkyRegionsFinal)
        rsgisUtils.deleteFileWithBasename(tmpClearSkyRegionsFullExtent)
        rsgisUtils.deleteFileWithBasename(tmpClearSkyRegionsFullExtentClumps)
        rsgisUtils.deleteFileWithBasename(tmpClearSkyRegionsFullExtentSelectClumps)
        rsgisUtils.deleteFileWithBasename(tmpClearSkyRegionsFullExtentSelectClumpsOpen)
        rsgisUtils.deleteFileWithBasename(tmpClearSkyRegionsFullExtentSelectClumpsOpenClump)
        rsgisUtils.deleteFileWithBasename(tmpClearSkyRegionsFullExtentSelectClumpsOpenClumpRMSmall)
        rsgisUtils.deleteFileWithBasename(tmpMorphOperator)
コード例 #22
0
parser = argparse.ArgumentParser()
parser.add_argument("--rat", type=str, required=True, help="Raster attribute table to copy classification to")
parser.add_argument("--txt", type=str, required=True, help="Text file containing classification")
parser.add_argument("--outraster", type=str, required=False, default=None, help="Output Raster classification")
parser.add_argument("--name", type=str, required=False, default='Classification', help="Outname for column in RAT. Defaults to 'Classification'")

args = parser.parse_args()    
 
print('Reading in Classification')
classification = np.genfromtxt(args.txt,dtype=int, skip_header=1)

print('Opening RAT')
inRatFile = args.rat
ratDataset = gdal.Open(inRatFile, gdal.GA_Update)

# Read in column names
colnames = rat.getColumnNames(inRatFile)

# Read in one column
# (just need to check same number as rows as classification)
testCol = rat.readColumn(ratDataset, colnames[0]) 

if testCol.shape[0] != classification.shape[0]:
    raise Exception("The classification file doesn't contain the same number of rows as the RAT")

rat.writeColumn(ratDataset, args.name, classification)
ratDataset = None

if args.outraster is not None:
    rastergis.exportCols2GDALImage(args.rat, args.outraster, 'KEA', rsgislib.TYPE_8INT, [args.name])