GEE呼叫Sentinel-2 MSI L2A資料集 示例程式碼解析筆記

IronRoc發表於2024-04-26

程式碼來源:https://developers.google.com/earth-engine/datasets/catalog/COPERNICUS_S2_SR_HARMONIZED#description

講解一下GEE示例

/**
 * Function to mask clouds using the Sentinel-2 QA band
 * @param {ee.Image} image Sentinel-2 image
 * @return {ee.Image} cloud masked Sentinel-2 image
 */
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);
}

var dataset = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')
                  .filterDate('2020-01-01', '2020-01-30')
                  // Pre-filter to get less cloudy granules.
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',10))
                  .map(maskS2clouds);

var visualization = {
  min: 0.0,
  max: 0.3,
  bands: ['B4', 'B3', 'B2'],
};

Map.setCenter(83.277, 17.7009, 12);

Map.addLayer(dataset.mean(), visualization, 'RGB');

QA60是Sentinel-2影像中的一種質量控制波段,用於記錄每個畫素點的質量資訊。具體來說,QA60波段記錄了每個畫素的60個質量控制位,每個位代表了一個特定的質量標誌,如雲、陰影、雪等。其中,第10位是雲,第11位是捲雲。

因此這段程式碼前半部分構造了一個 maskS2clouds() 的函式,根據對應位的數值構造掩膜。

var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
      .and(qa.bitwiseAnd(cirrusBitMask).eq(0));

這段程式碼表示,如果這個畫素沒受 影響,也沒受 捲雲 影響,那麼就為這個畫素構造掩膜

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

image.updateMask() 這個函式將image中所有mask值為1的畫素保留,然後又將每個畫素的DN值歸一化 (Sentinel-2 的DN值範圍:0-10000)

後續程式碼就是將對應時間內,雲量少於20%的影像進行掩膜處理,並平均的覆蓋地圖上的每一個位置。

如果想看不進行掩膜去雲處理的影像進行對比,可以執行以下程式碼:

/**
 * Function to mask clouds using the Sentinel-2 QA band
 * @param {ee.Image} image Sentinel-2 image
 * @return {ee.Image} cloud masked Sentinel-2 image
 */
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);
}

var dataset = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')
                  .filterDate('2020-01-01', '2020-01-30')
                  // Pre-filter to get less cloudy granules.
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',10)) //可以把“10”改大一點,更明顯
//                  .map(maskS2clouds);

var visualization = {
  min: 0,
  max: 10000,
  bands: ['B4', 'B3', 'B2'],
};

Map.setCenter(83.277, 17.7009, 12);

Map.addLayer(dataset.mean(), visualization, 'RGB');

相關文章