（初心者むけ）OpenDroneMapを使ってDSMと点群データ（LAS形式）をつくる

# はじめに
## 目的
ドローン等の画像から、DSMや点群データを作成したいと思い、オープンソースソフトウェアのOpenDroneMapを使ってデータ作成の実験をしてみました。結果をここにメモします。

（今後、作成した点群データ（LAS）を使って、UNVTのVoxel Tileを作ってみたいのですが、そのための第一歩です。）

## 参考にしたもの
この実験をするにあたり、2020年11月に実施されたUN Open GISイニシアチブのODMワークショップに参加した経験を活用しました。（ありがとう UN Open GIS）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/86009bfd-63c0-5db0-0106-633478e3bdd4.png)

## 環境
### 私の環境
* Windows 10 Enterprise
* Docker Desktop (Docker version 20.10.8)
* Powershell
* git version 2.25.0.windows.1

### 推奨環境
#### ミニマムの場合
2020年11月時点では以下のような環境が最低限必要とされていました。ただし、以下は100-200より少ない画像処理向けです。
* 2010年以降につくられた64bit CPU
* 20GBのディスクスペース
* 4GBのRAM

#### 推奨される環境
2020年11月時点での推奨環境は、
* 最新世代のCPU
* 100GBのディスクスペース
* 16GBのRAM
とのことでした。当時は、Graphics card（GPU）は処理に影響を与えない一方で、CPUのコア数が増えるとよいということを説明されていました。

以下にODMの文書がありますが、上記の奨励環境は2022年8月現在も同じようです。処理したい画像数とメモリの関係などは、以下の文章を参照しましょう。

https://docs.opendronemap.org/installation/

# 手順
## Step 1. 準備
### 1-0. PythonとDockerの準備
この記事では説明しませんが、Python 3.x と Dockerをインストールしておくことが必要です。

### 1-1. メモリとCPUアロケーションのチェック
Dockerの設定メニューからメモリとCPUの設定をします。前述の推奨にしたがって、以下のような割り当てにしてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/941cea32-6de6-09ff-ea34-79254788a071.png)

### 1-2. WebODMのインストール
多分WindowsでもWSLなどを使えばコマンドラインので全部できると思うのですが、ワークショップではGit Guiからインストールしていたのでそのようにします。Clone Existing Repository　のメニューから、クローンします。ソースは https://github.com/OpenDroneMap/WebODM で、保存先も適切に指定します（下図）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/c3ebe4ca-aea5-e6d2-1169-9831e4fbead1.png)

クローンができると、以下のようになります。RepositoryメニューからCreate Desktop Iconを実行しておくと、後で便利とのことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/be18e50e-7baa-6fb9-1ff4-a7c2971ee18c.png)

### 1-3. WebODMの起動
Git GuiのRepositoryメニューから、Git Bashをクリックします。そして以下のコマンドを実行します。
```
./webodm.sh start&
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/f8cf90f2-9134-b45d-1e7c-b52a9688b0d6.png)
これを実行すると、WebODM、NodeODEM、ODMなどがダウンロードされるそうです。

Docker for Windows を使っているので、このあと、http://localhos:8000 を開いてみるとよいそうです。Docker toolboxを使っていてIPがわからないときは、以下のコマンドでIPがわかるので、そのIPアドレスの8000番ポートにhttpでアクセスするといいそうです。

```
docker-machine ip
```
### 1-4. WebODMにアクセス、管理者アカウント作成
localhostにアクセスすると、お祝いの紙吹雪が舞っており、adminユーザーの名前とパスワードを作るように言われます（下の図）。また使うこともあるので、忘れないようにしましょう。（忘れたらbashで ./webodm.sh resetadminpassword newpassword をすれば大丈夫。ユーザー名も確認できます。）
![2022-08-22-ODM-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/39913d09-62d5-7c7f-219d-d45a990afa26.png)

そうすると無事にここまで来られます。
![2022-08-22-ODM-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/7c425b60-8423-b87b-cfa4-c1b6a32f812e.png)

### （参考）Macなら・・・
Windowsだとshを実行できないので、Git Guiのbashを使うのですが、MacやLinuxなどのshファイルを実行できる環境ならば、所定のディレクトリで以下を実行すればよいと思います。

```
git clone https://github.com/OpenDroneMap/WebODM
cd WebODM
./webodm.sh start
```

ちなみに、Linuxの人は、Docker、Git、Python、Pipがインストールされていることが必要ということでした。

## Step 2. 画像処理
### 2-1. 画像の準備
ドローンの画像でも、航空写真でも処理したい画像を準備します。ワークショップでは以下のように説明されていました。
* 高度は解像度が十分あるという前提で、高いほうがよいということです。（もちろんルールの範囲内で）
* カメラの角度は、すべての写真で多少の角度（10度）があるほうがよく、Nadir（直下視）ではないほうがよい。
* 理想的には前後に85％以上のオーバーラップ、サイドに70%以上のオーバーラップがあるとよい。
* フライトの速度は可能な限りゆっくりがよい。

データセットについては、テストデータセットが以下のレポジトリにあるそうなので、今回はそれを使います。ダウンロードしたものを解凍しておきます。
https://github.com/pierotofy/drone_dataset_brighton_beach/archive/master.zip
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/d6b06833-03cc-518f-2ac6-cced26c2e4ee.png)

なお、ここの画像には撮影位置（GPS）が入っていました。ジオレファレンスをするときに大切なので、画像の撮影位置があるか、GCPを指定した座標をつかうのか、あるいは座標情報がないもので処理を進めるのかよく確認しておきましょう。（私は地図座標情報がない画像でまず実験してみようと思って処理したら、位置情報がついていたので撮影位置が入っていたのだと気がついた。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/29c61a97-6c3f-32ec-8156-4167c76e1420.png)

### 2-2. 新規プロジェクトの作成
Add Projectボタンを押して、New Projectを作ります。今回は、ODM-001という名前で作ってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/8f19f363-c587-a964-4b3c-fe1124463fd0.png)

### 2-2. 画像の指定と処理の実行
プロジェクトが新たにできるので、そのSelect images and GCPを選びます。今回使った画像には、撮影位置（緯度経度と高さ）が入っているので、ここでGCPがなくても大丈夫とのことです。そして、画像ファイルを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/b6e1f9fe-5206-30e9-2830-273b22080087.png)

画像を選んだあと、オプションの設定ができます。ここではデータの名前をsample dataにしています。Optionのところで、DEMが欲しいときは「DSMとDEM」を作るようにしてもよいそうです。リサイズについては、このくらいのファイル数ではNoのままでも大丈夫ということなのでそのままにします。設定を確認するためにReviewボタンをおして、そのあとの画面でStart Processingを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/5d387d0b-c460-a229-1b6e-e8e43bfee56f.png)

すると処理が始まって、以下のような画面になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/6d808d2c-bf3d-bdcb-433e-7ee329523bd5.png)
処理が終わると以下のような画面になりました。時間を計るのを忘れましたが、今回は15分くらいで処理できたと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/8eb1f929-046d-d601-0be5-da3246a8c21e.png)


### 2-3. 成果の確認
まずView Mapをクリックしてマップを見てみます。右下のボタンで2Dと3Dの切り替えもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/23715d52-616b-caf5-7e08-22170d771349.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/143cfbe7-a035-adec-fbd8-2e524a5384da.png)

Georeferenceされた画像になっていますね。

## 2-4. 成果のダウンロード
Download Assetsのボタンから、ダウンロードしたいものを選びます。このボタンが見つからない場合は、Dashboardに戻って、プロジェクトのTasksをクリックして一覧を出したあと、必要なデータのチェックボタンをクリックすると下の図のように画面が開きます。
今回はPoint Cloudを選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/e1517e20-2167-c906-5b20-202e6d526c0c.png)

今後、Voxel Tilesにすることを考えて、ウェブメルカトル図法とLAS形式でダウンロードすることにします。オプションを指定したらダウンロードボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/3bad7150-906a-8d81-0eb8-8136bf6990d3.png)

もちろん、オルソ画像なども選べます。これで私がほしいデータをダウンロードできました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/3515bab3-88e9-82f8-2253-8d621e7c40ec.png)


# まとめと考察
以上で、撮影位置の入っている画像18枚からDSM、オルソ画像、点群データなどを得ることができました。

# （考察）ジオレファレンスについて

ODMでは、ジオレファレンスするための方法は2つあるそうです。一つは、画像のGPS情報をつかうことで、もう一つは画像にGCPを付加する方法だそうです。以下に細かく書きますが、ODMユーザーは、GPS情報を使って処理して、必要に応じてODMの外でデータのオフセットを調整する利用ケースが多いのかなと思いました。

## 画像のGPS情報で処理する場合
ドローン画像の撮影時のGPS情報を使う方法です。今回の手順でも画像のGPS情報を使って位置合わせがされています。ODMはドローン向けの処理ツールということもあり、こちらの方が利用されているケースが多いのかなと感じます。もともとの画像に情報がついていることもあり、下処理もさほど必要にならないと思います。
ただ、この方法だと、座標系や測地系が問題になるということも紹介されていました。例えば、デフォルトのWGS84などでは、アフリカのある地域のローカル座標系にあわずに対象地域が海面下になってしまったとのことです。話のなかで、ODMで作ったデータを外で使う際に最終的な調整を行うという経験も紹介されており、ODMでは測地系の中での絶対座標の精度というよりは、それぞれの地物の相対的な精度を求めているのだろうなと感じました。
（つまり使うときには多少のオフセットの調整が必要になる場合が多いかもしれません。）

## 画像をジオレファレンスして使う場合
画像を入力するときに、画像中のGCP情報を一緒に入れる方法です。ODMにもGroupd Control Pointsのインターフェースがあるので、それを使ってGCP情報を入れられるとのことです。インターフェースは対話式とのことなので、それなりの数の画像で作業すると結構大変そうです。ほかのソフトでテキスト形式のＧＣＰ情報を準備することが必要になるかなと思います。
GCPを正確に測量しておけば、この方法ではそれなりの精度が得られるのではないかと思うのですが、一方で、ODMの多くのユーザーはこの方法をとらないので、GCPインターフェースはまだ使い勝手が十分よくないというような話もありました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/8bed954e-dc80-3039-9b24-00778c0b0a51.png)


# 謝辞
UN Open GIS のワークショップで講師をしてくれたStephen Mother, India T. Johnson, Corey Snipesに心より感謝します。


# 参考ページ
https://docs.opendronemap.org/

http://unopengis.org/unopengis/main/main.php