【GEE】基于GEE进行非监督学习

2023-11-21 09:53:26 浏览数 (2)

1 简介与摘要

之前写了多季节叠加的监督学习,所以这次简单写一个非监督学习吧。。 这次为了简单明了,就不整那么多虚的了,在这里我不叠图层了,有需要的可以参考前一篇博客自己添加输入的图层。

2 制作输入影像

首先,同样的我们需要制作一个自带n个图层(波段)的影像。 我们需要先根据我们所选的卫星数据先放一个云掩膜函数。本例中我使用的是sentinel2影像(10m分辨率),所以我先放一个他的云掩膜函数在上面:

代码语言:javascript复制
function maskS2clouds(image) {
  var qa = image.select('QA60');

  // Bits 10 and 11 are clouds and cirrus, respectively.
  var cloudBitMask = 1 << 10;
  var cirrusBitMask = 1 << 11;

  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
      .and(qa.bitwiseAnd(cirrusBitMask).eq(0));

  return image.updateMask(mask).divide(10000);
}

然后,我们开始筛选我们需要的影像。时间段是start到end之间(这个参数需要自填),筛选云量在20%以下的影像再进行云掩膜:

代码语言:javascript复制
var s2 = ee.ImageCollection('COPERNICUS/S2_SR');

var img = ee.Image(s2.filterBounds(roi)
                       .filterDate(start, end)
                       .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',20))
                       .map(maskS2clouds)
                       .mean()
                       .clip(roi));

然后开始选我们需要的波段,叠成一个新的影像。我写这个例子的时候懒得算指数了,如果要叠出花样了可以参考我上一篇博客计算各种指数叠波段的方法。下面我简单地把哨兵自带的1-9波段放进去:

代码语言:javascript复制
var image = img.select('B2');
var image = image.addBands([img.select('B3'), img.select('B4'), img.select('B5'),
                            img.select('B6'), img.select('B7'), img.select('B8'),
                            img.select('B9')
                            ]);

然后得到的这个image就是我们要扔进去非监督学习的输入影像了。

3 非监督学习

我们有了影像,我们要在影像的范围内生成采样点,这样机器才知道要自己学什么。范围是roi,尺度是scale(本例中为10),numpixels是生成的个数:

代码语言:javascript复制
// sampling
var training = image.sample({
  region: roi,
  scale: scale,
  numPixels: numpixels
});

采样完开始选择方法。方法选我比较喜欢的wekaKMeans,里面填的classes是期望划分的类别数,training是刚才采的样,result是非监督分类完的图:

代码语言:javascript复制
// select method
var clusterer = ee.Clusterer.wekaKMeans(classes).train(training);

var result = image.cluster(clusterer);

如果想要使用其他非监督分类方法可以在GEE代码界面左上角的docs检索,或者参考这篇博客:google earth engine(GEE)进行非监督分类

4 影像的显示与结果

最后我们用几行代码让结果显示在在地图上:

代码语言:javascript复制
Map.centerObject(roi, 11);
Map.addLayer(image.clip(roi), {bands: ["B4", "B3", "B2"], min:0, max:0.25}, "raw_img");
Map.addLayer(result.randomVisualizer(), {}, 'clusters')

下面是我用真彩色合成的影像:

下图是分类结果:

然后设置一下cluster这个图层,给他调一下色:

通过inspector我们可以查询cluster的值,然后和合成的真彩色进行对比,然后调色。比如我们点一下点发现原来深绿色这类是海冰,然后它在cluster的值是1,所以我们设置第二个色块palette为海冰的颜色(0是第一个色块,1是第二个,依此类推)(记得把上面range也调一下,比如我这里分五类那就是0-5):

上图0是积雪(白)、1是海冰(灰)、2是海洋(蓝)、3是植被(绿)、4是裸地(褐)。

5 本例完整代码

本例使用sentinel2影像,对2020年11月1日到2021年3月1日海参崴地区的影像进行合成与非监督分类(5类)。代码的参数写在最前面,可以根据需要自行调整。

代码语言:javascript复制
var classes = 5;
var scale = 10;
var numpixels = 5000;
var start = '2020-11-01'
var end = '2021-03-31'

function maskS2clouds(image) {
  var qa = image.select('QA60');

  // Bits 10 and 11 are clouds and cirrus, respectively.
  var cloudBitMask = 1 << 10;
  var cirrusBitMask = 1 << 11;

  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
      .and(qa.bitwiseAnd(cirrusBitMask).eq(0));

  return image.updateMask(mask).divide(10000);
}


// select images
var s2 = ee.ImageCollection('COPERNICUS/S2_SR');

var img = ee.Image(s2.filterBounds(roi)
                       .filterDate(start, end)
                       .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',20))
                       .map(maskS2clouds)
                       .mean()
                       .clip(roi));

var image = img.select('B2');
var image = image.addBands([img.select('B3'), img.select('B4'), img.select('B5'),
                            img.select('B6'), img.select('B7'), img.select('B8'),
                            img.select('B9')
                            ]);                          
                            
// sampling
var training = image.sample({
  region: roi,
  scale: scale,
  numPixels: numpixels
});



// select method
var clusterer = ee.Clusterer.wekaKMeans(classes).train(training);

var result = image.cluster(clusterer);



Map.centerObject(roi, 11);
Map.addLayer(image.clip(roi), {bands: ["B4", "B3", "B2"], min:0, max:0.25}, "raw_img");
Map.addLayer(result.randomVisualizer(), {}, 'clusters')

0 人点赞