GEE: How to perform water/cloud masking on the MOD09GA dataset, calculate NDVI and export it to the cloud disk?

Table of contents

01 Why use GEE instead of the traditional download + ENVI + ArcGIS?

02 Detailed operation


01 Why use GEE instead of the traditional download + ENVI + ArcGIS?

Due to the lack of NDVI monthly synthetic images in October 2015 in the geospatial data cloud, some introductions to the processing of NDVI datasets in the geospatial data cloud are as follows (geospatial data cloud (gscloud.cn) ):

I planned to go to NASA to download it. I already got the download link, but after seeing 8 G, this is just a download. I also need to perform operations such as cropping and splicing, NDVI calculation and resampling, which are cumbersome, and in the end I just got it. It takes a month to synthesize NDVI images, and the time and energy are not directly proportional:

 So I plan to use the GEE platform to calculate and export NDVI.

02 Detailed operation

Dataset used: MOD09GA.061 Terra Surface Reflectance Daily Global 1km and 500m

In order to ensure the accuracy, cloud mask and water body mask are applied to the image.

First, a start date and an end date are defined:

// 定义日期范围
var start_date = '2015-10-01';
var end_date = '2015-10-31';

Next we define a water and cloud mask function:

// 定义云和水体掩膜函数
function maskCloudAndWater(image) {
  var QA = image.select('QC_500m');
  // 创建一个空的mask,初始值为1(即所有像素都不被掩膜覆盖)
  var mask = ee.Image.constant(1);
  
  // 遍历每个波段的数据质量标识
  for (var i = 0; i < 2; i++) {  // 因为我选取了两个波段进行ndvi的计算
    // 计算当前波段的数据质量标识的起始位(是从2开始)
    var startBit = 2 + i * 4;
    // 提取当前波段的数据质量标识
    var bandQuality = QA.rightShift(startBit).bitwiseAnd(15);
    // 如果数据质量标识为15,说明该像素可能被云或深海覆盖,需要被掩膜覆盖
    mask = mask.min(bandQuality.neq(15));  // min取两者间小的那个值,逐像元
  }
  
  // 应用掩膜
  return image.updateMask(mask);
}

The water body mask and cloud mask here are different from the general data set. The QC band here is marked with 4-bit binary numbers for each band image, so the mask is calculated for each band and then the All masks seek a similar OR operation.

The following is an introduction to the AC_500m band of the MOD09GA dataset (from GEE):

 

Here we mainly talk about the problem of binary masks.

In our function, QA is a 32-bit integer, that is to say, it is composed of 32 binary digits, and each band has a 4-bit data quality identifier, and these 4 bits are placed in one of QA Location. For example:

Let's take a simple example. For a certain pixel, its attribute (32-bit binary integer) value is:

0010 1100 1011 0011 0101 1001 0110 1011

(注意:空格是我为了方便阅读加上的)

In the above binary integer, each 4 bits represents the quality part of a band, then suppose we care about the leftmost part of 0010 (this is what we call the data quality part).

Then we can move it to the right (right shift operation) 28 bits to get:

0000 0000 0000 0000 0000 0000 0000 0010

接着我们就可以将其与掩膜值做比较,这里需要使用到位与操作:

The bitwise AND operation is to compare two binary numbers, and only when the two corresponding binary bits are 1, the corresponding bit of the result is 1, otherwise it is 0.

From the previous screenshots, we know that Bits2~5 represent the data quality part of the first band, and the mask value of 15 (decimal) represents deep sea or clouds.

And we know that the conversion of 15 in decimal to 32-bit binary is:

0000 0000 0000 0000 0000 0000 0000 1111

因此二者进行位与操作之后为:

0000 0000 0000 0000 0000 0000 0000 0010

Its conversion into decimal is not equal to 15, indicating that the pixel position is not deep sea or cloud layer.


The other code parts are not explained one by one due to time reasons, and the complete code is posted here:

// 定义日期范围
var start_date = '2015-10-01';
var end_date = '2015-10-31';

// 定义云和水体掩膜函数
function maskCloudAndWater(image) {
  var QA = image.select('QC_500m');
  // 创建一个空的mask,初始值为1(即所有像素都不被掩膜覆盖)
  var mask = ee.Image.constant(1);
  
  // 遍历每个波段的数据质量标识
  for (var i = 0; i < 2; i++) {  // 因为我选取了两个波段进行ndvi的计算
    // 计算当前波段的数据质量标识的起始位(是从2开始)
    var startBit = 2 + i * 4;
    // 提取当前波段的数据质量标识
    var bandQuality = QA.rightShift(startBit).bitwiseAnd(15);
    // 如果数据质量标识为15,说明该像素可能被云或深海覆盖,需要被掩膜覆盖
    mask = mask.min(bandQuality.neq(15));  // min取两者间小的那个值,逐像元
  }
  
  // 应用掩膜
  return image.updateMask(mask);
}

// 定义地理空间范围(四川省)
var geom = ee.FeatureCollection('projects/ee-chaoqiezione/assets/china_admin_province')
geom = geom.filter(ee.Filter.eq('省', '四川省'));
// 加载MODIS数据根据日期和地理范围进行筛选
var modis_ndvi = ee.ImageCollection('MODIS/006/MOD09GA')
  .filterDate(start_date, end_date)
  .filterBounds(geom)
  .select(['sur_refl_b02', 'sur_refl_b01', 'QC_500m'])
  .map(function (img) {
    img = maskCloudAndWater(img);  // 水体和云掩膜
    return img.normalizedDifference(['sur_refl_b02', 'sur_refl_b01']).rename('ndvi')  // 计算ndvi
  })
  .mean().clip(geom)

// 添加到地图上以便可视化
print(modis_ndvi)  // 命令面板输出简要信息
Map.addLayer(modis_ndvi.select('ndvi'), {min: 0, max: 1, palette: ['blue', 'white', 'green']}, 'MeanNDVI');
Map.centerObject(geom, 6)

// 导出至云盘
Export.image.toDrive({
  image: modis_ndvi.select('ndvi'),
  description: 'Mean_NDVI',
  region: geom,
  scale: 500,
  maxPixels: 1e13,
  fileFormat: 'GeoTIFF'})

Guess you like

Origin blog.csdn.net/m0_63001937/article/details/130670086