Google Earth EngineとPythonを使って衛星画像処理をする方法

スポンサーリンク

今回は、Pythonを使って衛星画像を扱い、可視化する方法を学びます。

このチュートリアルは、地理空間解析の世界へのごく簡単な紹介です。

少なくともPythonの初心者レベルの知識を持っている人を対象にしています。

スポンサーリンク

Python で Google Earth Engine を使った衛星画像処理

Google Earth Engineは、衛星画像と計算のための最良のソースの1つです。

これは、学術、非営利、ビジネス、および政府のユーザー向けに、地理空間データセットの科学的分析と視覚化のためのプラットフォームです。

Earth Engineは、衛星画像をホストし、40年以上前の過去の地球画像を含む公開データアーカイブに保存しています。

Googleは、少ないコードで簡単にEarth-Engineと通信できるAPIを提供してくれているのが素晴らしい。

このAPIはJavaScriptのAPIと似たようなもので、あまりPython的ではありません。

そのため、初めてAPIを使うときは少し戸惑うかもしれません。

1. eeライブラリのインストール

注:Google earthengine-apiはColab環境内に既にインストールされています。

そのため、Google Colabプラットフォームでpythonを実行している場合は、このステップを飛ばしても大丈夫です。

ローカルマシンで実行している場合は、まずローカルマシンにearthatgine-apiをインストールする必要があります。

earthengine-apiをインストールするためのpipコマンドは以下の通りです。

pip install earthengine-api --upgrade

2. インポートと認証

# Import the earth-engine module
import ee

Google Earth Engineへのアクセスは、現在登録ユーザのみとなっています。

そのため、このサービスを利用するには、Google Earth Engineへのユーザー登録が必要です。

また、ローカルマシンで初めてGoogle Earth Engineを利用する際には、登録ユーザーとして認証する必要があります。

ee.Authenticate()

一般に、ローカル環境での認証は一度だけ行われ、永続的な認証トークンが生成されますが、ColabのようなVMサービスではトークンの有効期限が制限されています。

最後に、APIを初期化する必要があります。

ee.Initialize()

これで、earth-engine APIを使用するための準備が整いました。

3. 画像データセットの読み込み

前述したように、Earth Engineには数多くのデータセットが用意されています。

我々のタスクに適したデータセットを選択することは、非常に重要です。

各データセットは、地球のさまざまな側面をカバーするためのものです。

例えば、樹木、水域などです。

この記事では、DMSP OLSを使用します。

このデータセットには、様々な国の夜間照明の時系列データが含まれています。

各データセットは、画像のコレクションです。

データセットの命名規則はImageCollectionで、以降この命名規則を用いて説明します。

# Load the Nighttime Image Collection
 
collection = ee.ImageCollection('NOAA/DMSP-OLS/NIGHTTIME_LIGHTS')

4. ImageCollection の操作

通常の写真と衛星画像を区別する最も重要な点は、画像のスペクトルが通常の 0-255 の範囲をはるかに超えていることです。

画像は、通常の画像のチャンネル(RGB)と比較することができる異なるバンドを持っています。

各バンドは、異なる電磁スペクトルをキャプチャします。

それでは、画像集の各画像がどのような帯域を持っているかを見てみましょう。

# Extract the first image
first_image = collection.first()
 
# Display band information about the image
first_image.bandNames().getInfo()

結果は、以下の通りです。

['avg_vis', 'stable_lights', 'cf_cvg', 'avg_lights_x_pct']

可視化するためには、stable_lightsバンドが必要です。

しかし、幸運なことに、earth-engineは画像のコレクションから1つのバンドを選択する方法を提供しています。

collection = collection.select('stable_lights')

これで、画像コレクションの各画像は1つのバンドを持つようになりました。

時間的な変化を視覚化するためには、時間を表す別のバンドが必要になります。

first_image = collection.first()
 
# Get number of years after 1991 from the first image
year = ee.Date(first_image.get('system:time_start')).get('year').subtract(1991)
 
# Turn it into a band
img1 = ee.Image(year).byte().addBands(first_image)
 
# A new band appears in the new image
img1.bandNames().getInfo()

結果は、以下の通りになります。

['constant', 'stable_lights']

これをコレクション内のすべての画像に対して行う必要があります。

そこで、関数を作成し、コレクションにマッピングします。

def createTimeBand(img):
    year = ee.Date(img.get('system:time_start')).get('year').subtract(1991)
    return ee.Image(year).byte().addBands(img)
 
# Map it to the collection to create a new collection
collection = collection.map(createTimeBand)

5. ナイトライトの可視化

ImageCollectionを表示する準備ができたので、画像を表示するためのUIが必要です。

UIはFolium、matplotlib、PILなど、たくさんの選択肢があります。

この記事では、Foliumを選択しました。

Foliumはleaflet.js(モバイルフレンドリーなインタラクティブマップのためのオープンソースのJavaScriptライブラリ)をベースにしたPythonライブラリで、インタラクティブな地図を作るために使うことができます。

FoliumはWMS、GeoJSONレイヤー、ベクターレイヤー、タイルレイヤーをサポートしており、pythonで操作するデータを視覚化するのに非常に便利でわかりやすくなっています。

もし、foliumがインストールされていない場合は、以下のpipコマンドでインストールすることができます

pip install folium --upgrade
# Import the folium library
import folium

ここで、foliumでgoogle earthの画像を表示する方法を定義する必要があります。

ここでは、FoliumとEarth-Engineで使用するのに非常に便利な関数を紹介します。

# Define a method for displaying Earth Engine image tiles to folium map.
def add_ee_layer(self, ee_image_object, vis_params, name):
  map_id_dict = ee.Image(ee_image_object).getMapId(vis_params)
  folium.raster_layers.TileLayer(
    tiles = map_id_dict['tile_fetcher'].url_format,
    attr = 'Map Data <a href="https://earthengine.google.com/">Google Earth Engine</a>',
    name = name,
    overlay = True,
    control = True
  ).add_to(self)
 
# Add EE drawing method to folium.
folium.Map.add_ee_layer = add_ee_layer

これで、初期座標とズームファクターを指定して、地図を作成することができます

多少間違っても気にしないでください。

Foliumはインタラクティブなので、地図を見ながら位置やズームを変更することができます

# Create the night map
night_map = folium.Map(location=[37.5010, -102.1899], zoom_start=4.5)

画像を表示するためのいくつかのパラメータ、例えばそれぞれのバンドや色の好みを設定する必要があります。

ここでは、あなたが好きそうなデフォルトの設定を紹介します。

#  visualize the y-intercept in green, and positive/negative slopes as red/blue.
 
params = {
    'bands' :  ['scale', 'offset', 'scale'],
    'min' : 0,
    'max' : [0.18, 20, -0.18],
}

可視化する前に、最後のステップがあります。

定数項を持つ1変数の線形関数の最小二乗推定値を計算する LinearFit メソッドを使って、画像を縮小する必要があります。

night_light = collection.reduce(ee.Reducer.linearFit())

画像とパラメータをマップに追加し、マップを表示します。

# Add the image layer to the night_map
night_map.add_ee_layer(night_light, params, 'test')
 
# Display the map
display(map)
Night Light 1 - Satellite Imagery using Google Earth Engine
Fig 1: Here is a beautiful representation of change of America night light from 1991
Night Light India - Satellite Imagery using Google Earth Engine
Fig 2: Here is a representation of change of night light in India and parts of south Asia since 1991
Trendy Lights Image - Satellite Imagery using Google Earth Engine
Fig 3: Change of night lights in the European countries

結論

Google Earth Engineを使った夜間照明の変化の可視化について、ここまで説明しました。

次のステップでは、異なるバンドや異なるデータセットを使用してみてください。

また、Googleでは、Sentinel-1イメージの変化を検出するなどのチュートリアルを用意していますので、ジオスペーシャル解析の詳細な方法について学ぶことができます。

タイトルとURLをコピーしました