google earth engine随缘学习(五)关于删除斑块平滑图像

今天整理一波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))
}
该方法先是矢量化,然后提取缓冲区,最后计算不同矢量斑块缓冲区内包含的其他地物面积的百分比ee.Reducer.frequencyHistogram(),把其作为一项属性赋予矢量斑块。其中,先是把缓冲区内不同矢量所占面积作为字典提取出来,然后转化为数组按照矢量的地物类型字段对面积求和,才真正求出来缓冲区内不同地物的总面积,并计算百分比,并作为属性赋予矢量,该方法考虑最周全,可以自由选择保留或删去各种地物包围斑块,但是缺点是太慢了。
PS:失恋了真的是丧啊!!

猜你喜欢

转载自blog.csdn.net/qq_21567935/article/details/85107842