NDVI、对集合应用函数、质量镶嵌

之前,您已了解如何通过执行类似以下操作来获取各个 Landsat 场景,其中 l8point 是表示 Landsat 8 TOA 集合和感兴趣区域几何图形的导入项: <x0A>

代码编辑器 (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 - red) / (NIR + red)。这样会得到一个介于 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 集合添加到地图,然后使用检查器标签页查询随机位置。您应该会注意到,集合中的每个图片现在都有一个名为 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 高,因此水面区域会获得多云像素,而植被区域则全部显示为绿色,因为当像素中的植被具有光合作用活性时,NDVI 最高。

Tutorial_api_09_greenest.png
图 9. Landsat 8 最绿像素合成图。

现在,您已经了解了在 Earth Engine 中合成和镶嵌图像的几种方法。您可以根据按时间和地点过滤的图片或集合中的所有图片制作最近值、中值或最绿像素合成图。您已了解如何对影像进行计算并提取信息。下一页将介绍如何从 Earth Engine 中获取信息,例如以图表或导出到 Google 云端硬盘文件夹的数据集的形式。