NDVI、將函式對應至集合、品質鑲嵌

先前您已瞭解如何透過類似以下的操作取得個別 Landsat 場景,其中 l8 和 point 是代表 Landsat 8 TOA 集合和感興趣區域幾何圖形的匯入項目:

程式碼編輯器 (JavaScript)

// Define a point of interest. Use the UI Drawing Tools to import a point
// geometry and name it "point" or set the point coordinates with the
// ee.Geometry.Point() function as demonstrated here.
var point = ee.Geometry.Point([-122.292, 37.9018]);

// Import the Landsat 8 TOA image collection.
var l8 = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA');

// Get the least cloudy image in 2015.
var image = ee.Image(
  l8.filterBounds(point)
    .filterDate('2015-01-01', '2015-12-31')
    .sort('CLOUD_COVER')
    .first()
);

現在假設您想根據 Landsat 圖片,計算歸一化差值植生指數 (NDVI) 圖片。植被會反射電磁光譜中近紅外線 (NIR) 部分的光,並吸收紅色部分的光 (進一步瞭解植被的 NIR 反射率)。NDVI 會使用這個值建立單一值,大致反映像素發生的光合作用活動。計算公式為 (NIR - 紅色) / (NIR + 紅色)。這會產生介於 1 和 -1 之間的數字,其中光合作用活動高的像素具有高 NDVI。以下是在 Earth Engine 中計算 NDVI 的其中一種方法:

程式碼編輯器 (JavaScript)

// Compute the Normalized Difference Vegetation Index (NDVI).
var nir = image.select('B5');
var red = image.select('B4');
var ndvi = nir.subtract(red).divide(nir.add(red)).rename('NDVI');

// Display the result.
Map.centerObject(image, 9);
var ndviParams = {min: -1, max: 1, palette: ['blue', 'white', 'green']};
Map.addLayer(ndvi, ndviParams, 'NDVI image');

結果應如圖 8 所示。請注意,我們使用您在上一節遮罩中學到的 select() 函式,取得近紅外線和紅色波段,然後使用您在上一節 Image 數學中看過的圖片數學運算子,計算 NDVI。最後,使用調色盤顯示圖片。這裡我們在調色盤中使用顏色名稱,而非十六進位字串。(詳情請參閱這份關於 CSS 顏色的外部參考資料)。

Tutorial_api_08_ndvi.png
圖 8. 單一 Landsat 場景的 NDVI。藍色代表 NDVI 較低,綠色代表 NDVI 較高。

正規化差異運算在遙測中非常普遍,因此 ee.Image 有一個捷徑函式,可用於簡化前一個範例中的程式碼:

程式碼編輯器 (JavaScript)

var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');

將函式對應至集合

假設您現在想將 NDVI 新增至圖片集合中的「每張」圖片。在 Earth Engine 中,做法是對集合map()函式。請勿將 map() 與 Map 物件混淆。前者是集合的方法,並在平行運算中使用 map,將函式套用至集合中的每個元素。函式會定義要套用至集合中每個元素的作業。您已在 JavaScript 教學課程中看過簡單的函式,但現在我們要建立包含 Earth Engine 功能的函式。舉例來說,將先前的 NDVI 程式碼複製到函式中,該函式會傳回含有 NDVI 頻帶的輸入圖片:

程式碼編輯器 (JavaScript)

var addNDVI = function(image) {
  var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');
  return image.addBands(ndvi);
};

// Test the addNDVI function on a single image.
var ndvi = addNDVI(image).select('NDVI');

這段程式碼在計算單張圖片的 NDVI 時可能效率不高,但這個函式可做為 map() 的引數,以便為集合中的每張圖片新增 NDVI 頻帶。建議您先在單一圖片上測試函式,確認函式是否如預期般運作。在個別圖片上測試函式,並確認函式能達到預期效果後,即可將函式對應至集合:

程式碼編輯器 (JavaScript)

var withNDVI = l8.map(addNDVI);

如要確認這項操作確實為這個集合中的每張圖片加入 NDVI 頻帶,您可以將 withNDVI 集合新增至地圖,並使用「Inspector」分頁查詢隨機位置。您應該會發現,集合中的每張圖片現在都有一個名為 NDVI 的波段。

製作最綠像素合成圖

現在您已建立圖片集合,其中每張圖片都有 NDVI 頻帶,我們可以探索新的合成方式:qualityMosaic()。您可能已注意到 Landsat 路徑之間有不連續的情況,即使在中位數像素合成中也是如此。部分原因可能是物候學差異,因為相鄰路徑中的圖片是在不同時間收集 (具體來說,相隔 8 天)。如要盡可能減少這種情況,其中一種方法是嘗試從大致相同的物候階段設定合成影像中的像素值,例如植物最綠的時期 (葉子長出且光合作用活躍時)。如果我們將最大綠度定義為最大 NDVI,則可以使用 qualityMosaic() 建立合成影像,其中每個像素都包含集合中的最大 NDVI 像素。現在,您可以使用 withNDVI 集合中新增的 NDVI 波段:

程式碼編輯器 (JavaScript)

// Make a "greenest" pixel composite.
var greenest = withNDVI.qualityMosaic('NDVI');

// Display the result.
var visParams = {bands: ['B4', 'B3', 'B2'], max: 0.3};
Map.addLayer(greenest, visParams, 'Greenest pixel composite');

這段程式碼的結果應如圖 9 所示。比較圖 9 與圖 6 所示的中位數合成圖,可以發現最綠像素合成圖確實更綠。不過,仔細檢查水體後,應該會發現另一個問題。具體來說,水體現在會呈現混濁。這是因為 qualityMosaic() 方法的運作方式:在每個位置,系統會檢查整個時間序列,並將 NDVI 頻帶中最大值的像素設為合成值。由於雲層的 NDVI 高於水體,因此水體區域會出現多雲像素,而植被區域則全部顯示為綠色,因為像素中的植被進行光合作用時,NDVI 最高。

Tutorial_api_09_greenest.png
圖 9. Landsat 8 最綠像素合成。

您已瞭解在 Earth Engine 中合成及拼接圖片的幾種方式。您可以根據依時間和地點篩選的圖片,或集合中的所有圖片,製作近期值、中位數或最綠像素合成影像。您已瞭解如何對圖像進行運算及擷取資訊。下一頁將介紹從 Earth Engine 取得資訊的方法,例如將圖表或資料集匯出至 Google 雲端硬碟資料夾。