GEE提取水体和植被(基于哨兵二号数据源)

这算是第一次用GEE进行实验分析。为了从稍微简单的地方入门,这里先选择提取水体和植被的实验,使用的方法也是最常见的NDWI指数和NDVI指数。

实验直接在GEE网页端的工作台上进行,所以使用的是JavaScript语法。如果要在python环境下运行,需要先配置环境,详见个人博客配置GEE谷歌地球引擎的Python环境(conda命令)_Deng__zy的博客-CSDN博客

实验范围是武汉地区,遥感数据源是哨兵二号2020年的影像数据。

首先做一些知识储备,这里提取水体使用的是NDWI指数, Normalized Difference Water Index,(归一化水指数),计算方法如下:

NDWI =(p(Green)-p(NIR))/(p(Green)+p(NIR))

对于哨兵二号数据源而言,带入相应波段,上述公式对应的是:

NDWI = (band3 - band8) / (band3 + band8)

这一点可以在哨兵二号的数据集介绍中查到:

GEE提取水体和植被(基于哨兵二号数据源)_第1张图片

现在我们理一理大致的思路:使用武汉市的矢量范围来划定相应的影像范围,然后对这些影像进行波段运算,进而得到NDWI指数的表现。接下来进行实验:

首先加载出武汉市的矢量范围和哨兵二号数据集(这里是直接加载的,所以没法复制代码):

GEE提取水体和植被(基于哨兵二号数据源)_第2张图片

使用如下代码查看范围:

var district = table;
var district_geometry = district.geometry();
Map.addLayer(table,{},"wuhan")

 可以查看武汉市矢量范围:

接下来选择合适的数据集。理论上来说使用的影像应当经过一些预处理(如去云)。这里为了简化操作,暂时先不进行这些预处理(其实我们使用的影像已经经过了一些基本的预处理,只是大部分情况下可能不太够)。

通过如下代码导入哨兵二号2020年的影像:

//处理数据,生成数据集
var image = ee.ImageCollection('COPERNICUS/S2')
                  .filterBounds(district_geometry)//区域筛选
                  .filterDate('2020-01-01', '2020-12-30')//时间范围
                  .mosaic()//镶嵌为一张影像

这里要注意的是,经过区域筛选得到的影像不止一张,如果只是单纯的将这些影像导出并赋给image变量,这时的image就包含了不止一张影像,这在后续的处理中会导致一些波段计算的函数无法使用,所以一定要使用mosaic进行镶嵌。

接下来计算ndwi指数,参照之前的公式,我们可以这样计算:

var NIR = image.select('B8')
var RED = image.select('B3')
var fenmu =NIR.add(RED)
var fenzi=NIR.subtract(RED)
var ndwi =fenzi.divide(fenmu)

 这相当是将ndwi指数的计算一步步做了拆解,其实GEE为我们提供了一个函数,可以一步完成上述的计算:

var ndwi = image.normalizedDifference(['B3', 'B8']);

现在我们完成了计算,需要将结果显示在图上,这时就需要设置显示模式:

var ndwiViz = {'min': -0.5, 'max': 0.5, 'palette': ['00FFFF', '0000FF']};

这里的参数设置不用一直记着,需要用的时候进行查阅即可。

最后我们使用展示函数:

Map.addLayer(ndwi, ndwiViz, 'NDWI');

得到的结果如下,这就是我们计算出的ndwi波段:

 

接下来设置水体掩膜,将计算出的ndwi指数阈值设为0.05,即保留ndwi大于0.05的区域:

var ndwiMasked = ndwi.updateMask(ndwi.gte(0.05));
Map.addLayer(ndwiMasked, ndwiViz, 'NDWI masked');

 加载在卫星影像上看到的效果如下:

同理计算NDVI(归一化植被指数),将波段计算调整为:

var ndvi = image.normalizedDifference(['B8', 'B4']);
var ndviViz = {'min': -0.2, 'max': 0.8, 'palette': ['FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901', '66A000', '529400',
   '3E8601', '207401', '056201', '004C00', '023B01', '012E01', '011D01', '011301']}
Map.addLayer(ndvi, {}, 'NDVI');
var ndviMasked = ndvi.updateMask(ndvi.gte(0.2));
Map.addLayer(ndviMasked, ndviViz, 'NDWI masked');

加载至卫星影像上效果如下:

其实我们还可以通过设置去云函数来筛选去除影像云层,之后再进行波段计算。具体函数如下:

function maskS2clouds(image) {
  var qa = image.select('QA60');
  
  // Bits 10和11分别是云和卷云
  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);
}

这样我们就可以将影像加载函数修改为:

var image = ee.ImageCollection('COPERNICUS/S2')
                  .filterBounds(district_geometry)//区域筛选
                  .filterDate('2020-01-01', '2020-12-30')//时间范围
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 1))
                  .map(maskS2clouds)
                  .mosaic()

以上只是进行了初步的实验探究,对其中参数的把握还很不到位,后面会进行改正。

你可能感兴趣的:(学习,经验分享)