LoginSignup
6
9

More than 3 years have passed since last update.

衛星画像ファイルをNumpy Arrayの形で保存する方法(Python)

Last updated at Posted at 2021-01-27

概要

こんにちは。
 衛星リモートセンシングの分野では大量の画像を扱うことがありますが、GeoTiffなどの位置情報付きのものは専用のソフト(QGIS)などで扱うことが主だと思います。数十枚までならば気合で処理することもできますが、数百~数千枚になると非常に険しいのでPython等で自動化したい気持ちが湧いてきます。特にNumpy arrayの形は統計手法や機械学習手法を用いる際のベースとなるので、この形で取り込めると便利ですね。また衛星画像解析では時系列の情報も大切になりますが、変数に逐一"~_2019"と付けるのも大変です。
 以上を踏まえて、画像が格納されているフォルダから画像ファイルをNumpy arrayの形で読み込み、それを辞書型配列に画像の取得年と一緒に格納するコードを書いたので、ご紹介したいと思います。

環境と前提条件

  1. Google Colabで実行 (記事執筆時点でのバージョンはpython 3.6.9)
  2. ファイル名は"~YYYYMMDD~.geotiff"の様に取得年を含む形になっていることが前提条件です
  3. ファイルパス等についてはご自分の環境に合わせて変えて頂ければ(多分)動くと思います。Google Colabは個人的にとても便利だと感じているので、是非この機会に手を出されてみるのもオススメです!

Colab入門編

コード

最初に必要なモノをインポートしましょう。

import.py
from osgeo import gdal
import numpy as np
import glob
import os
import pandas as pd

ファイル名を取得して年ごとに辞書型配列にしまっておきます。例では2001年から2020年までのMODIS衛星のプロダクト画像を使う準備をしています。ここを変えれば違う年についても大丈夫だと思われます。ソートをかけているのは、これが無いとファイル順がカオスになってしまうからです。ワイルドカードで特定の年に合うファイル名を探しつつ、forループでぐるぐる回しています。"/content/drive/My Drive/Colab Notebooks"はColabからDriveのファイルを使う際に特有の書き方なので、ここを変えればColab以外でも動くのではないでしょうか。

filename.py
for y in range(2001,2021):
  filenames=[os.path.basename(p) for p in \
sorted(glob.glob(f'/content/drive/My Drive/Colab Notebooks/satellite_data/MODIS.2001-2020.FRP.Buryat/L3/MODIS.{y}*.geotiff', recursive=True)) \
if os.path.isfile(p)]
  list_of_filenames[f"{y}"]=filenames

画像をnumpy行列へ格納していきます。画像が重かったり、沢山ある場合にはそこそこ時間がかかると思います。gdalでファイルを開いて、Arrayとして読み込んでいきます。グレースケール画像を使っていたのでバンドを一つしか読んでいません。前段階でソートをかけているので、日時についてはfor文で頭から順番に読んでいきます。途中でコメントアウトしてあるprint(FName)を使うことでファイル名が書かれていくと思うので、これによって順番通りに処理されているか確認されても良いかもしれません。

array.py
database_array={}
for year in list_of_filenames.keys():
  ArrayList=[]
  for day in range(len(list_of_filenames[f"{year}"])):
    FName=list_of_filenames[f"{year}"][day]
    #print(FName)
    File=gdal.Open(f'/content/drive/My Drive/Colab Notebooks/satellite_data/MODIS.2001-2020.FRP.Buryat/L3/{FName}')
    FileAsArray=File.GetRasterBand(1).ReadAsArray()
    ArrayList.append(FileAsArray)
  database_array[f"{year}"]=ArrayList

処理が終わると、辞書型配列として画像が格納されているかと思います。
配列の格納にはそこそこ時間がかかるので、以下の様にpickleとして保存しておいてもいいかもしれません。

save.py
pd.to_pickle(database_array,'/content/drive/My Drive/Colab Notebooks/outputs/pickle/database_array.pkl')
#再度の読み込みも簡単
#database_array=pd.read_pickle('/content/drive/My Drive/Colab Notebooks/outputs/pickle/database_array.pkl')

以上が記事の内容です。初投稿なので色々と至らなかった点も多いと思いますが、今までお世話になったQiitaコミュニティへと少しでも貢献できていたら幸いです。

6
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
9