ラベル リモートセンシング の投稿を表示しています。 すべての投稿を表示
ラベル リモートセンシング の投稿を表示しています。 すべての投稿を表示

2019/01/07

文系のための「正規化指標」(2)

リモートセンシングにおける解析手法として、
正規化指標は基礎的な手法の一つであり、
高度な分析においても部分的に使用されることもある。

NDVI(Normalized Difference Vegetation Index)がよく知られているが、
植生以外の状態を分析するための正規化指標もある。
そこで、今回は代表的な正規化指標を紹介することにする。

とりあえずは、使用するデータを準備する。
まず、検索バーからLandsat 8の Tier 1 Raw Scenenes を検索し、
インポートして変数名を landsat8としておく。

また、表示範囲を絞り込むために、
ジオメトリ・ツール使って、適当な場所にポイントを作成し、
作成した変数名を geomtry としておく。

var image = ee.Image(landsat8
    .filterBounds(geometry)
    .filterDate('2015-06-01', '2015-09-01')
    .sort('CLOUD_COVER')
    .first()
);

ついでに、表示用のカラーパレットも準備しておく。

var waterPalette = ['red', 'yellow', 'green', 'blue'];
var builtPalette = ['blue', 'green', 'yellow', 'red'];
var snowPalette = ['red', 'green', 'blue', 'white'];

まずは、植生の含水量の指標としてGao (1996) によって開発された
NDWI(Normalized Difference Water Index)という指標である。
この指標は近赤外線(NIR)と短波長赤外線(SWIR)の放射輝度を使用する。

NDWI = (NIR - SWIR) / (NIR + SWIR)

短波長赤外域は植物の葉の水分によって吸収されるという特性があるが、
近赤外域は植物の細胞を傷つけてしまうために反射される。
この特性によって植物の含水量を分析する方法がNDWIである。

一応、実際に適用する方法は以下の通り…。
ただし、NDWIはあくまでTMセンサを前提とした指標であり、
Landsat 8 に搭載されているOLIセンサの場合には要注意!

var ndwi = image.normalizedDifference(['B5', 'B6']);
Map.addLayer(
    ndwi, 
    {
        min: 0.0, 
        max: 0.3, 
        palette: waterPalette
    }, 
    'NDWI'
);

このコードの実行結果は以下の通り。



NDWBI(Normalized Difference Water Body Index)という指標もある。
この指標はNDWIと同じ1996年にMacFeeters (1996)によって発表された指標であり、
緑色光域と近赤外域の反射・吸収特性を使用して水域を抽出する。

NDWBI = (Green - NIR) / (Green + NIR)

水域は緑色光域においても緑色の光を反射するが、近赤外域は吸収する。
したがって、植生のある部分では近赤外域の反射が相対的に強くなり、
逆に、水域では近赤外の反射が相対的に弱くなる。

ということで、Google Earth Engine で実装してみる。

var ndwbi = image.normalizedDifference(['B3', 'B5']);
Map.addLayer(
    ndwbi, 
    {
        min: -0.5, 
        max: 0.2, 
        palette: waterPalette
    }, 
    'NDWBI'
);

そして、実行結果は以下の通り。



NDWIとNDWBIは名前もよく似ていて、両方とも水に関わる指標であるが、
前者は植物の葉に含まれる水分量、後者は水域を抽出するための指標である。
実際に両者を比較すると、どのような違いが見られるだろうか?

正規化指標は植物や水に関わる分析以外にも利用される。
そうした指標の一つがNDBI(Normalized Difference Built-up Index)である。
この指標は都市域を抽出するために用いられる指標である。

NDBI = (SWIR - NIR) / (SWIR + NIR)

この指標のモデルを見てみるとNDWIの式の関係が逆転していることが解る。
この指標は都市部の短波長赤外域の反射強度が近赤外域よりも高いことを利用している。

ということで…。

var ndbi = image.normalizedDifference(['B6', 'B5']);
Map.addLayer(
    ndbi, 
    {
        min: -0.4, 
        max: 0.1, 
        palette: builtPalette
    }, 
    'NDBI'
);

これも実行すると…。



地球温暖化に焦点を当てるのであれば、雪の分析が必要なるかもしれない。
その指標に利用されるのがNDSI(Normalized Difference Snow Index)である。
この指標は雪が短波長赤外域を吸収すること利用している。

NDSI = (Green - SWIR) / (Green + SWIR)

波長域とバンド名が解っていれば簡単であるが…。

var ndsi = image.normalizedDifference(['B3', 'B6']);
Map.addLayer(
    ndsi, 
    {
        min: -0.3, 
        max: 0.3, 
        palette: snowPalette
    }, 
    'NDSI'
);

そして、最後に…。



Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License.

2018/06/06

文系のための「Map Linker」

Google Earth Engine(GEE)を使っていると、
複数の解析画像を同時に並べて表示したいことがある。
実は、GEEのCode Editor ではそういったことも可能になる。

とにかく、こんな感じのことをやってみたい。できれば、連動してもらいたい。



ということで、まずは、Landsat 8 の画像を取得することにする。
時期の範囲は2016年1月1日〜2016年12月31日とし、
場所は奈良の平城旧跡が入る範囲とする。

もちろん、Langsat 8 のImageCollectionから選ぶのは雲が最も少ない画像。

//   Landsat 8 の画像から一枚の画像を取得する
var beginning = '2016-01-01';
var ending = '2016-12-31';
var heijou = ee.Geometry.Point(135.791605, 34.6881882);

var ln8_2016 = ee.Image(landsat8
                .filterDate(beginning, ending)
                .filterBounds(heijou)
                .sort("CLOUD_COVER")
                .first()
);

次に、可視化する際の可視化パラメータを変数として定義しておく。

// トゥルーカラーパレットを定義する。
var trueColorParam = {
  bands: ['B4', 'B3', 'B2'],
  gamma: 1,
  max: 12000,
  min: 5000
};

// フォールスカラーパレットを定義する。

var falseColorParam = {
  bands: ['B5', 'B4', 'B3'],
  gamma: 1,
  max: 12000,
  min: 5000
}

// ナチュラルカラーパレットを定義する。
var naturalColorParam = {
  bands: ['B4', 'B5', 'B3'],
  gamma: 1,
  max: 12000,
  min: 5000
}

最初にするべきことはMapオブジェクトを作ること。
今回の場合、トゥルーカラー、フォールスカラー、ナチュラルカラーに対応するように、
それぞれの画像に対応した、三つのMapオブジェクトを準備しておく必要がある。

// Mapオブジェクトをインスタンス化する
var map_true = ui.Map();        // トゥルーカラー用の Map
var map_false = ui.Map();       // フォールスカラー用の Map
var map_natural = ui.Map();     // ナチュラルカラー用の Map

そして、それぞれのMapオブジェクトに対応する画像を追加していく。
よく見ると、これまでに使ってきた「Map.addLayer()」と全く同じ。
既定の「Map」インスタンスではなく、新しく作ったMapオブジェクトに追加する。

// それぞれのレイヤにそれぞれの画像を追加する。
map_true.addLayer(ln8_2016, trueColorParam, 'True Color');
map_false.addLayer(ln8_2016, falseColorParam, 'False Color');
map_natural.addLayer(ln8_2016, naturalColorParam, 'Natural Color');

単に表示させるだけであれば、飛ばしても良いのであるが、
少しでも見栄えがよくなるように、
タイトル・ラベルとレイヤー・マネージャーも追加しておく。

まずは、タイトル・ラベル。各々のレイヤに追加していく。

// それぞれのMapにタイトルラベルを追加する。
map_true.add(ui.Label('True Color'));
map_false.add(ui.Label('False Color'));
map_natural.add(ui.Label('Natural Color'));

次に、レイヤー・マネージャーも追加しておく。

// それぞれのMapにレイヤー・マネージャーを追加する。
map_true.setControlVisibility(true);
map_false.setControlVisibility(true);
map_natural.setControlVisibility(true);

複数のマップの同時表示には複数のマップを格納するための「器」が必要となる。
ここでは「maps」という名前を定義し、初期値として「空の配列」をセットする。
そして、これまでに使ってきたMapオブジェクトを配列に放り込む。

// 複数のマップオブジェクトを格納するための空の配列を定義する。
var maps = [];

// それぞれのMapを配列に追加する。
maps.push(map_true);
maps.push(map_false);
maps.push(map_natural);

以上で準備完了。あとは、それぞれのマップ・オブジェクトを連動させる。
このときに用いるのがLinkerオブジェクトである。
複数のマップが格納された配列「maps」をそのまま入れてインスタンス化する。

そして、最後の仕上げとしてUIをリセットして完了!

// マップ・リンカーオブジェクトを作って、複数のマップを連動させる
var linker = ui.Map.Linker(maps);

// UIをリセットする。
ui.root.widgets().reset(maps);

これで、今回作成した三つのマップは横三つに並び、
表示位置も連動してくれるはず。
試しに、三つのマップの中でひとつ目のMapの中心を指定してみる。

// 地図の中心をひとつ目のマップのオブジェクトの衛星画像に設定する。
maps[0].centerObject(ln8_2016, 9);


これで三つのマップが連動して動けば完了。 Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License.