def sieve_filter(in_file): source_dataset = gdal.Open(in_file) if source_dataset is None: sys.exit('Problem opening file %s !' % in_file) xsize = source_dataset.RasterXSize ysize = source_dataset.RasterYSize geotransform = source_dataset.GetGeoTransform() projection = source_dataset.GetProjectionRef() in_band = source_dataset.GetRasterBand(1) out_file = os.path.splitext(in_file)[0] + '_sieve.tif' if os.path.exists(out_file): os.remove(out_file) out_driver = gdal.GetDriverByName('GTiff') out_dataset = out_driver.Create(out_file, xsize, ysize, 1, gdal.GDT_Byte) out_band = out_dataset.GetRasterBand(1) result_sieve = gdal.SieveFilter(in_band, None, out_band, 2**10, 4, callback = None) data = out_band.ReadAsArray(0, 0, xsize, ysize) if len(data[np.where(data == 1)]) <= 2 ** 10: sys.exit('the number of water point too few, can not do Raster To Polygon') out_band.SetNoDataValue(0) out_dataset.SetGeoTransform(geotransform) out_dataset.SetProjection(projection) source_dataset = None out_dataset = None return out_file
def test_sieve_3(): drv = gdal.GetDriverByName('GTiff') src_ds = gdal.Open('data/unmergable.grd') src_band = src_ds.GetRasterBand(1) dst_ds = drv.Create('tmp/sieve_3.tif', 5, 7, 1, gdal.GDT_Byte) dst_band = dst_ds.GetRasterBand(1) gdal.SieveFilter(src_band, None, dst_band, 2, 8) # cs_expected = 472 cs_expected = 451 cs = dst_band.Checksum() dst_band = None dst_ds = None if cs == cs_expected \ or gdal.GetConfigOption('CPL_DEBUG', 'OFF') != 'ON': drv.Delete('tmp/sieve_3.tif') if cs != cs_expected: print('Got: ', cs) pytest.fail('got wrong checksum')
def sieve_6(): try: import numpy except: return 'skip' # Try 3002. Should run in less than 10 seconds #size = 3002 size = 102 ds = gdal.GetDriverByName('MEM').Create('', size + 1, size) ar = numpy.zeros((size, size + 1), dtype=numpy.uint8) for i in range(size): for j in range(int(size / 3)): ar[i][size + 1 - 1 - i - 1 - 3 * j] = 255 ar[i][size + 1 - 1 - i - 3 * j] = 255 ar[i][0] = 255 ar[size - 1] = 255 ds.GetRasterBand(1).WriteArray(ar) band = ds.GetRasterBand(1) gdal.SieveFilter(band, None, band, 2, 4) #ar = band.ReadAsArray() #print(ar) cs = band.Checksum() if (size == 102 and cs != 60955) or (size == 3002 and cs != 63178): print('Got: ', cs) gdaltest.post_reason('got wrong checksum') return 'fail' return 'success'
def Sieve_filter(in_file, out_file, size): source_dataset = gdal.Open(in_file) if source_dataset is None: sys.exit('Problem opening file %s!' % in_file) xsize = source_dataset.RasterXSize ysize = source_dataset.RasterYSize geotransform = source_dataset.GetGeoTransform() projection = source_dataset.GetProjectionRef() in_band = source_dataset.GetRasterBand(1) data1 = in_band.ReadAsArray(0, 0, xsize, ysize) # in_band.SetNoDataValue(-999) # out_file=in_file[:-4]+'_sieve.tif' # if os.path.exists(out_file): # os.remove(out_file) # out_driver = gdal.GetDriverByName('GTIFF') out_dataset = out_driver.Create(out_file, xsize, ysize, 1, gdal.GDT_Byte) out_band = out_dataset.GetRasterBand(1) result_sieve = gdal.SieveFilter(in_band, None, out_band, size, 8, callback=None) data = out_band.ReadAsArray(0, 0, xsize, ysize) # if len(data[np.where(data==1)])<=2**10: # # sys.exit('the number of water point too few, can not do Raster To Polygon') out_band.WriteArray(ndimage.binary_dilation(out_band.ReadAsArray(), iterations=1), 0, 0) out_band.SetNoDataValue(0) out_dataset.SetGeoTransform(geotransform) out_dataset.SetProjection(projection) out_band = None source_dataset = None out_dataset = None print('ok')
def sieve_2(): drv = gdal.GetDriverByName('GTiff') src_ds = gdal.Open('data/sieve_src.grd') src_band = src_ds.GetRasterBand(1) dst_ds = drv.Create('tmp/sieve_2.tif', 5, 7, 1, gdal.GDT_Byte) dst_band = dst_ds.GetRasterBand(1) gdal.SieveFilter(src_band, None, dst_band, 2, 8) cs_expected = 370 cs = dst_band.Checksum() dst_band = None dst_ds = None if cs == cs_expected \ or gdal.GetConfigOption( 'CPL_DEBUG', 'OFF' ) != 'ON': drv.Delete('tmp/sieve_2.tif') if cs != cs_expected: print('Got: ', cs) gdaltest.post_reason('got wrong checksum') return 'fail' else: return 'success'
def sieve_7(): gdal.FileFromMemBuffer( '/vsimem/sieve_7.asc', """ncols 7 nrows 7 xllcorner 440720.000000000000 yllcorner 3750120.000000000000 cellsize 60.000000000000 NODATA_value 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 1 0 0 1 1 1 0 1 0 2 2 2 1 0 1 1 2 1 2 1 0 1 1 2 2 2 1 0 1 1 1 1 1 1 """) drv = gdal.GetDriverByName('GTiff') src_ds = gdal.Open('/vsimem/sieve_7.asc') src_band = src_ds.GetRasterBand(1) dst_ds = drv.Create('/vsimem/sieve_7.tif', 7, 7, 1, gdal.GDT_Byte) dst_band = dst_ds.GetRasterBand(1) gdal.SieveFilter(src_band, src_band.GetMaskBand(), dst_band, 4, 4) cs_expected = 42 cs = dst_band.Checksum() dst_band = None dst_ds = None gdal.Unlink('/vsimem/sieve_7.asc') if cs == cs_expected \ or gdal.GetConfigOption( 'CPL_DEBUG', 'OFF' ) != 'ON': drv.Delete('/vsimem/sieve_7.tif') # Expeced: #[[0 0 0 0 0 0 0] # [0 1 1 1 1 1 1] # [0 1 0 0 1 1 1] # [0 1 0 2 2 2 1] # [0 1 1 2 2 2 1] # [0 1 1 2 2 2 1] # [0 1 1 1 1 1 1]] if cs != cs_expected: print('Got: ', cs) gdaltest.post_reason('got wrong checksum') return 'fail' else: return 'success'
def savetif(outpath, arr, info_dict, type='GTiff', filt=True, filt_dic=None): # 保存tif文件 driver = gdal.GetDriverByName(type) new_raster = driver.Create(outpath, info_dict['w'], info_dict['h'], 1, gdal.GDT_Byte) new_raster.SetGeoTransform(info_dict['transform']) new_raster.SetProjection(info_dict['proj']) raster_band = new_raster.GetRasterBand(1) raster_band.WriteArray(arr) if filt: _ = gdal.SieveFilter(raster_band, None, raster_band, filt_dic['thresold'], filt_dic['connectness'])
def _gdal_sieve(self, out_raster, *args, **kwargs): """ Sieve filter using gdal :param args: :param kwargs: :return: """ # Destination dataset dst_ds = self._clone_gdal_dataset(out_raster) # Apply sieve filter with GdalOpen(self.raster_file) as source_ds: gdal.SieveFilter(source_ds.GetRasterBand(1), None, dst_ds.GetRasterBand(1), *args, **kwargs)
def sieve(in_file, dst_dir, operate, th, op, co): # 定义结构元 SE = { 4: np.array([0, 1, 0, 1, 1, 1, 0, 1, 0]), 8: np.array([1, 1, 1, 1, 1, 1, 1, 1, 1]) } basename = os.path.splitext(os.path.basename(in_file))[0] dst_file = os.path.join(dst_dir, basename) + '_sieve1.tif' if os.path.exists(dst_file): return None in_ds = gdal.Open(in_file) xsize = in_ds.RasterXSize ysize = in_ds.RasterYSize prj = in_ds.GetProjection() geo = in_ds.GetGeoTransform() srcband = in_ds.GetRasterBand(1) # 创建输出文件,存放经开运算和填孔洞后的结果 drv = gdal.GetDriverByName('GTiff') dst_ds = drv.Create(dst_file, xsize, ysize, 1, gdal.GDT_Byte) dst_ds.SetProjection(prj) dst_ds.SetGeoTransform(geo) dstband = dst_ds.GetRasterBand(1) maskband = None result = gdal.SieveFilter(srcband, maskband, dstband, th, co[0], callback=None) dstband.FlushCache() # 进行开操作,平滑边缘 kernel = SE[co[1]] win_size = np.sqrt(kernel.size) src_data = dstband.ReadAsArray() if not win_size % 1 == 0: raise ('The size of SE is wrong!') # 根据输入判断是进行开运算还是进行闭运算 if operate: filter_img = closing(win_size, kernel, op, src_data) else: filter_img = opening(win_size, kernel, op, src_data) # 更新结果 dstband.WriteArray(filter_img) dstband.FlushCache() in_ds = srcband = dst_ds = dstband = filter_img = None return None
def sieve_8(): gdal.FileFromMemBuffer('/vsimem/sieve_8.asc', """ncols 7 nrows 7 xllcorner 440720.000000000000 yllcorner 3750120.000000000000 cellsize 60.000000000000 0 0 0 0 0 0 0 0 5 5 0 0 0 0 0 5 2 3 4 0 0 0 0 8 1 5 0 0 0 0 7 6 5 9 0 0 0 0 0 9 9 0 0 0 0 0 0 0 0 """) drv = gdal.GetDriverByName( 'GTiff' ) src_ds = gdal.Open('/vsimem/sieve_8.asc') src_band = src_ds.GetRasterBand(1) dst_ds = drv.Create('/vsimem/sieve_8.tif', 7, 7, 1, gdal.GDT_Byte ) dst_band = dst_ds.GetRasterBand(1) gdal.SieveFilter( src_band, src_band.GetMaskBand(), dst_band, 4, 4 ) # All non 0 should be mapped to 0 cs_expected = 0 cs = dst_band.Checksum() dst_band = None dst_ds = None gdal.Unlink('/vsimem/sieve_8.asc') if cs == cs_expected \ or gdal.GetConfigOption( 'CPL_DEBUG', 'OFF' ) != 'ON': drv.Delete( '/vsimem/sieve_8.tif' ) if cs != cs_expected: print('Got: ', cs) gdaltest.post_reason( 'got wrong checksum' ) return 'fail' else: return 'success'
def polygonizeSelectionImage(): ds_img = gdal.Open( pImgSel['filename'], GA_ReadOnly ) if gdal.GetLastErrorType() != 0: return { 'isOk': False, 'msg': gdal.GetLastErrorMsg() } band = ds_img.GetRasterBand( 1 ) # Sieve Band drv = gdal.GetDriverByName('MEM') ds_sieve = drv.Create( '', ds_img.RasterXSize, ds_img.RasterYSize,1, band.DataType ) ds_sieve.SetGeoTransform( ds_img.GetGeoTransform() ) ds_sieve.SetProjection( self.paramsImage['wktProj'] ) band_sieve = ds_sieve.GetRasterBand(1) p_threshold = self.paramsSieve['threshold'] p_connectedness = self.paramsSieve['connectedness'] gdal.SieveFilter( band, None, band_sieve, p_threshold, p_connectedness, [], callback=None ) ds_img = band = None if gdal.GetLastErrorType() != 0: return { 'isOk': False, 'msg': gdal.GetLastErrorMsg() } # Memory layer - Polygonize srs = osr.SpatialReference() srs.ImportFromWkt( self.paramsImage['wktProj'] ) drv_poly = ogr.GetDriverByName('MEMORY') ds_poly = drv_poly.CreateDataSource('memData') layer_poly = ds_poly.CreateLayer( 'memLayer', srs, ogr.wkbPolygon ) field = ogr.FieldDefn("dn", ogr.OFTInteger) layer_poly.CreateField( field ) idField = 0 gdal.Polygonize( band_sieve, None, layer_poly, idField, [], callback=None ) ds_sieve = band_sieve = None if gdal.GetLastErrorType() != 0: return { 'isOk': False, 'msg': gdal.GetLastErrorMsg() } # Get Geoms geoms = [] layer_poly.SetAttributeFilter("dn = 255") for feat in layer_poly: geoms.append( feat.GetGeometryRef().Clone() ) ds_poly = layer_poly = None return { 'isOk': True, 'geoms': geoms }
def ClumpEliminate(rasterPath, neighbors, pxSize): drvMemR = gdal.GetDriverByName('MEM') # Output is a raster that is written into memory ds = gdal.Open(rasterPath) gt = ds.GetGeoTransform() pr = ds.GetProjection() cols = ds.RasterXSize rows = ds.RasterYSize # Generate output-file --> first in memory sieveMem = drvMemR.Create('', cols, rows, 1, gdal.GDT_Byte) sieveMem.SetGeoTransform(gt) sieveMem.SetProjection(pr) # Do the ClumpSieve rb_in = ds.GetRasterBand(1) rb_out = sieveMem.GetRasterBand(1) maskband = None prog_func = gdal.TermProgress result = gdal.SieveFilter(rb_in, maskband, rb_out, pxSize, neighbors, callback=prog_func) return sieveMem
dst_ds = drv.Create(dst_filename, src_ds.RasterXSize, src_ds.RasterYSize, 1, srcband.DataType) wkt = src_ds.GetProjection() if wkt != '': dst_ds.SetProjection(wkt) dst_ds.SetGeoTransform(src_ds.GetGeoTransform()) dstband = dst_ds.GetRasterBand(1) else: dstband = srcband # ============================================================================= # Invoke algorithm. # ============================================================================= if quiet_flag: prog_func = None else: prog_func = gdal.TermProgress_nocb result = gdal.SieveFilter(srcband, maskband, dstband, threshold, connectedness, callback=prog_func) src_ds = None dst_ds = None mask_ds = None
# we extract the mask that corresponds to the backgroung of the segment in this BB mask = np.zeros((image_seg.shape[1:]), dtype=int) mask[ind_seg_i_mod, ind_seg_j_mod] = 1 # we perform the segmentation of the whole BB labels = segmented_array_enc[ i_min:i_max + 1, j_min:j_max + 1] #we open segmentation of the encoded image # we apply mask to extract only the segment of the interest and we create a temporal file with it labels = labels * mask geo_seg = geo ds = create_tiff(1, "", labels.shape[1], labels.shape[0], gdal.GDT_Float32, labels, geo_seg, proj) ds_mask = create_tiff(1, "", labels.shape[1], labels.shape[0], gdal.GDT_Float32, mask, geo_seg, proj) gdal.SieveFilter(ds.GetRasterBand(1), ds_mask.GetRasterBand(1), ds.GetRasterBand(1), min_obj_size + 1, 4) # we filter out small objects ds.FlushCache() # We correct segmentation in case we have two separate segments with the same label, because of the mask application on the original segmentation of bb labels = ds.GetRasterBand(1).ReadAsArray().astype(int) # print(labels) labels_no_zero = np.delete(labels.flatten(), np.where(labels.flatten() == 0)[0]) unique_labels, unique_labels_size = np.unique(labels_no_zero, return_counts=True) if len(unique_labels) > 1: # We create temporal shp where we check segments srs = osr.SpatialReference() srs.ImportFromWkt(ds.GetProjectionRef()) dst_ds_shp = driver_memory_shp.CreateDataSource("memData")
def gdal_sieve(src_filename: Optional[str] = None, dst_filename: PathLikeOrStr = None, driver_name: Optional[str] = None, mask: str = 'default', threshold: int = 2, connectedness: int = 4, quiet: bool = False): # ============================================================================= # Verify we have next gen bindings with the sievefilter method. # ============================================================================= try: gdal.SieveFilter except AttributeError: print('') print( 'gdal.SieveFilter() not available. You are likely using "old gen"' ) print('bindings or an older version of the next gen bindings.') print('') return 1 # ============================================================================= # Open source file # ============================================================================= if dst_filename is None: src_ds = gdal.Open(src_filename, gdal.GA_Update) else: src_ds = gdal.Open(src_filename, gdal.GA_ReadOnly) if src_ds is None: print('Unable to open %s ' % src_filename) return 1 srcband = src_ds.GetRasterBand(1) if mask == 'default': maskband = srcband.GetMaskBand() elif mask == 'none': maskband = None else: mask_ds = gdal.Open(mask) maskband = mask_ds.GetRasterBand(1) # ============================================================================= # Create output file if one is specified. # ============================================================================= if dst_filename is not None: if driver_name is None: driver_name = GetOutputDriverFor(dst_filename) drv = gdal.GetDriverByName(driver_name) dst_ds = drv.Create(dst_filename, src_ds.RasterXSize, src_ds.RasterYSize, 1, srcband.DataType) wkt = src_ds.GetProjection() if wkt != '': dst_ds.SetProjection(wkt) gt = src_ds.GetGeoTransform(can_return_null=True) if gt is not None: dst_ds.SetGeoTransform(gt) dstband = dst_ds.GetRasterBand(1) dstband.SetNoDataValue(srcband.GetNoDataValue()) else: dstband = srcband # ============================================================================= # Invoke algorithm. # ============================================================================= if quiet: prog_func = None else: prog_func = gdal.TermProgress_nocb result = gdal.SieveFilter(srcband, maskband, dstband, threshold, connectedness, callback=prog_func) src_ds = None dst_ds = None mask_ds = None return result
def main(argv): threshold = 2 connectedness = 4 quiet_flag = 0 src_filename = None dst_filename = None frmt = None mask = 'default' argv = gdal.GeneralCmdLineProcessor(argv) if argv is None: return 0 # Parse command line arguments. i = 1 while i < len(argv): arg = argv[i] if arg == '-of' or arg == '-f': i = i + 1 frmt = argv[i] elif arg == '-4': connectedness = 4 elif arg == '-8': connectedness = 8 elif arg == '-q' or arg == '-quiet': quiet_flag = 1 elif arg == '-st': i = i + 1 threshold = int(argv[i]) elif arg == '-nomask': mask = 'none' elif arg == '-mask': i = i + 1 mask = argv[i] elif arg == '-mask': i = i + 1 mask = argv[i] elif arg[:2] == '-h': return Usage() elif src_filename is None: src_filename = argv[i] elif dst_filename is None: dst_filename = argv[i] else: return Usage() i = i + 1 if src_filename is None: return Usage() # ============================================================================= # Verify we have next gen bindings with the sievefilter method. # ============================================================================= try: gdal.SieveFilter except AttributeError: print('') print( 'gdal.SieveFilter() not available. You are likely using "old gen"' ) print('bindings or an older version of the next gen bindings.') print('') return 1 # ============================================================================= # Open source file # ============================================================================= if dst_filename is None: src_ds = gdal.Open(src_filename, gdal.GA_Update) else: src_ds = gdal.Open(src_filename, gdal.GA_ReadOnly) if src_ds is None: print('Unable to open %s ' % src_filename) return 1 srcband = src_ds.GetRasterBand(1) if mask == 'default': maskband = srcband.GetMaskBand() elif mask == 'none': maskband = None else: mask_ds = gdal.Open(mask) maskband = mask_ds.GetRasterBand(1) # ============================================================================= # Create output file if one is specified. # ============================================================================= if dst_filename is not None: if frmt is None: frmt = GetOutputDriverFor(dst_filename) drv = gdal.GetDriverByName(frmt) dst_ds = drv.Create(dst_filename, src_ds.RasterXSize, src_ds.RasterYSize, 1, srcband.DataType) wkt = src_ds.GetProjection() if wkt != '': dst_ds.SetProjection(wkt) gt = src_ds.GetGeoTransform(can_return_null=True) if gt is not None: dst_ds.SetGeoTransform(gt) dstband = dst_ds.GetRasterBand(1) else: dstband = srcband # ============================================================================= # Invoke algorithm. # ============================================================================= if quiet_flag: prog_func = None else: prog_func = gdal.TermProgress_nocb result = gdal.SieveFilter(srcband, maskband, dstband, threshold, connectedness, callback=prog_func) src_ds = None dst_ds = None mask_ds = None return result
def pyNearBlack(dstFilename, srcFilename, domFileNum, **kwargs): """ 执行剔除异常值操作,为静态函数,是对gdal.Nearblack的封装。 :param dstFilename: 处理后数据文件路径名 :param srcFilename: 原始数据文件路径名 :param domFileNum: 原始数据个数 :param kwargs: 参数 :return: (dstFilename,srcFilename,domFileNum,mskList) """ try: blockSize = 2048 gdal.AllRegister() gdal.SetConfigOption('TIFF_USE_OVR', 'YES') gdal.SetConfigOption('HFA_USE_RRD', 'YES') # gdal.SetConfigOption('JPEG_QUALITY_OVERVIEW', '50') # gdal.SetConfigOption('HFA_COMPRESS_OVR', 'YES') imgdriver = gdal.GetDriverByName('HFA') driver = gdal.GetDriverByName(kwargs['format']) domSrcDS = gdal.Open(srcFilename) COMPRESSoptions = ['COMPRESS=RLE'] if kwargs['ext'] != 'img': COMPRESSoptions = [ 'COMPRESS=LZW', 'TFW=YES', 'GEOTIFF_KEYS_FLAVOR=ESRI_PE' ] # ,'PREDICTOR=2' domDstDS = driver.Create(dstFilename, domSrcDS.RasterXSize, domSrcDS.RasterYSize, domSrcDS.RasterCount, gdal.GDT_Byte, options=COMPRESSoptions) GeoTransform = domSrcDS.GetGeoTransform() Projection = domSrcDS.GetProjection() domDstDS.SetGeoTransform(GeoTransform) domDstDS.SetProjection(Projection) #简单去边模式#改成convex # rowNum = domDstDS.RasterYSize # columnNum = domDstDS.RasterXSize # # vRowNum = rowNum/10 # hColNum = columnNum/10 # # for i in range(domDstDS.RasterCount): # srcband = domSrcDS.GetRasterBand(i + 1) # band = domDstDS.GetRasterBand(i + 1) # upArray = srcband.ReadAsArray(0, 0, columnNum, vRowNum) # downArray = srcband.ReadAsArray(0, 9 * vRowNum, columnNum, rowNum) # leftArray = srcband.ReadAsArray(0, vRowNum, hColNum, 9 * vRowNum) # rightArray = srcband.ReadAsArray(9 * hColNum, vRowNum, columnNum, 9 * vRowNum) # # # temparray = np.where(temparray == 255, 254, temparray) # # temp = np.where(tempmask == 0, 255, temparray) # # band.WriteArray(temp, colstep * blockSize, rowstep * blockSize) # for rowstep in range(rowblockNum): # for colstep in range(colblockNum): # rowpafNum = blockSize # colpafNum = blockSize # if (rowstep == rowblockNum - 1): # rowpafNum = int((rowNum - 1) % blockSize) + 1 # if (colstep == colblockNum - 1): # colpafNum = int((columnNum - 1) % blockSize) + 1 # for i in range(domDstDS.RasterCount): # srcband = domSrcDS.GetRasterBand(i + 1) # band = domDstDS.GetRasterBand(i + 1) # band.SetNoDataValue(255) # temparray = srcband.ReadAsArray(colstep * blockSize, rowstep * blockSize, colpafNum, rowpafNum) # tempmask = mskBand.ReadAsArray(colstep * blockSize, rowstep * blockSize, colpafNum, rowpafNum) # temparray = np.where(temparray == 255, 254, temparray) # temp = np.where(tempmask == 0, 255, temparray) # band.WriteArray(temp, colstep * blockSize, rowstep * blockSize) # # ==================================================================================== # rowNum = domDstDS.RasterYSize # columnNum = domDstDS.RasterXSize # # rowblockNum = int((rowNum - 1) / blockSize) + 1 # colblockNum = int((columnNum - 1) / blockSize) + 1 # # gdal.Nearblack(domDstDS, # domSrcDS, # format=kwargs['format'], # colors=[tuple(kwargs['easyColors'] for i in range(domSrcDS.RasterCount))], # nearDist=kwargs['easyNearDist'], # maxNonBlack=1, # setMask=True, # ) # domDstDS = None # domDstDS = gdal.Open(dstFilename,gdal.GA_Update) # # # 通过msk文件统计总像元数量和异常像元数量 # mskDs = gdal.Open(dstFilename + '.msk') # mskBand = mskDs.GetRasterBand(1) # mskList = mskBand.GetHistogram(-0.5,255.5,buckets = 256, include_out_of_range = 0,approx_ok = 0) # for rowstep in range(rowblockNum): # for colstep in range(colblockNum): # rowpafNum = blockSize # colpafNum = blockSize # if (rowstep == rowblockNum - 1): # rowpafNum = int((rowNum - 1) % blockSize) + 1 # if (colstep == colblockNum - 1): # colpafNum = int((columnNum - 1) % blockSize) + 1 # for i in range(domDstDS.RasterCount): # srcband = domSrcDS.GetRasterBand(i + 1) # band = domDstDS.GetRasterBand(i + 1) # band.SetNoDataValue(255) # temparray = srcband.ReadAsArray(colstep * blockSize, rowstep * blockSize, colpafNum, rowpafNum) # tempmask = mskBand.ReadAsArray(colstep * blockSize, rowstep * blockSize, colpafNum, rowpafNum) # # temparray = np.where(temparray == 255, 254, temparray) # temp = np.where(tempmask == 0, 254, temparray) # band.WriteArray(temp, colstep * blockSize, rowstep * blockSize) # # if kwargs['ovrBuild'] is True: # domDstDS.BuildOverviews("NEAREST", [2, 4, 8]) # # domSrcDS = None # domDstDS = None # mskDs = None # # # ==================================================================================== # # # print('easyKill == True') # # rowNum = domDstDS.RasterYSize # # columnNum = domDstDS.RasterXSize # # # # rowblockNum = int((rowNum - 1) / blockSize) + 1 # # colblockNum = int((columnNum - 1) / blockSize) + 1 # # # # # mskDS = gdal.Open(dstFilename + '.msk',gdal.GA_Update) # # # # # 分块检查异常值手动生成掩膜的方案 # # mskDS = imgdriver.Create(dstFilename.replace('.' + kwargs['ext'], '_M.img'), domSrcDS.RasterXSize, # # domSrcDS.RasterYSize, # # 1, gdal.GDT_Byte, options=['COMPRESS=RLE']) # # # # mskDS.SetGeoTransform(GeoTransform) # # mskDS.SetProjection(Projection) # # # # delNum = kwargs['delNum'] # # # # mskBand = mskDS.GetRasterBand(1) # # # # for rowstep in range(rowblockNum): # # for colstep in range(colblockNum): # # rowpafNum = blockSize # # colpafNum = blockSize # # if (rowstep == rowblockNum - 1): # # rowpafNum = int((rowNum - 1) % blockSize) + 1 # # if (colstep == colblockNum - 1): # # colpafNum = int((columnNum - 1) % blockSize) + 1 # # mskArray = np.zeros((rowpafNum, colpafNum), # # dtype=np.int8) # np.ones(rowpafNum, colpafNum) * 255 # mskBand.ReadAsArray(colstep * blockSize, rowstep * blockSize, colpafNum, rowpafNum) # # for i in range(domSrcDS.RasterCount): # # band = domSrcDS.GetRasterBand(i + 1) # # domSrcNoData = band.GetNoDataValue() # # tempArray = band.ReadAsArray(colstep * blockSize, rowstep * blockSize, colpafNum, rowpafNum) # # mskArray = np.where((mskArray == 0) & ((tempArray <= kwargs['easyColors'] + kwargs['easyNearDist']) & # # (tempArray >= kwargs['easyColors'] - kwargs['easyNearDist'])), 0, 255) # # band = None # # mskBand.WriteArray(mskArray, colstep * blockSize, rowstep * blockSize) # # gdal.SieveFilter(srcBand=mskBand, maskBand=None, dstBand=mskBand, threshold=(1024)) # # # # mskDS = None # # # 通过msk文件统计总像元数量和异常像元数量 # # mskDS = gdal.Open(dstFilename.replace('.' + kwargs['ext'], '_M.img')) # # mskBand = mskDS.GetRasterBand(1) # # mskList = mskBand.GetHistogram(-0.5, 255.5, buckets=256, include_out_of_range=0, approx_ok=0) # # # # for rowstep in range(rowblockNum): # # for colstep in range(colblockNum): # # rowpafNum = blockSize # # colpafNum = blockSize # # if (rowstep == rowblockNum - 1): # # rowpafNum = int((rowNum - 1) % blockSize) + 1 # # if (colstep == colblockNum - 1): # # colpafNum = int((columnNum - 1) % blockSize) + 1 # # for i in range(domDstDS.RasterCount): # # srcband = domSrcDS.GetRasterBand(i + 1) # # band = domDstDS.GetRasterBand(i + 1) # # band.SetNoDataValue(255) # # temparray = srcband.ReadAsArray(colstep * blockSize, rowstep * blockSize, colpafNum, rowpafNum) # # tempmask = mskBand.ReadAsArray(colstep * blockSize, rowstep * blockSize, colpafNum, rowpafNum) # # temparray = np.where(temparray == 255, 254, temparray) # # temp = np.where(tempmask == 0, 255, temparray) # # band.WriteArray(temp, colstep * blockSize, rowstep * blockSize) # # # # if kwargs['ovrBuild'] is True: # # domDstDS.BuildOverviews("NEAREST", [2, 4, 8]) # # # # domSrcDS = None # # domDstDS = None # # mskDS = None # # return (dstFilename, srcFilename, domFileNum, mskList, kwargs['ext']) # print('easyKill == False') # gdal.Nearblack(domDstDS, # domSrcDS, # format=kwargs['format'], # colors=[tuple(kwargs['colors'] for i in range(domSrcDS.RasterCount))], # nearDist=kwargs['nearDist'], # maxNonBlack=kwargs['maxNonBlack'], # setMask=kwargs['setMask'], # ) # 这里不关闭数据集的话,msk数据将不能保存,下一步没法用。不用nearblack及其msk的话就不用考虑了 # domDstDS = None # domDstDS = gdal.Open(dstFilename,gdal.GA_Update) rowNum = domDstDS.RasterYSize columnNum = domDstDS.RasterXSize rowblockNum = int((rowNum - 1) / blockSize) + 1 colblockNum = int((columnNum - 1) / blockSize) + 1 c254 = kwargs['c254'] if c254 == True: for rowstep in range(rowblockNum): for colstep in range(colblockNum): rowpafNum = blockSize colpafNum = blockSize if (rowstep == rowblockNum - 1): rowpafNum = int((rowNum - 1) % blockSize) + 1 if (colstep == colblockNum - 1): colpafNum = int((columnNum - 1) % blockSize) + 1 for i in range(domDstDS.RasterCount): srcband = domSrcDS.GetRasterBand(i + 1) band = domDstDS.GetRasterBand(i + 1) band.SetNoDataValue(255) temparray = srcband.ReadAsArray( colstep * blockSize, rowstep * blockSize, colpafNum, rowpafNum) temparray = np.where(temparray >= 255, 254, temparray) band.WriteArray(temparray, colstep * blockSize, rowstep * blockSize) if kwargs['ovrBuild'] is True: domDstDS.BuildOverviews("NEAREST", [2, 4, 8]) domSrcDS = None domDstDS = None return (dstFilename, srcFilename, domFileNum, None, kwargs['ext']) # mskDS = gdal.Open(dstFilename + '.msk',gdal.GA_Update) # 分块检查异常值手动生成掩膜的方案 mskDS = imgdriver.Create(dstFilename.replace( '.' + kwargs['ext'], '_M.img'), domSrcDS.RasterXSize, domSrcDS.RasterYSize, 1, gdal.GDT_Byte, options=['COMPRESS=RLE']) mskDS.SetGeoTransform(GeoTransform) mskDS.SetProjection(Projection) delNum = kwargs['delNum'] mskBand = mskDS.GetRasterBand(1) for rowstep in range(rowblockNum): for colstep in range(colblockNum): rowpafNum = blockSize colpafNum = blockSize if (rowstep == rowblockNum - 1): rowpafNum = int((rowNum - 1) % blockSize) + 1 if (colstep == colblockNum - 1): colpafNum = int((columnNum - 1) % blockSize) + 1 mskArray = np.zeros( (rowpafNum, colpafNum), dtype=np.int8 ) # np.ones(rowpafNum, colpafNum) * 255 # mskBand.ReadAsArray(colstep * blockSize, rowstep * blockSize, colpafNum, rowpafNum) for i in range(domSrcDS.RasterCount): band = domSrcDS.GetRasterBand(i + 1) domSrcNoData = band.GetNoDataValue() tempArray = band.ReadAsArray(colstep * blockSize, rowstep * blockSize, colpafNum, rowpafNum) mskArray = np.where( (mskArray == 0) & (((tempArray <= kwargs['colors'] + kwargs['nearDist']) & (tempArray >= kwargs['colors'] - kwargs['nearDist'])) | (tempArray == domSrcNoData)), 0, 255) band = None mskBand.WriteArray(mskArray, colstep * blockSize, rowstep * blockSize) gdal.SieveFilter(srcBand=mskBand, maskBand=None, dstBand=mskBand, threshold=(1024)) #if delNum != 0: unit = abs(GeoTransform[5]) mskLessDS = imgdriver.Create(dstFilename.replace( '.' + kwargs['ext'], '_N.img'), domSrcDS.RasterXSize, domSrcDS.RasterYSize, 1, gdal.GDT_Byte, options=['COMPRESS=RLE']) mskLessDS.SetGeoTransform(GeoTransform) mskLessDS.SetProjection(Projection) #mskLessBand = mskLessDS.GetRasterBand(1) shpFilename = dstFilename.replace('.' + kwargs['ext'], '_N.shp') dstLayername = "POLYGONIZED" drv = ogr.GetDriverByName("ESRI Shapefile") dst_ds = drv.CreateDataSource(shpFilename) dst_layer = dst_ds.CreateLayer(dstLayername, srs=None) fd = ogr.FieldDefn("Status", ogr.OFTInteger) dst_layer.CreateField(fd) dst_field = dst_layer.FindFieldIndex("Status", 1) gdal.Polygonize(mskBand, None, dst_layer, dst_field, [], callback=None) dst_ds = None dst_ds = ogr.Open(shpFilename, 1) dst_layer2 = dst_ds.GetLayer(0) maxAreaFID = None maxTempArea = 0 delIndexList = [] mergeIndexList = [] mergePolyList = [] f = dst_layer2.GetNextFeature() while f is not None: # for f in dst_layer2: if f.GetField('status') == 0: delIndexList.append(f.GetFID()) else: mergeIndexList.append(f.GetFID()) mergePolyList.append( shape(json.loads(f.geometry().ExportToJson()))) f = None f = dst_layer2.GetNextFeature() [dst_layer2.DeleteFeature(i) for i in delIndexList] [dst_layer2.DeleteFeature(i) for i in mergeIndexList[1:]] feat = dst_layer2.GetFeature(mergeIndexList[0]) reducePolyList = [] print(mergePolyList) # 以下代码存在的问题:当区域被完全分割成几个子区域后,缓冲区无法修复已经被区分的子区域之间的裂痕(如白色道路)。 # 解决方法是对整体进行级联合并,并对整体进行缓冲区和内扩操作。 # for simplePoly in mergePolyList: # if simplePoly.geom_type == 'Polygon': # simplePoly = Polygon(simplePoly.exterior) # else: # maxArea = 0 # maxExt = None # for p in simplePoly: # if (p.area > maxArea): # maxArea = p.area # maxExt = p.exterior # simplePoly = Polygon(maxExt) # fx = simplePoly.buffer(distance=kwargs['maxNonBlack'] * unit, cap_style=1, join_style=2).buffer( # distance=-(kwargs['maxNonBlack'] * unit), cap_style=1, join_style=2) # reducefx = fx # if delNum != 0: # reducefx = fx.buffer(distance=-(delNum * unit), cap_style=1, join_style=3) # if reducefx.geom_type == 'Polygon': # reducefx = Polygon(reducefx.exterior) # else: # maxArea = 0 # maxExt = None # for p in reducefx: # if (p.area > maxArea): # maxArea = p.area # maxExt = p.exterior # reducefx = Polygon(maxExt) # reducePolyList.append(reducefx) for simplePoly in mergePolyList: if simplePoly.geom_type == 'Polygon': simplePoly = Polygon(simplePoly.exterior) else: maxArea = 0 maxExt = None for p in simplePoly: if (p.area > maxArea): maxArea = p.area maxExt = p.exterior simplePoly = Polygon(maxExt) reducePolyList.append(simplePoly) poly = cascaded_union(reducePolyList) if kwargs['easyKill'] == True: poly = poly.convex_hull # 对整体poly进行边缘修正与内扩 poly = poly.buffer(0) poly = poly.buffer(distance=kwargs['maxNonBlack'] * unit, cap_style=2, join_style=1).buffer( distance=-(kwargs['maxNonBlack'] * unit), cap_style=2, join_style=2) if delNum != 0: poly = poly.buffer(distance=-(delNum * unit), cap_style=2, join_style=1) # 消除内部冗余几何形态 finalPolyList = [] if poly.geom_type == 'Polygon': poly = Polygon(poly.exterior) else: for p in poly: maxExt = p.exterior subPoly = Polygon(maxExt) finalPolyList.append(subPoly) poly = cascaded_union(finalPolyList) geobf = ogr.CreateGeometryFromWkb(poly.wkb) feat.SetGeometry(geobf) dst_layer2.SetFeature(feat) dst_ds = None gdal.Rasterize(mskLessDS, shpFilename, attribute='status') # 如果注释这里,则最终使用阈值法 mskBand = None mskBand = mskLessDS.GetRasterBand(1) # 废弃 # gdal.SieveFilter(srcBand=mskBand, maskBand=None, dstBand=mskBand, threshold=1024) mskList = mskBand.GetHistogram(-0.5, 255.5, buckets=256, include_out_of_range=0, approx_ok=0) nodataFill = kwargs['nodataFill'] for rowstep in range(rowblockNum): for colstep in range(colblockNum): rowpafNum = blockSize colpafNum = blockSize if (rowstep == rowblockNum - 1): rowpafNum = int((rowNum - 1) % blockSize) + 1 if (colstep == colblockNum - 1): colpafNum = int((columnNum - 1) % blockSize) + 1 for i in range(domDstDS.RasterCount): srcband = domSrcDS.GetRasterBand(i + 1) band = domDstDS.GetRasterBand(i + 1) band.SetNoDataValue(255) temparray = srcband.ReadAsArray( colstep * blockSize, rowstep * blockSize, colpafNum, rowpafNum) tempmask = mskBand.ReadAsArray(colstep * blockSize, rowstep * blockSize, colpafNum, rowpafNum) temparray = np.where(temparray == 255, 254, temparray) if nodataFill is True: temp = np.where(tempmask == 0, 0, temparray) else: temp = np.where(tempmask == 0, 255, temparray) band.WriteArray(temp, colstep * blockSize, rowstep * blockSize) if kwargs['ovrBuild'] is True: domDstDS.BuildOverviews("NEAREST", [2, 4, 8]) domSrcDS = None domDstDS = None mskLessDS = None mskDS = None return (dstFilename, srcFilename, domFileNum, mskList, kwargs['ext']) except Exception as e: print(e.__str__()) return (False, e.__str__())
test[(slope_array <= 5) & (slope_array >= 0)] = 1 # test[(slope_array > 5) & (slope_array <= 10)] = 2 crs = proj4_from_raster(slope) array_to_raster('test_raster.tif', test, geo_grid, crs) # Test with gdal sieve filter # sieved = np.zeros(test.shape) # array_to_raster('test_raster_sieved.tif', sieved, geo_grid, crs) src_ds = gdal.Open('test_raster.tif') src_band = src_ds.GetRasterBand(1) drv = gdal.GetDriverByName('GTiff') dst_ds = drv.Create('test_raster_sieved.tif', test.shape[1], test.shape[0], 1, gdal.GDT_Byte) dst_band = dst_ds.GetRasterBand(1) gdal.SieveFilter(src_band, None, dst_band, 20, 4) # dst_band = None # dst_ds = None del dst_band, dst_ds # Get array from raster sieved = raster_to_array('test_raster_sieved.tif') pyplot.imshow(sieved) pyplot.show() # with rasterio.drivers(): # # with rasterio.open('test_raster.tif') as src:
def pyMosaicChecker(dstFilename, srcFilename, demFileNum, **kwargs): """ 执行dem接边检查与记录操作,为静态函数。 :param dstFilename: 处理后数据文件路径名 :param srcFilename: 原始数据文件路径名 :param demFileNum: 原始数据个数 :param kwargs: 自定义参数 :return: (dstFilename,srcFilename,demFileNum) """ #tempFilename = os.path.splitext(dstFilename)[0] + '.img' #srcFilename = r"D:\Documents\Tencent Files\344042096\FileRecv\dem_cs\dem_cs.img" slopeFilename = os.path.splitext(dstFilename)[0] + '_slope.img' aspectFilename = os.path.splitext(dstFilename)[0] + '_aspect.img' resultFilename = os.path.splitext(dstFilename)[0] + '_result.img' resultShpname = dstFilename # r"D:\Documents\Tencent Files\344042096\FileRecv\dem_cs\result\dem_cs_result.shp" driver = gdal.GetDriverByName(kwargs['format']) demSrcDS = gdal.Open(srcFilename) # demSlopeDS = driver.Create(slopeFilename, demSrcDS.RasterXSize, demSrcDS.RasterYSize, # demSrcDS.RasterCount, gdal.GDT_Byte, options=['COMPRESS=RLE']) # demResultDS = driver.Create(resultFilename, demSrcDS.RasterXSize, demSrcDS.RasterYSize, demSrcDS.RasterCount, gdal.GDT_Byte, options=['COMPRESS=RLE']) GeoTransform = demSrcDS.GetGeoTransform() Projection = demSrcDS.GetProjection() demResultDS.SetGeoTransform(GeoTransform) demResultDS.SetProjection(Projection) # # demAspectDS.SetGeoTransform(GeoTransform) # demAspectDS.SetProjection(Projection) demSlopeDS = gdal.DEMProcessing(slopeFilename, srcFilename, "slope", computeEdges=True) demAspectDS = gdal.DEMProcessing(aspectFilename, srcFilename, "aspect", computeEdges=True) rowNum = demSrcDS.RasterYSize columnNum = demSrcDS.RasterXSize rowblockNum = int((rowNum - 1) / 1024) + 1 colblockNum = int((columnNum - 1) / 1024) + 1 valueRange = kwargs['valueRange'] slopeThreshold = kwargs['slopeThreshold'] srcBand = demSrcDS.GetRasterBand(1) slopeBand = demSlopeDS.GetRasterBand(1) aspectBand = demAspectDS.GetRasterBand(1) resultBand = demResultDS.GetRasterBand(1) srcNoDataValue = srcBand.GetNoDataValue() for rowstep in range(rowblockNum): for colstep in range(colblockNum): rowpafNum = 1024 colpafNum = 1024 if (rowstep == rowblockNum - 1): rowpafNum = int((rowNum - 1) % 1024) + 1 if (colstep == colblockNum - 1): colpafNum = int((columnNum - 1) % 1024) + 1 srcArray = srcBand.ReadAsArray(colstep * 1024, rowstep * 1024, colpafNum, rowpafNum) slopeArray = slopeBand.ReadAsArray(colstep * 1024, rowstep * 1024, colpafNum, rowpafNum) aspectArray = aspectBand.ReadAsArray(colstep * 1024, rowstep * 1024, colpafNum, rowpafNum) aspectTemp = np.where( ((aspectArray >= 0) & (aspectArray <= 1)) | ((aspectArray >= 89) & (aspectArray <= 91)) | ((aspectArray >= 179) & (aspectArray <= 181)) | ((aspectArray >= 269) & (aspectArray <= 271)) | ((aspectArray >= 359) & (aspectArray <= 360)), 0, 255) ssTemp = np.where( (srcArray == srcNoDataValue) | ((srcArray <= valueRange[0]) & (srcArray >= valueRange[1])) | (slopeArray >= slopeThreshold), 0, 255) aspectBand.WriteArray(aspectTemp, colstep * 1024, rowstep * 1024) resultBand.WriteArray(ssTemp, colstep * 1024, rowstep * 1024) gdal.SieveFilter(srcBand=aspectBand, maskBand=None, dstBand=aspectBand, threshold=(512)) for rowstep in range(rowblockNum): for colstep in range(colblockNum): rowpafNum = 1024 colpafNum = 1024 if (rowstep == rowblockNum - 1): rowpafNum = int((rowNum - 1) % 1024) + 1 if (colstep == colblockNum - 1): colpafNum = int((columnNum - 1) % 1024) + 1 resultArray = resultBand.ReadAsArray(colstep * 1024, rowstep * 1024, colpafNum, rowpafNum) aspectArray = aspectBand.ReadAsArray(colstep * 1024, rowstep * 1024, colpafNum, rowpafNum) resultTemp = np.where(aspectArray == 0, 0, resultArray) resultBand.WriteArray(resultTemp, colstep * 1024, rowstep * 1024) dstLayername = "POLYGONIZED" drv = ogr.GetDriverByName("ESRI Shapefile") dst_ds = drv.CreateDataSource(resultShpname) dst_layer = dst_ds.CreateLayer(dstLayername, srs=None) fd = ogr.FieldDefn("Status", ogr.OFTInteger) dst_layer.CreateField(fd) dst_field = dst_layer.FindFieldIndex("Status", 1) gdal.Polygonize(resultBand, None, dst_layer, dst_field, [], callback=None) dst_ds = None demSrcDS = None demResultDS = None demSlopeDS = None demAspectDS = None return (dstFilename, srcFilename, demFileNum, resultFilename)
def sieve(srcband,dstband,sieveSize): gdal.SieveFilter(srcband,None,dstband,SIZE_HA,INPUT_CONNECTIVITY)
if (colstep == colblockNum - 1): colpafNum = int((columnNum - 1) % 4096) + 1 maskArray = np.ones((rowpafNum, colpafNum)) * 255 for i in range(domSrcDS.RasterCount): band = domSrcDS.GetRasterBand(i + 1) tempArray = band.ReadAsArray(colstep * 4096, rowstep * 4096, colpafNum, rowpafNum) maskArray = np.where( (maskArray == 0) | ((tempArray <= valueRange + valueDist) & (tempArray >= valueRange - valueDist)), 0, 255) band = None maskBand.WriteArray(maskArray, colstep * 4096, rowstep * 4096) gdal.SieveFilter(srcBand=maskBand, maskBand=None, dstBand=maskBand, threshold=1000) maskDS = None maskDS = gdal.Open(r'E:\20180401中文\data\dataLab\mask.img', gdal.GA_Update) maskBand = maskDS.GetRasterBand(1) for rowstep in range(rowblockNum): for colstep in range(colblockNum): rowpafNum = 4096 colpafNum = 4096 if (rowstep == rowblockNum - 1): rowpafNum = int((rowNum - 1) % 4096) + 1 if (colstep == colblockNum - 1): colpafNum = int((columnNum - 1) % 4096) + 1 maskarray = maskBand.ReadAsArray(colstep * 4096, rowstep * 4096, colpafNum, rowpafNum)
(rowpafNum, colpafNum), dtype=np.int8 ) # np.ones(rowpafNum, colpafNum) * 255 # mskBand.ReadAsArray(colstep * 2048, rowstep * 2048, colpafNum, rowpafNum) for i in range(domSrcDS.RasterCount): band = domSrcDS.GetRasterBand(i + 1) domSrcNoData = band.GetNoDataValue() tempArray = band.ReadAsArray(colstep * 2048, rowstep * 2048, colpafNum, rowpafNum) mskArray = np.where( (mskArray == 0) & (((tempArray <= kwargs['colors'] + kwargs['nearDist']) & (tempArray >= kwargs['colors'] - kwargs['nearDist'])) | (tempArray == domSrcNoData)), 0, 255) band = None mskBand.WriteArray(mskArray, colstep * 2048, rowstep * 2048) gdal.SieveFilter(srcBand=mskBand, maskBand=None, dstBand=mskBand, threshold=(1024)) # if delNum != 0: unit = abs(GeoTransform[5]) mskLessDS = driver.Create(dstFilename.replace('.img', '_N.img'), domSrcDS.RasterXSize, domSrcDS.RasterYSize, 1, gdal.GDT_Byte, options=['COMPRESS=RLE']) mskLessDS.SetGeoTransform(GeoTransform) mskLessDS.SetProjection(Projection) # mskLessBand = mskLessDS.GetRasterBand(1)
# make a patch raster file from years patchMaskFile = os.path.join(vectorDirFull, 'patches.tif') shutil.copyfile(yodFile, patchMaskFile) print(' sieving to minimum mapping unit...') srcPatches = gdal.Open(patchMaskFile, gdal.GA_Update) nBands = srcPatches.RasterCount for band in range(1,nBands+1): srcBand = srcPatches.GetRasterBand(band) dstBand = srcBand maskBand = None # will also fill gaps that less than threshold gdal.SieveFilter(srcBand, maskBand, dstBand, threshold=mmu, connectedness=connectedness) srcPatches = None # make polygons print(' making polygons from disturbance pixel patches...') # read in the patch raster srcPatches = gdal.Open(patchMaskFile, gdal.GA_ReadOnly) # make a srs definition from patch raster file srs = osr.SpatialReference() srs.ImportFromWkt(srcPatches.GetProjectionRef())
def calculate(self, filename): def setMetadata(ds): def getMetadataSR(): sr = osr.SpatialReference() sr.ImportFromWkt(ds.GetProjectionRef()) is_geographic = False unit_sr = None if sr.IsGeographic(): is_geographic = True epsg = sr.GetAuthorityCode('GEOGCS') unit_sr = sr.GetAngularUnitsName() elif sr.IsProjected(): epsg = sr.GetAuthorityCode('PROJCS') unit_sr = sr.GetLinearUnitsName() else: epsg = None return { 'crs': { 'is_geographic': is_geographic, 'epsg': epsg, 'unit_sr': unit_sr }, 'sr': sr, 'wkt_sr': sr.ExportToWkt() } def getStrTypeBands(): strTypes = [] for id in xrange(ds.RasterCount): band = ds.GetRasterBand(id + 1) strType = "B%d(%s)" % (id + 1, gdal.GetDataTypeName(band.DataType)) strTypes.append(strType) return ",".join(strTypes) coefs = ds.GetGeoTransform() raster_size = { 'x': ds.RasterXSize, 'y': ds.RasterYSize, 'resX': coefs[1], 'resY': -1 * coefs[5] } self.metadata = { 'raster_size': raster_size, 'drive': ds.GetDriver().GetDescription(), 'bands': { 'number': ds.RasterCount, 'types': getStrTypeBands() }, 'transform': coefs, } self.metadata.update(getMetadataSR()) def getDatasetMem(datatype): ds = None try: ds = drv_mem.Create('', self.metadata['raster_size']['x'], self.metadata['raster_size']['y'], 1, datatype) except RuntimeError: return None ds.SetProjection(self.metadata['wkt_sr']) ds.SetGeoTransform(self.metadata['transform']) return ds def populateMask(datatype_mask): xoff, xsize, ysize = 0, self.metadata['raster_size']['x'], 1 format_struct_img = self.gdal_sctruct_types[ self.metadata['type_band1']] * xsize * ysize format_struct__mask = self.gdal_sctruct_types[ datatype_mask] * xsize * ysize value_new = [] for row in xrange(self.metadata['raster_size']['y']): line = band_img.ReadRaster(xoff, row, xsize, ysize, xsize, ysize, self.metadata['type_band1']) value = list(struct.unpack(format_struct_img, line)) del line for index, item in enumerate(value): value[index] = int(value[index] != 0) line = struct.pack(format_struct__mask, *value) del value band_mask.WriteRaster(xoff, row, xsize, ysize, line) del line if self.isKilled: break def getGeomsSieve(): srs = osr.SpatialReference() srs.ImportFromWkt(self.metadata['wkt_sr']) drv_poly = ogr.GetDriverByName('MEMORY') ds_poly = drv_poly.CreateDataSource('memData') layer_poly = ds_poly.CreateLayer('memLayer', srs, ogr.wkbPolygon) field = ogr.FieldDefn("dn", ogr.OFTInteger) layer_poly.CreateField(field) idField = 0 try: gdal.Polygonize(band_sieve, None, layer_poly, idField, [], callback=None) except RuntimeError: return {'isOk': False, 'msg': gdal.GetLastErrorMsg()} geoms = [] layer_poly.SetAttributeFilter("dn = 1") for feat in layer_poly: geoms.append(feat.GetGeometryRef().Clone()) ds_poly = layer_poly = None return {'isOk': True, 'geoms': geoms} def addArea(geom): area = None area_img = None typeFootprint = "Valid pixeis" if self.hasValidPixels else "Bounding box" if not self.metadata['crs']['is_geographic']: area = geom.GetArea() area_img = {'is_calculate': True, 'ha': area / 10000} else: if not self.srsTransform is None: geom_c = geom.Clone() geom_c.AssignSpatialReference(self.metadata['sr']) geom_c.TransformTo(self.srsTransform) area = geom_c.GetArea() geom_c.Destroy() area_img = { 'is_calculate': True, 'ha': area / 10000, 'crs_description': self.crsDescripTransform } else: area_img = {'is_calculate': False} area_img['type'] = typeFootprint self.metadata.update({'area': area_img}) def addGeom(geom): num_parts = geom.GetGeometryCount() num_holes = 0 for i in xrange(num_parts): poly = geom.GetGeometryRef(i) num_rings = poly.GetGeometryCount() if num_rings > 1: num_holes += num_rings - 1 value = {'num_parts': num_parts, 'num_holes': num_holes} self.metadata.update({'geometry': value}) tol = (self.metadata['raster_size']['resX'] + self.metadata['raster_size']['resY']) / 2.0 tol *= self.factorTolerance wkt_geom = geom.SimplifyPreserveTopology(tol).ExportToWkt() self.metadata.update({'wkt_geom': wkt_geom}) def getBoundBox(): def getXY(col, line): x = coefs[0] + col * coefs[1] + line * coefs[2] y = coefs[3] + col * coefs[4] + line * coefs[5] return {'x': x, 'y': y} coefs = self.metadata['transform'] p1 = getXY(0, 0) p2 = getXY(self.metadata['raster_size']['x'], self.metadata['raster_size']['y']) geom = ogr.Geometry(ogr.wkbMultiPolygon) ring = ogr.Geometry(ogr.wkbLinearRing) ring.AddPoint(p1['x'], p1['y']) ring.AddPoint(p2['x'], p1['y']) ring.AddPoint(p2['x'], p2['y']) ring.AddPoint(p1['x'], p2['y']) ring.AddPoint(p1['x'], p1['y']) poly = ogr.Geometry(ogr.wkbPolygon) poly.AddGeometry(ring) geom.AddGeometry(poly) return geom ds_img = gdal.Open(filename, GA_ReadOnly) self.metadata.clear() setMetadata(ds_img) if not self.hasValidPixels: geom = getBoundBox() ds_img = None addArea(geom) addGeom(geom) geom.Destroy() del self.metadata['transform'] del self.metadata['sr'] return True if self.isKilled: return False band_img = ds_img.GetRasterBand(self.metadata['bands']['number']) self.metadata.update({'type_band1': band_img.DataType}) if not self.metadata['type_band1'] in self.gdal_sctruct_types.keys(): ds_img = None self.msgError = "Type of image not supported" return False drv_mem = gdal.GetDriverByName('MEM') datatype_out = gdal.GDT_Byte if self.isKilled: return False # Mask ds_mask = getDatasetMem(datatype_out) if ds_mask is None: self.msgError = "Error for create 'mask' image in memory" return False band_mask = ds_mask.GetRasterBand(1) populateMask(datatype_out) ds_img = band_img = None if self.isKilled: return False # Sieve pSieve = {'threshold': 100, 'connectedness': 8} ds_sieve = getDatasetMem(datatype_out) if ds_sieve is None: self.msgError = "Error for create memory 'sieve' image in memory" ds_mask = None return False if self.isKilled: ds_sieve = None return False band_sieve = ds_sieve.GetRasterBand(1) try: gdal.SieveFilter(band_mask, None, band_sieve, pSieve['threshold'], pSieve['connectedness'], [], callback=None) except RuntimeError: self.msgError = gdal.GetLastErrorMsg() ds_mask = band_mask = None return False ds_mask = band_mask = None if self.isKilled: ds_sieve = band_sieve = None return False # Geoms vreturn = getGeomsSieve() ds_sieve = band_sieve = None if not vreturn['isOk']: self.msgError = vreturn['msg'] return False geomsSieve = vreturn['geoms'] numGeoms = len(geomsSieve) if numGeoms == 0: self.msgError = "Not exist geometry from image" return False if self.isKilled: for id in xrange(numGeoms): geomsSieve[id].Destroy() del geomsSieve[:] return False geomUnion = ogr.Geometry(ogr.wkbMultiPolygon) for id in xrange(numGeoms): geomUnion.AddGeometry(geomsSieve[id]) geomsSieve[id].Destroy() del geomsSieve[:] if self.isKilled: geomUnion.Destroy() return False geom = geomUnion.UnionCascaded() geomUnion.Destroy() addArea(geom) addGeom(geom) geom.Destroy() del self.metadata['transform'] del self.metadata['type_band1'] del self.metadata['sr'] return True
def getGeom_NumParts(self): def getDatasetMem(datatype): ds = drv_mem.Create('', infoimage['xsize'], infoimage['ysize'], 1, datatype) ds.SetProjection(infoimage['wktSRS']) ds.SetGeoTransform(infoimage['transform']) return ds def populateMask_origin(datatype_mask): xoff, xsize, ysize = 0, infoimage['xsize'], 1 format_struct_img = self.gdal_sctruct_types[ infoimage['datatype']] * xsize * ysize format_struct__mask = self.gdal_sctruct_types[ datatype_mask] * xsize * ysize for row in xrange(infoimage['ysize']): line = band_img.ReadRaster(xoff, row, xsize, ysize, xsize, ysize, infoimage['datatype']) value = list(struct.unpack(format_struct_img, line)) del line for col in xrange(infoimage['xsize']): value[col] = int(value[col] != 0) line = struct.pack(format_struct__mask, *value) del value band_mask.WriteRaster(xoff, row, xsize, ysize, line) del line def populateMask1(datatype_mask): xoff, xsize, ysize = 0, infoimage['xsize'], 1 format_struct_img = self.gdal_sctruct_types[ infoimage['datatype']] * xsize * ysize format_struct__mask = self.gdal_sctruct_types[ datatype_mask] * xsize * ysize for row in xrange(infoimage['ysize']): line = band_img.ReadRaster(xoff, row, xsize, ysize, xsize, ysize, infoimage['datatype']) value = list(struct.unpack(format_struct_img, line)) del line for col in xrange(infoimage['xsize']): value[col] = int(value[col] != 0) line = struct.pack(format_struct__mask, *value) del value band_mask.WriteRaster(xoff, row, xsize, ysize, line) del line def populateMask2(datatype_mask): xoff, xsize, ysize = 0, infoimage['xsize'], 1 format_struct_img = self.gdal_sctruct_types[ infoimage['datatype']] * xsize * ysize format_struct__mask = self.gdal_sctruct_types[ datatype_mask] * xsize * ysize value_new = [] for row in xrange(infoimage['ysize']): line = band_img.ReadRaster(xoff, row, xsize, ysize, xsize, ysize, infoimage['datatype']) value = list(struct.unpack(format_struct_img, line)) del line for index, item in enumerate(value): value[index] = int(value[index] != 0) line = struct.pack(format_struct__mask, *value) del value band_mask.WriteRaster(xoff, row, xsize, ysize, line) del line def getGeomsSieve(): srs = osr.SpatialReference() srs.ImportFromWkt(infoimage['wktSRS']) drv_poly = ogr.GetDriverByName('MEMORY') ds_poly = drv_poly.CreateDataSource('memData') layer_poly = ds_poly.CreateLayer('memLayer', srs, ogr.wkbPolygon) field = ogr.FieldDefn("dn", ogr.OFTInteger) layer_poly.CreateField(field) idField = 0 gdal.Polygonize(band_sieve, None, layer_poly, idField, [], callback=None) if gdal.GetLastErrorType() != 0: return {'isOk': False, 'msg': gdal.GetLastErrorMsg()} geoms = [] layer_poly.SetAttributeFilter("dn = 1") for feat in layer_poly: geoms.append(feat.GetGeometryRef().Clone()) ds_poly = layer_poly = None return {'isOk': True, 'geoms': geoms} ds_img = gdal.Open(self.filename, GA_ReadOnly) band_img = ds_img.GetRasterBand(1) infoimage = { 'datatype': band_img.DataType, 'wktSRS': ds_img.GetProjection(), 'transform': ds_img.GetGeoTransform(), 'xsize': ds_img.RasterXSize, 'ysize': ds_img.RasterYSize } if not infoimage['datatype'] in self.gdal_sctruct_types.keys(): ds_img = None return {'isOk': False, 'msg': "Type of image not supported"} drv_mem = gdal.GetDriverByName('MEM') datatype_out = gdal.GDT_Byte # Mask ds_mask = getDatasetMem(datatype_out) band_mask = ds_mask.GetRasterBand(1) populateMask2(datatype_out) ds_img = band_img = None # Sieve pSieve = {'threshold': 100, 'connectedness': 8} ds_sieve = getDatasetMem(datatype_out) band_sieve = ds_sieve.GetRasterBand(1) gdal.SieveFilter(band_mask, None, band_sieve, pSieve['threshold'], pSieve['connectedness'], [], callback=None) ds_mask = band_mask = None if gdal.GetLastErrorType() != 0: return {'isOk': False, 'msg': gdal.GetLastErrorMsg()} # Geoms vreturn = getGeomsSieve() ds_sieve = band_sieve = None if not vreturn['isOk']: return {'isOk': False, 'msg': vreturn['msg']} geomsSieve = vreturn['geoms'] numGeoms = len(geomsSieve) if numGeoms == 0: return { 'isOk': False, 'msg': "Not exist geometry from image '%s'" % self.filename } geomUnion = ogr.Geometry(ogr.wkbMultiPolygon) for id in xrange(numGeoms): geomUnion.AddGeometry(geomsSieve[id]) return { 'isOk': True, 'geom': geomUnion.UnionCascaded(), 'numparts': numGeoms, 'wktSRS': infoimage['wktSRS'] }
def polygonizeSelectionBand(ds_Select, band_Select, paramsTransform, wktProj): def setGeomAzimuthTolerance(geom, threshold): def changeRing(ring): def azimuth(p1, p2): dx = p2[0] - p1[0] dy = p2[1] - p1[1] az = math.atan2(dx, dy) * 180.0 / math.pi return az if ring.GetPointCount() < 4: return points = ring.GetPoints() ids_new = [0] upperIdPoints = len(points) - 1 for i in range(1, upperIdPoints): aznew = azimuth(points[ids_new[-1]], points[i]) az = azimuth(points[i], points[i + 1]) if abs(az - aznew) > threshold: ids_new.append(i) ids_new.append(upperIdPoints) if len(ids_new) < len(points): ids_remove = list( set(range(len(points))) - set(ids_new)) ids_remove.sort() ids_remove.reverse() for i in range(len(ids_remove)): del points[ids_remove[i]] ring.Empty() for i in range(len(points)): ring.SetPoint_2D(i, points[i][0], points[i][1]) numPolygons = geom.GetGeometryCount() for id1 in range(numPolygons): polygon = geom.GetGeometryRef(id1) numRings = polygon.GetGeometryCount() if numRings == 0: changeRing(polygon) # Only Out ring! else: for id2 in range(numRings): ring = polygon.GetGeometryRef(id2) changeRing(ring) # Sieve Band drvMem = gdal.GetDriverByName('MEM') ds_sieve = drvMem.Create('', ds_Select.RasterXSize, ds_Select.RasterYSize, 1, band_Select.DataType) ds_sieve.SetGeoTransform(paramsTransform) band_sieve = ds_sieve.GetRasterBand(1) p_threshold = self.paramsProcess['sieve']['threshold'] p_connectedness = self.paramsProcess['sieve']['connectedness'] gdal.SieveFilter(band_Select, None, band_sieve, p_threshold, p_connectedness, [], callback=None) if gdal.GetLastErrorType() != 0: return {'isOk': False, 'message': gdal.GetLastErrorMsg()} # Memory layer - Polygonize srs = osr.SpatialReference() srs.ImportFromWkt(wktProj) drv_poly = ogr.GetDriverByName('MEMORY') ds_poly = drv_poly.CreateDataSource('memData') layer_poly = ds_poly.CreateLayer('memLayer', srs, ogr.wkbPolygon) field = ogr.FieldDefn("dn", ogr.OFTInteger) layer_poly.CreateField(field) idField = 0 gdal.Polygonize(band_sieve, None, layer_poly, idField, [], callback=None) ds_sieve = band_sieve = None if gdal.GetLastErrorType() != 0: ds_poly, layer_poly = None, None return {'isOk': False, 'message': gdal.GetLastErrorMsg()} # Get Geoms - Apply Azimuth tolerance geoms = [] layer_poly.SetAttributeFilter("dn = 255") p_threshold = self.paramsProcess['azimuth']['threshold'] if p_threshold > 0: p_threshold = float(p_threshold) for feat in layer_poly: geom = feat.GetGeometryRef() setGeomAzimuthTolerance(geom, p_threshold) geoms.append(geom.Clone()) else: for feat in layer_poly: geoms.append(feat.GetGeometryRef().Clone()) ds_poly, layer_poly = None, None return {'isOk': True, 'geoms': geoms}
def otsu(image_array_loss1, image_array_loss2, H, W, geo, proj, path_results, images_date, threshold=0.995, changes=None, mask=None): image_array_loss = np.divide((image_array_loss1 + image_array_loss2), 2) max_ = np.max(image_array_loss) coef = max_ / 256 image_array_loss = image_array_loss / coef image_array_loss = np.asarray(image_array_loss, dtype=int) if mask is not None: val = filters.threshold_otsu( np.sort( image_array_loss.flatten()[mask])[0:int(len(mask) * threshold)]) else: val = filters.threshold_otsu( np.sort(image_array_loss.flatten())[0:int(H * W * threshold)]) image_array_outliers = np.zeros(H * W) image_array_outliers[image_array_loss.flatten() > val] = 1 if mask is not None: defected_mask = np.setdiff1d(np.arange(H * W), mask) image_array_outliers[defected_mask] = 0 outliers_image_mean = "Outliers_average_" + images_date + "_" + str( threshold) dst_ds = create_tiff(1, path_results + "/" + outliers_image_mean + ".TIF", W, H, gdal.GDT_Byte, np.reshape(image_array_outliers, (H, W)), geo, proj) gdal.SieveFilter(dst_ds.GetRasterBand(1), None, dst_ds.GetRasterBand(1), 5, 4) dst_ds.FlushCache() vectorize_tiff(path_results, "/" + outliers_image_mean, dst_ds) dst_ds = None if changes is not None: if changes in ["changes_2004_2005", "changes_2006_2008"]: path_cm = 'C:/Users/Ekaterina_the_Great/Dropbox/IJCNN/images/' + changes path_cm = '/home/user/Dropbox/IJCNN/images/' + changes path_cm = "/media/user/DATA/Results/RESULTS_CHANGE_DETECTION/GT_Montpellier/" + changes cm_truth_name = "mask_changes_small1" print(image_array_outliers.shape) if changes == "changes_2004_2005": cm_predicted = (np.reshape(image_array_outliers, (H, W))[0:600, 600:1400]).flatten() if changes == "changes_2006_2008": cm_predicted = (np.reshape(image_array_outliers, (H, W))[100:370, 1000:1320]).flatten() else: if changes in [ "changes_Rostov_20150830_20150919", "changes_Rostov_20170918_20180111" ]: print("hello") path_cm = "/media/user/DATA/Results/RESULTS_CHANGE_DETECTION/GT_Rostov/" cm_truth_name = changes + "_1" if changes == "changes_Rostov_20150830_20150919": print(image_array_outliers.shape) print(np.reshape(image_array_outliers, (H, W)).shape) cm_predicted = (np.reshape(image_array_outliers, (H, W))[0:700, 0:900]).flatten() # cm_predicted = np.asarray(np.reshape(image_array_outliers, (H, W))[0:700, 0:900]).flatten() if changes == "changes_Rostov_20170918_20180111": cm_predicted = (np.reshape(image_array_outliers, (H, W))[2100:2400, 900:1400]).flatten() cm_predicted[cm_predicted == 0] = 0 cm_predicted[cm_predicted == 1] = 1 print(cm_predicted.shape) cm_truth, _, _, _, _, _ = open_tiff(path_cm, cm_truth_name) cm_truth = cm_truth.flatten() cm_truth[cm_truth == 0] = 0 cm_truth[cm_truth == 1] = 1 print(cm_truth.shape) cm_truth[cm_truth == 255] = 0 print( classification_report(cm_truth, cm_predicted, target_names=["no changes", "changes"])) print(accuracy_score(cm_truth, cm_predicted)) print(cohen_kappa_score(cm_truth, cm_predicted)) conf = confusion_matrix(cm_truth, cm_predicted) print(confusion_matrix(cm_truth, cm_predicted)) omission = conf[1][0] / sum(conf[1]) print(omission)
def sieve(srcband, dstband, sieveSize): gdal.SieveFilter(srcband, None, dstband, sieveSize)
def setGeometryValidPixels(info): def setError(message): info['geom'] = {'value': None, 'message': message} info['area'] = {'value': None, 'auth': authArea} self.countErrorInfoGeom += 1 def getDataSetRasterMemory(dsIn): drv_mem = gdal.GetDriverByName('MEM') ds = drv_mem.Create('', dsIn.RasterXSize, dsIn.RasterYSize, 1, gdal.GDT_Byte) if ds is None: msg = QCoreApplication.translate( 'Footprint', 'Error create Raster memory') return {'isOk': False, 'message': msg} ds.SetGeoTransform(dsIn.GetGeoTransform()) ds.SetProjection(dsIn.GetProjection()) return {'isOk': True, 'ds': ds} def getDataSetBandMaskMemory(dsIn): def writeValidPixels(band): nodata = info['nodata'] if not info[ 'nodata'] is None else paramsValidPixels['nodata'] arryBand = np.array(dsIn.GetRasterBand(1).ReadAsArray()) arryValid = arryBand != nodata del arryBand band.WriteArray(arryValid) del arryValid band.SetNoDataValue(0) r = getDataSetRasterMemory(dsIn) if not r['isOk']: return r dsMask = r['ds'] bandMask = dsMask.GetRasterBand(1) writeValidPixels(bandMask) return {'isOk': True, 'ds': dsMask, 'band': bandMask} def getDataSetLayerPolygonMaskMemory(wktSrs): srs = osr.SpatialReference() srs.ImportFromWkt(wktSrs) driver = ogr.GetDriverByName('MEMORY') ds = driver.CreateDataSource('memData') if ds is None: msg = QCoreApplication.translate( 'Footprint', 'Error create Polygon layer memory') return {'isOk': False, 'message': msg} layer = ds.CreateLayer('memLayer', srs, ogr.wkbPolygon) field = ogr.FieldDefn("dn", ogr.OFTInteger) layer.CreateField(field) return {'isOk': True, 'ds': ds, 'layer': layer} try: ds = gdal.Open(info['pathfile'], gdal.GA_ReadOnly) except RuntimeError as error: setError(str(error)) return # Mask r = getDataSetBandMaskMemory(ds) if not r['isOk']: setError(r['message']) return dsMask, bandMask = r['ds'], r['band'] ds = None # Sieve r = getDataSetRasterMemory(dsMask) if not r['isOk']: setError(r['message']) return dsSieve = r['ds'] bandSieve = dsSieve.GetRasterBand(1) threshold, connectedness = 100, 8 try: gdal.SieveFilter(bandMask, None, bandSieve, threshold, connectedness, [], callback=None) except RuntimeError as error: setError(str(error)) return dsMask, bandMask = None, None # Polygonize r = getDataSetLayerPolygonMaskMemory(dsSieve.GetProjection()) if not r['isOk']: setError(r['message']) return dsPolygonMask, layerMask = r['ds'], r['layer'] idField = 0 try: gdal.Polygonize(bandSieve, None, layerMask, idField, [], callback=None) except RuntimeError as error: setError(str(error)) return dsSieve, bandSieve = None, None # Geometry geomsOGR = [] layerMask.SetAttributeFilter("dn = 1") for feat in layerMask: outerRing = feat.GetGeometryRef().GetGeometryRef(0) poly = ogr.Geometry(ogr.wkbPolygon) poly.AddGeometry(outerRing) geomsOGR.append(poly) dsPolygonMask, layerMask = None, None # Union Geos geomUnion = ogr.Geometry(ogr.wkbMultiPolygon) for idx in range(len(geomsOGR)): geomUnion.AddGeometry(geomsOGR[idx]) del geomsOGR[idx] del geomsOGR[:] geomOGR = geomUnion.UnionCascaded() del geomUnion # set Info del info['bbox_wkt'] geom = QgsGeometry.fromWkt(geomOGR.ExportToWkt()) setInfoArea(info, geom) tolerance_unit = paramsValidPixels['tolerance_pixels'] * info[ 'sizes']['pixel']['resolutionX'] geom_s = geom.simplify(tolerance_unit) setInfoGeometry(info, geom_s)
def sieve_raster(infile, threshold, connectedness=4, outfile=None, mask=None, frmt="GTiff", silence=True): """ Removes raster polygons smaller than a provided threshold size (in pixels) and replaces them with the pixel value of the largest neighbour polygon. The result can be written back to the existing raster band, or copied into a new file. ###NOTE: Polygons smaller than the threshold with no neighbours that are as large as the threshold will not be altered. Polygons surrounded by nodata areas will therefore not be altered.#### The input dataset is read as integer data which means that floating point values are rounded to integers. Re-scaling source data may be necessary in some cases (e.g. 32-bit floating point data with min=0 and max=1). The algorithm makes three passes over the input file to enumerate the polygons and collect limited information about them. Memory use is proportional to the number of polygons (roughly 24 bytes per polygon), but is not directly related to the size of the raster. So very large raster files can be processed effectively if there aren't too many polygons. But extremely noisy rasters with many one pixel polygons will end up being expensive (in memory) to process. More info: http://www.gdal.org/gdal__alg_8h.html#a33309c0a316b223bd33ae5753cc7f616 http://www.gdal.org/gdal_sieve.html :param infile: path to input file :param threshold: size threshold in pixels. Only raster polygons smaller than this size will be removed. :param connectedness: 4 Four connectedness should be used when determining polygons. That is diagonal pixels are not considered directly connected. This is the default. 8 Eight connectedness should be used when determining polygons. That is diagonal pixels are considered directly connected :param outfile: path to output file, pass None to change the input in place :param mask: an optional path to a mask band. All pixels in the mask band with a value other than zero will be considered suitable for inclusion in polygons. Pass "default" to use a mask included in the input file :param frmt: the output format, default "GTiff" :param silence: pass any value to enable debug info :return: None """ if connectedness != 4: connectedness = 8 src_ds = None dst_ds = None mask_ds = None try: #open source file and mask if not outfile: src_ds = gdal.Open(infile, gdal.GA_Update) else: src_ds = gdal.Open(infile, gdal.GA_ReadOnly) srcband = src_ds.GetRasterBand(1) if mask: if mask is 'default': maskband = srcband.GetMaskBand() else: mask_ds = gdal.Open(mask) maskband = mask_ds.GetRasterBand(1) else: maskband = None # define the output, copy properties from the input if outfile: drv = gdal.GetDriverByName(frmt) dst_ds = drv.Create(outfile, src_ds.RasterXSize, src_ds.RasterYSize, 1, srcband.DataType) wkt = src_ds.GetProjection() if wkt != '': dst_ds.SetProjection(wkt) dst_ds.SetGeoTransform(src_ds.GetGeoTransform()) dstband = dst_ds.GetRasterBand(1) # set the nodata value dstband.SetNoDataValue(srcband.GetNoDataValue()) else: dstband = srcband if silence: prog_func = None else: prog_func = gdal.TermProgress gdal.SieveFilter(srcband, maskband, dstband, threshold, connectedness, callback=prog_func) except: if src_ds: src_ds = None if dst_ds: dst_ds = None if mask_ds: mask_ds = None