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 - red) / (NIR + red) です。これにより、1 ~-1 の数値が得られます。光合成活性が高いピクセルは NDVI が高くなります。これは、Earth Engine で NDVI を計算する方法の 1 つです。

コードエディタ(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() 関数を使用して、NIR バンドと赤バンドを取得し、Image 数学に関するセクションで説明した画像数学演算子を使用して NDVI を計算します。最後に、パレットを使用して画像を表示します。ここでは、パレットで 16 進文字列の代わりに色の名前を使用しています。(詳しくは、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 バンドを追加できます。多くの場合、まず 1 つの画像で関数をテストして、関数が想定どおりに動作することを確認すると便利です。個々の画像で関数をテストし、目的の処理が行われることを確認したら、コレクションにマッピングします。

コードエディタ(JavaScript)

var withNDVI = l8.map(addNDVI);

このコレクションのすべての画像に NDVI バンドが実際に配置されていることを確認するには、withNDVI コレクションを地図に追加し、[Inspector] タブでランダムな場所をクエリします。コレクション内の各画像に NDVI というバンドが追加されていることがわかります。

最も緑の多いピクセル合成を作成する

各画像に NDVI バンドがある画像コレクションを作成したので、qualityMosaic() を使用してコンポジットを作成する新しい方法を試すことができます。中央値ピクセル合成でも、Landsat パス間に不連続性があることに気づいたかもしれません。その理由の一部は、隣接するパスの画像が異なる時期(具体的には 8 日間隔)に収集された結果、フェノロジーに違いがあるためと考えられます。これを最小限に抑える方法の 1 つは、ほぼ同じ生物季節段階(たとえば、植物の緑が最も濃い時期、つまり葉が茂り、光合成が活発な時期)のコンポジットでピクセル値を設定することです。最大緑度を最大 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 ドライブ フォルダにエクスポートされたデータセットなど)について説明します。