Edited at
FOSS4G Day 14

pix2pix でタイル地図を変換してみた!

More than 1 year has passed since last update.


概要



  • pix2pix-tensorflowで地図タイルを扱うためのツールを公開しました → pix2pix for Map tiles

  • 学習データとして,地図タイル,WMS等を指定できます.また複数のレイヤを学習データとして指定することができます.

  • サンプルとして,二時期,計四種類のLandsat7号の画像と地理院標高PNGタイル画像を学習データとし,教師画像を植生図とした変換を行ってみました.


はじめに

pix2pixは,ご存じの通り画像から画像への変換を行うDeep Learningの1つです.一対の画像を準備することにより,画像間変換が可能となります.pix2pixのサンプルでも空中写真から地図への変換例ががありあす。

pix2pix sample

pix2pixでの画像変換例。左下が空中写真から地図への変換です。

この変換のための画像を準備するのが大変なのですが,地理空間情報では,地図タイルという形で256*256の画像が大量に整備されています.

そこで,地図タイル画像をpix2pixで簡単に扱えるようにするツールをつかって,衛星画像と標高データから,植生図への変換を試みました.


pix2pix for Map tiles

pix2pix for Map tilesは,pix2pix-tensorflowで地図タイルを扱うための各種ツールです.特徴としては,


  • WEB上で公開されている地図タイルのアドレスと{Z}/{X}/{Y}.extを指定することにより,学習用のデータを生成できる

  • 学習用データとして,複数のソースを指定することができる.

という点があります.現在公開しているツールは,

DataSetMake_tfwiter.py:地図タイルやWMSから学習のためのデータを生成するスクリプト.

pix2pix_multi.py:上記で作ったデータを持ちいて,学習を行うためのプログラム.

の2つです.


pix2pix for Map tilesをつかった画像変換例


使用した画像

pix2pix for Map tilesを使った変換を行ってみました.学習データとして使用したのは,

の五種類で,教師データは,

です.学習に用いた範囲は,地図タイルで「Z:12,X:3635~3648,Y:1600~1613」になります.LandBrowserではWMSで提供されたデータを,国土地理院標高PNGタイルでは地図タイルとして提供されるデータを使用しています.

以下に,学習に使用したデータのイメージを表示します.

2017-10-15 15_28_42-input_image0.png ‎- フォト.png

Landsat7号PanSharpend画像 Path:107 Row:035 2000年5月16日撮影 産総研LandBrowser提供

2017-10-15 15_30_06-input_image1.png ‎- フォト.png

Landsat7号band62画像 Path:107 Row:035 2000年5月16日撮影 産総研LandBrowser提供

2017-10-15 15_30_14-input_image2.png ‎- フォト.png

Landsat7号PanSharpend画像 Path:107 Row:035 2000年12月26日撮影 産総研LandBrowser提供

2017-10-15 15_30_21-input_image3.png ‎- フォト.png

Landsat7号band62画像 Path:107 Row:035 2000年12月26日撮影 産総研LandBrowser提供

2017-10-15 15_30_27-input_image4.png ‎- フォト.png

国土地理院標高PNGタイル

2017-10-15 15_30_32-target_image.png ‎- フォト.png

環境省第六~七回植生図 エコリス地図タイル提供


学習用データの作成

学習用データの作成には,DataSetMake_tfwiter.pyを使用します.このスクリプトの実行には,学習対象となる地図タイルのアドレスを指定したJSON形式のファイルが必要になります.今回は,jsonLan2Vege.txtとして以下の内容で作成しました.

{

"targetURL": {
"url": "http://map.ecoris.info/tiles/vege67/",
"type": "tile",
"format": "{z}/{x}/{y}.png"
},
"inputURL": [
{
"url": "http://ows8.geogrid.org/land7uswms/LE71070352000137HAJ00?LAYERS=default&TRANSPARENT=TRUE&",
"type": "wms",
"format": "SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image/png&BBOX={miny},{minx},{maxy},{maxx}&SRS=EPSG:4612&width={output_height}&height={output_height}&ua=landbrowser"
},
{
"url": "http://ows8.geogrid.org/land7uswms/LE71070352000137HAJ00?LAYERS=BAND62COLOR&TRANSPARENT=TRUE&",
"type": "wms",
"format": "SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image/png&BBOX={miny},{minx},{maxy},{maxx}&SRS=EPSG:4612&width={output_height}&height={output_height}&ua=landbrowser"
},
{
"url": "http://ows8.geogrid.org/land7uswms/LE71070352000361EDC00?LAYERS=default&TRANSPARENT=TRUE&",
"type": "wms",
"format": "SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image/png&BBOX={miny},{minx},{maxy},{maxx}&SRS=EPSG:4612&width={output_height}&height={output_height}&ua=landbrowser"
},
{
"url": "http://ows8.geogrid.org/land7uswms/LE71070352000361EDC00?LAYERS=BAND62COLOR&TRANSPARENT=TRUE&",
"type": "wms",
"format": "SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image/png&BBOX={miny},{minx},{maxy},{maxx}&SRS=EPSG:4612&width={output_height}&height={output_height}&ua=landbrowser"
},
{
"url": "http://cyberjapandata.gsi.go.jp/xyz/dem_png/",
"type": "tile",
"format": "{z}/{x}/{y}.png"
}
]
}

データの作成は,以下のコマンドで実行します.

python DataSetMake_tfwiter.py 3635 3648 1600 1613 12 --outputPath train --inputJson jsonVege.txt

なお,データ作成中に学習データと教師データのチャンネル数が表示されます.このチャンネル数は,以降の学習の実行,学習結果の確認で使用するので,メモしてください.

作成が成功すると,trainディレクトリ内に,1.tfrecords,2.tfrecords,・・・・という形で学習用データが生成されます.また,実行したフォルダには,input_image0.png,input_image1.png,input_image2.png,input_image3.png,input_image4.pngという形で学習用データを結合した画像が,target_image.pngとして教師データを結合した画像が出力されます.


学習の実行

学習の実行は,pix2pix_multi.py--mode trainを指定して行います.今回は

python pix2pix_multi.py --mode train --max_epochs 200 --input_dir train --input_ch 20 --target_ch 4 --output_dir classify --GPUdevice 0

として行いました.ここで,学習データは--input_dir trainで指定し,学習結果は--output_dir classifyに出力されます.また--max_epochs 200で学習回数を,--GPUdevice 0で学習に使用するGPUを指定します.学習データと教師データのチャンネル数は,それぞれ--input_ch 20 --target_ch 4として指定します.


学習結果の確認

学習結果の確認は,pix2pix_multi.py--mode testを指定して行います.今回は

python pix2pix_multi.py --mode test --output_dir output --input_dir train --checkpoint classify --input_ch 20 --target_ch 4

として実行しました.ここで,--input_dir trainは確認に使用するデータを,--input_ch 20 --target_ch 4は学習データと教師データのチャンネル数を指定します.--checkpoint classifyでは,学習したモデルを格納したディレクトリを指定し,比較結果は--output_dir outputに出力されます.結果は以下のような形で出力されます.

2017-10-15 16_10_56-Program Manager.png

今回の試験結果は, https://naro-41605.github.io/pix2pix_map_tiles/lad2veg/output/index.html で確認できます.


おわりに

今回使用したスクリプトでは,複数のタイル画像を指定してpix2pixで学習させることができます.地図タイル形式で公開されているデータであれば,様々な用途で利用できると思うので,是非活用してもらえればと思います.

また,今後,以下のような点が改善できればいいなーと,思います.


  • 出力のデータ形式がRGBになっているが,例えば主題図であればRGBではなく,カテゴリー値(8bitデータとか)として分類を行うようにする.

  • 学習済みのモデルを,他の地域で実行させる機能


    • たとえば,QGISで表示させた 範囲のデータを分類するとか



  • 学習データとして,ベクタタイルに対応できるといいなー,とか.


おまけ・環境構築について


動作確認環境

本作業は、以下の環境において行いました。

分類
バージョン

OS
Ubuntu 14.04 LTR 64bit

フレームワーク等
Python 2.7.6

tensorflow 1.0.0

CUDA 8.0 (GPU環境のみ)

CuDNN V5 (GPU環境のみ)


インストール方法


  1. 実行に必要な各パッケージをインストールします。

sudo apt-get update

sudo apt-get install python-pip python-dev libfreetype6-dev pkg-config liblapack-dev gfortran libtiff5-dev libjpeg8-dev zlib1g-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python-tk python-scipy

sudo pip install \
appdirs==1.4.0 \
funcsigs==1.0.2 \
google-api-python-client==1.6.2 \
google-auth==0.7.0 \
google-auth-httplib2==0.0.2 \
google-cloud-core==0.22.1 \
google-cloud-storage==0.22.0 \
googleapis-common-protos==1.5.2 \
httplib2==0.10.3 \
mock==2.0.0 \
numpy==1.12.0 \
oauth2client==4.0.0 \
packaging==16.8 \
pbr==1.10.0 \
protobuf==3.2.0 \
pyasn1==0.2.2 \
pyasn1-modules==0.0.8 \
pyparsing==2.1.10 \
rsa==3.4.2 \
six==1.10.0 \
uritemplate==3.0.0 \
requests\
cython\
pandas\
scikit-image\
pillow

2. Tensorflowをインストールします。

3. 任意の場所にDataSetMake_tfwiter.pyおよびpix2pix_multi.pyを配置する。

以上で、インストールは完了です。


実行方法


地図タイル取得先URLの設定方法

まず、地図タイルを取得するURL指定するファイルをJSON形式で作成します。作成するJSON形式ファイルの内容は以下の通りです。

{

"targetURL": 教師データとなる地図タイルの取得先
,
"inputURL": [
入力データとなる地図タイルの取得先1
,
入力データとなる地図タイルの取得先2
]
}

変数
説明

"targetURL"
教師データとなるタイルの取得先URL

"inputURL"
入力する地図タイルの取得先URL。[]の中に取得先をカンマ(,)区切りで複数指定することができます。

教師データと入力データそれぞれの地図タイル取得先を設定します。地図タイル取得先の設定については以下を参照してください。

{

"url": 地図タイル取得先のベースURL ,
"type": 取得する地図タイルの種類 ,
"format": 取得する地図タイルの形式
}

変数
説明

"url"
地図タイルの取得先のベースURL

"type"
取得する地図タイルの種類。地図タイル形式やWMTSは"tile"、WMSは"wms"になります。

"format"
拡張子やタイル座標、WMTS やWMSのパラメータなどの設定。詳細については下記の各タイル取得設定例を参照してください。


タイル地図形式の地図タイル取得先設定例(国土地理院 全国最新写真(シームレス))

{

"url": "http://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/",
"type": "tile",
"format": "{z}/{x}/{y}.jpg"
}


  • タイル地図形式の"format"では主としてタイル座標と拡張子やWMTSのパラメータ等を設定します。取得先の形式に従って設定してください。

  • タイル座標については以下のように記述してください。


    • {z} : ズームレベル、{x} : タイルのX座標、{y} : タイルのY座標




WMS形式の地図タイル取得先設定例(地震ハザードステーション 地すべり地形分布図WMSサービス)

{

"url": "http://www.j-shis.bosai.go.jp/map/wms/landslide?",
"type": "wms",
"format": "SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX={minx},{miny},{maxx},{maxy}&CRS=EPSG:4612&WIDTH={output_width}&HEIGHT={output_height}&LAYERS=L-V3-S300&FORMAT=image/png&TRANSPARENT=FALSE"
}


  • WMS形式の"format"ではWMSのパラメータ設定を行ないます。取得先の形式に従って設定してください。

  • WMSのパラメータの中で取得範囲指定を行なうBBOX、取得する画像のサイズを指定するWIDTH、HEIGHTについては以下のように記述してください。
    ~~~
    BBOX={minx},{miny},{maxx},{maxy}
    WIDTH={output_width}
    HEIGHT={output_height}
    ~~~


学習用データセットの作成

学習用データセットに使用するDataSetMake_tfwiter.pyの実行形式およびパラメータは以下の通りです。

python DataSetMake_tfwiter.py "images_x_start" "images_x_end" "images_y_start" "images_y_end" "zoom_level"

--inputJson "INPUTJSON"
--outputPath "OUTPUTPATH"

引数
説明

"images_x_start"
指定する範囲の始点となるタイルのx方向の位置

"images_x_end"
指定する範囲の始点となるタイルのx方向の位置

"images_y_start"
指定する範囲の始点となるタイルのy方向の位置

"images_y_end"
指定する範囲の終点となるタイルのy方向の位置

--inputJson "INPUTJSON"
地図タイル取得先URLを設定したjson形式のファイルを指定します。デフォルトは"./jsonSample.txt"

--outputPath "OUTPUTPATH"
データセットの出力先ディレクトリの指定。ディレクトリがない場合は自動生成します。デフォルトは"Data"


  • 実行中はタイルの取得先URLと入力データのチャンネル数(input channel)、教師データのチャンネル数(target channel)等が表示されます。各チャンネル数は pix2pix_multi.py 実行時に入力するので確認するようにしてください。

  • 実行後、--outputPathで指定したディレクトリ内に{通し番号}.tfrecordsが取得したタイルの枚数分生成されます。また、プログラムを実行したディレクトリ内に取得したタイルを繋げた、input_image{通し番号}.png、target_image{通し番号}.pngが生成されます。


学習用の実行

学習の実行に使用するpix2pix_multi.pyの実行形式および主なパラメータは以下の通りです。

pix2pix_multi.py  --input_dir "INPUT_DIR" 

--mode {train,test,export}
--output_dir "OUTPUT_DIR"
--checkpoint "CHECKPOINT"
--max_steps "MAX_STEPS"
--max_epochs "MAX_EPOCHS"
--progress_freq "PROGRESS_FREQ"
--save_freq "SAVE_FREQ"
--ngf "NGF"
--input_ch "INPUT_CH"
--target_ch "TARGET_CH"
--GPUdevice "GPUDEVICE"

変数
説明

--input_dir
学習用データセットがあるディレクトリ。

--mode
プログラムの実行モード。学習をする際には、"train"を指定。

--output_dir
モデルの出力先ディレクトリ

--checkpoint
読み込む学習済みモデルがあるディレクトリ。指定しない場合、新規で学習を行なう。

--max_epochs
学習回数

--progress_freq
学習時に学習状況を表示するステップ数。デフォルトは50

--save_freq
モデルを保存するステップ数。デフォルトは100。

--ngf
生成器の第一層のフィルター数。デフォルトは64。

--ndf
判別器の第一層のフィルター数。デフォルトは64。

--input_ch
入力データのチャンネル数。デフォルトは4。

--target_ch
教師データのチャンネル数。デフォルトは4。

--GPUdevice
実行するGPUの番号を指定します。デフォルトは0。複数のGPUがあるマシンを使用する場合に任意のGPUを指定して実行します。GPUがない場合はCPUを使用して実行されます。


  • 実行中に--save_freqで指定したステップごとに指定した保存先に学習モデル model-{ステップ数}.data -00000-of-00001、model-{ステップ数}.index、model-{ステップ数}.meta が出力されます。


参考

この学習プログラムは、pix2pix-tensorflowを基に作成しています。学習プログラムの詳細については基となったプログラムの配布ページを参照してください。

また、今回のサンプルはlad2vegにアップロードしてあります。