今天整理一波GEE关于删除斑块平滑图像的代码
之前做填海造陆制图中,就要去除一些陆地里的水系,于是用了connectedPixelCount方法消除了小水体
今天整理学习了一下大神写的别的方法:
传送门———https://code.earthengine.google.com/7ddcdcd7ae307205062f3b8d84cf6fab
方法一:
var smooth_map = map_classification
.focal_mode({
radius: 10, kernelType: 'octagon', units: 'pixels', iterations: 1
})
.mask(map_classification.gte(1))
var crude_object_removal = map_classification
.updateMask(map_classification.connectedPixelCount(50, false).gte(50))
.unmask(smooth_map)
(注意这里map_classification是只有一个地物类别波段的分类图像)首先是利用滑动窗口求取众数来平滑图像,然后将小于50像素数斑块的地物类型用该处平滑后的地物类型替代,缺点是一刀切,许多小但重要的地物斑块会消失掉。
方法二(消除某一特定类的小斑块):
var smooth_map_15 = map_classification.mask(map_classification.neq(15))
.focal_mode({
radius: 20, kernelType: 'circle', units: 'pixels', iterations: 1
})
.mask(map_classification.gte(1))
var limit_size_15 = map_classification
.updateMask(map_classification.gt(0)
.subtract(map_classification.eq(15).selfMask()
.connectedPixelCount(300, false).lt(300).unmask(0)
) // clunky, sure there's a simpler way...
)
.unmask(smooth_map_15)
该代码是消除面积小于300像素数的15类地物斑块。先是对去掉15类地物的图像进行平滑,然后提取出15类地物小于300的部分然后掩膜掉,用平滑图像代替。
var smooth_map_14 = map_classification.mask(map_classification.neq(14))
.focal_mode({
radius: 20, kernelType: 'circle', units: 'pixels', iterations: 1
})
.mask(map_classification.gte(1))
var limit_size_14 = limit_size_15
.updateMask(map_classification.gt(0)
.subtract(map_classification.eq(14).selfMask()
.connectedPixelCount(300, false).lt(300).unmask(0)
) // clunky, sure there's a simpler way...
)
.unmask(smooth_map_14)
该代码是在消除面积小于300像素数的15类地物斑块基础上同方法消除14类地物斑块。
方法三(基于斑块边界相邻关系消除斑块):
var border_pixels = map_classification.reduceNeighborhood({
reducer: ee.Reducer.countDistinct(),
kernel: ee.Kernel.square(1)
})
var neighbour_pixels = map_classification.rename('classes').addBands(border_pixels)
.reduceConnectedComponents(ee.Reducer.max(), 'classes', 2000)
var border_compl_15 = map_classification
.updateMask(map_classification.gt(0)
.subtract(
map_classification.eq(15).and(neighbour_pixels.lte(3))
.unmask(0)
)
)
.unmask(smooth_map_15)
该代码先是计算栅格影像的边界栅格影像,比较像矢量,边界线段部分为2,表示两种地物相邻,边界端点部分可以是多种地物相邻,因此可以为2~4。然后将不同地物的斑块分成独立的对象,取其边界最大值也就是看这个斑块与其他几种地物相邻,最后消除只和另外2种或1种地物相邻的15类地物斑块(用光滑后图像代替)。
方法四(通过矢量化来判断某斑块百分之多少被某某斑块包围):
var map_fc = map_classification.reduceToVectors({
scale: 10,
eightConnected: false,
bestEffort: true,
maxPixels: 1e13,
tileScale: 1
})
print(map_fc.limit(50)) //只显示前50个元素信息
print(map_fc.size()) //返回元素数量
var set_neighbour_properties = function(f) {
var diff = f.buffer(10).difference(f, ee.ErrorMargin(0.5)) //提取缓冲区
var diff_classes = ee.Dictionary(
map_classification.unmask(ee.Image(0)).reduceRegion({
reducer: ee.Reducer.frequencyHistogram(),
geometry: diff.geometry(),
scale: 10
}).get('classification')
)
var diff_sum = diff_classes.toArray().reduce(ee.Reducer.sum(), [0]).get([0])
var diff_percs = diff_classes.map(function(k,v){return(ee.Number(v).divide(diff_sum).multiply(100))})
return(f.set(diff_percs))
}