Google Earth EngineとGoogle Colabによる人工衛星画像解析　〜無料で始める衛星画像解析（入門編）〜

## はじめに
- 近年、人工衛星データを社会やビジネスで利用するケースが増えてきています
- 人工衛星は宇宙から地球の状態を様々なセンサーで観測しており、それらは**オープンデータ**として公開されています
- 衛星データはビッグデータであり、昨今の機械学習やAIの技術と親和性の高いのですが、必要とされる処理リソース（ストレージ・メモリ）が膨大になりがちであり、個人のPC環境で利用するにはハードルが高いです
- しかし、Googleが提供するクラウドリソースを利用することで、**個人でも無料で衛星データ解析**を行うことができます
- 本記事では、**Google Earth Engine (GEE)**と**Google Colaboratory (Colab)**を利用して衛星データ解析の手法を紹介します
- 後日公開予定の[【実践編】](https://qiita.com/takubb/items/a98e2cab6f66d2f9c507)では衛星データから取得できる代表的なデータ（地表面温度・植生指数・積雪指数）の取り扱いも紹介していきたいと思います
- 衛星データ解析では様々なセンサーを組み合わせることで、色々な地球環境の状態を捉えることができるので、**本記事の内容を入門として、身近な環境状態のデータ解析に役立ててみる**と面白いかと思います

## 本記事の特徴
- 通常、GEEはブラウズ上でJavaScriptを用いて解析を行います
- しかし、**機械学習や統計解析のライブラリが豊富なPythonで解析を行いたい**ので、**最低限の処理（衛星画像の抽出と保存）のみGEEのPython API**で行い、**可視化や解析はpythonの通常ライブラリ(numpyやmatplotlib)**で行う方法を紹介します
- また、大容量の衛星画像データをローカルPCのリソースに依存せずに解析を行いたいので、Google Colab+Google Driveの**クラウド環境のみで処理を完結する方法**を紹介します（勿論、保存先をローカルに指定すれば、ローカル環境でも同様に解析が行えます）

#### サービスの使い分けイメージ ~Googleサービスを利用してクラウドサービスのみで衛星画像解析を行う~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76983/edbbd025-042a-686f-3d06-d4fb7abcc819.png)

## Google Earth Engine (GEE) の 概要
- 2010年の12月にGoogleがサービスリリース
- 人工衛星画像を自前のパソコンにダウンロードすることなく、GEEサーバー上で解析を行うことが出来る
- 通常の衛星データ解析では、異なるデータフォーマットの対応やデータの前処理が必要だが、GEE上には様々な衛星データが準備されており、必要なデータのみロードして利用することができる
- 研究・教育・非営利目的に限り無償で利用することができる（有償プランもあり）
- 注）地球儀を閲覧できるGoogle Earthとは別サービスです

## Google Colaboratory (Colab) の概要
- 環境構築不要でブラウザからPython を記述・実行できるサービス
- GPUも無料で利用することができる
- Google Colabの概要や利用方法は分かり易い記事が豊富にあるので、それらをご覧ください
    - [Google Colabを導入](https://qiita.com/kyo92/items/ebeb5ea9ce216e1d6205)
    - [Google Colabの使い方まとめ](https://qiita.com/shoji9x9/items/0ff0f6f603df18d631ab)

## 【利用方法】　衛星画像解析 on GEE&Colab
### アカウントの準備
1. [Google Earth Engine ](https://earthengine.google.com/)の公式ページよりサインアップを行う（Googleアカウントが必要です）
2. サインアップが完了するとGEE上で利用できる衛星データの一覧である[データカタログ](https://developers.google.com/earth-engine/datasets/catalog)にアクセスできるようになる

### Python環境(Google Colab)でのGEE利用
#### 1. Google ColabからPython APIを用いてGEEの認証を行う

```python
# Earth Engine Python APIのインポート
import ee
# GEEの認証・初期化
ee.Authenticate()
ee.Initialize()
```
- GEE認証を実行すると認証に必要なURLが表示される
- URLへアクセスしてGoogleアカウントを指定すると、認証コードが表示される
- 認証コードをGoogle Colabのボックスへコピペする

#### 2. GEEの衛星データをロードする
- データカタログからロードしたい**衛星名**を選択
    - ここでは夜間光（NightTime-Light）のデータを収集しているDMSP-OLSを選択
    - 夜間光については[過去記事](https://qiita.com/takubb/items/97b2e4ed91cf417c4a66)「夜間光データとは」を参照
- データロードしたい**バンド名**を選択
    - 通常、人工衛星では複数のバンド（波長が異なるセンサー）でデータを取得しているので、目的にあったバンド名を指定する
    - ここでは、夜間光データの本体である'avg_vis'を選択する
    - 'avg_vis'は0~63の整数値で夜間光の強さを表現するセンサーである
- データロードしたい**期間**を指定
    - 通常、衛星は再帰的に観測を継続している時系列データである（観測頻度は衛星によって異なる）
    - そこで取得したいデータの期間を選択する
- データロードしたい**エリア**を指定
    - 人工衛星は地球全域を観測しているので、必要なエリアを指定する
    - ここでは緯度・経度を用いて、長方形でデータを抽出する方法を採用している
        - ee.Geometry.Rectangle([xMin, yMin, xMax, yMax])で指定する
        - xMin=(左下の経度), yMin=(左下の緯度), xMax=(右上の経度), yMax=(右上の緯度)


```python
# 衛星名を指定
satellite = 'NOAA/DMSP-OLS/NIGHTTIME_LIGHTS'
# バンド名を指定
band = 'avg_vis'
# 期間を指定
from_date='2010-01-01'
to_date='2012-12-31'
## エリアを指定(日本エリアを緯度・経度を指定)
geometry = ee.Geometry.Rectangle([128.60, 29.97, 148.43, 46.12])

# 指定した条件でGEEからデータをロード
dataset = ee.ImageCollection(satellite).filter(
    ee.Filter.date(from_date, to_date)).filter(
    ee.Filter.geometry(geometry)).select(band)
```

- 今回の衛星プロダクトは年ごとのデータセットなので、2010~2012年の3年分のデータが存在している
- 衛星によって計測頻度は異なり、時間解像度の細かい衛星（例:12日ごとに観測している衛星）では長期間を指定すると大量のデータがロードされるので注意が必要となる
- 対象のデータ数は下記のコマンドで確認することができる

```python
# 対象データ数の確認
print(dataset.size().getInfo())
```

#### 3. 衛星画像データの保存
- 指定した衛星データをGoogle Driveへ保存する
- リスト形式へ変換しておくことで、任意の画像を保存することができる
- ee.batch.Export.image.toDriveを利用することで、Google DriveのMyDrive内の指定したフォルダへデータが保存される
- また画像をダウンロードする際に、scaleで画像の解像度を指定することができる

```python
## リスト形式へ変換
data_list = dataset.toList(dataset.size().getInfo())
# 0番目の画像（2010年の画像）を取得
image = ee.Image(data_list.get(0))

# Gdriveへ保存
task = ee.batch.Export.image.toDrive(**{
    'image': image,# 対象データの指定
    'description': 'sample_dataloading_NTL',# ファイル名の指定
    'folder':'GEE_download',# Google Drive(MyDrive)のフォルダ名
    'scale': 1000,# 解像度の指定
    'region': geometry.getInfo()['coordinates']# 上記で指定した対象エリア
})

# 処理の実行
task.start()
```

- 上記コマンドを実行すると、Google Drive > My Drive > GEE_downloadにsample_dataloading_NTLというファイルが保存される
- ロードするデータサイズによっては時間がかかり、task.active()によって進捗を確認することができる
task.active()=Trueの場合はGEEが処理中なので、Falseになるまで待つ

```python
# データの処理状況の確認（Trueで処理中を表す）
task.active()
```

#### 4. 保存した衛星画像の確認
- データはTIF形式で保存されている
- そこでrasterioを利用しTIF形式のデータの読み込みとmatplotlibを用いた可視化を行う
- TIFデータの取り扱いとrasterioの利用方法については下記を参照
[【入門】Pythonによる人工衛星データ解析（Google Colab環境）](https://qiita.com/takubb/items/97b2e4ed91cf417c4a66)

```python
# パッケージのインストール&インポート
!pip install rasterio
import numpy as np
import matplotlib.pyplot as plt
import rasterio

# データの読み込み
with rasterio.open('/content/drive/My Drive/GEE_download/sample_dataloading_NTL.tif') as src:
    arr = src.read()

#  numpy形式でデータを取得 -> (1, 1847, 2208)の配列で取得
print(arr.shape)

# 可視化
plt.imshow(arr[0])
```
"2010年 DMSP-OLSによる夜間光データ"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76983/10ad41e3-c832-8b5b-659a-9b7be6f9389c.png)

- arrはnumpy形式なので、衛星データの統計値を計算したり、翌年のデータを取得してきて時系列比較したり、自由に解析を行うことができます
- また[過去記事](https://qiita.com/takubb/items/97b2e4ed91cf417c4a66)で紹介している　ベクターファイルやgeopandasを用いることで、国や都道府県単位でデータをくり抜いて可視化したり、データ変化を計算することも可能です

### 一連の処理の関数化
- 最後に上記の一連の処理を関数化しておきます
- 次回はこの関数を用いて、人工衛星を用いて観測されている様々な指標（地表面温度、植生指数、積雪指数など）を用いた解析を行ってみたいと思います

```python

# Earth Engine Python APIのインポート
import ee

# GEEの認証・初期化
ee.Authenticate()
ee.Initialize()

# GEEのデータロード
def load_data(snippet, from_date, to_date, geometry, band):
    # パラメータの条件にしたがってデータを抽出
    dataset = ee.ImageCollection(snippet).filter(
    ee.Filter.date(from_date, to_date)).filter(
    ee.Filter.geometry(geometry)).select(band)
    # リスト型へ変換
    data_list = dataset.toList(dataset.size().getInfo())
    # 対象データ数とデータリストを出力
    return dataset.size().getInfo(), data_list

# 衛星画像をGoogle Driveへ保存
def save_on_gdrive(image, geometry, dir_name, file_name, scale):
    task = ee.batch.Export.image.toDrive(**{
        'image': image,# ロードする衛星情報
        'description': file_name,# 保存するファイル名
        'folder':dir_name,# 保存先のフォルダ名
        'scale': scale,# 解像度
        'region': geometry.getInfo()['coordinates'],# 対象エリア
        'crs': 'EPSG:4326'
    })
    # Run exporting
    task.start()
    print('Done.')

## パラメーターの指定
# 衛星を指定
snippet = 'NOAA/DMSP-OLS/NIGHTTIME_LIGHTS'
# バンド名を指定
band = 'avg_vis'
# 期間を指定
from_date='2010-01-01'
to_date='2012-12-31'
# エリアを指定(日本エリアを緯度・経度を指定)
geometry = ee.Geometry.Rectangle([128.60, 29.97, 148.43, 46.12])
# 保存するフォルダ名
dir_name = 'GEE_download'
# ファイル名
file_name = 'file_name'
# 解像度
scale = 1000

## 処理の実行 ----------------------------------------------
num_data, data_list = load_data(snippet=snippet, from_date=from_date, to_date=to_date, geometry=geometry, band=band)
print('#Datasets; ', num_data)

## 全件保存（ファイル名は衛星IDを利用）
for i in range(data_list.size().getInfo()):
    image = ee.Image(data_list.get(i))
    save_on_gdrive(image, geometry, dir_name, image.getInfo()['id'].replace('/', '_'), scale)
```

## さいごに
- 本記事ではGoogleの各種サービス（GEE, Colab and Drive)を利用した衛星画像解析の方法を紹介しました
- GEEを利用することで、データカタログに記載されている様々な衛星データセットを同じコマンドで利用できることが魅力的です（通常、衛星データセットを利用する際は、運用機関ごとの異なるフォーマットや複雑な前処理が必要になるのですが、GEEを利用するこで、解析者が分析・活用に注力することができます）
- また、Goole Colabを利用することで基本的な可視化や解析から、本記事では紹介していませんが、GPU環境へ切り替えて衛星データをインプットとした機械学習の訓練への拡張も簡単に行うことができます
- [GEEのデータカタログ](https://developers.google.com/earth-engine/datasets/catalog)には沢山のデータセットが掲載されているので、本記事をキッカケに地球環境分析に興味を持って頂ければと思います