Windows 10でWebODMを動かしSfMの点群データ・オルソモザイク画像を生成する

# はじめに
ドローンで撮影した大量の画像を入手いたしました。

撮影画像をつなぎ合わせてデジタル3Dモデルを構築する、いわゆるSfM (Structure from Motion) 処理を行うためには、一般的にはスイス[Pix4D](https://pix4d.com/jp)社の[Pix4D Mapper](https://www.pix4d.com/jp/product/pix4dmapper-photogrammetry-software)などが利用されています。しかし、メジャーなSfMソフトウェアは大変高額であり、フリーソフトでデジタル3Dモデルを構築できないか挑戦してみました。
# Open Drone MapとWebODM
SfMを行うために、[Open Drone Map](https://www.opendronemap.org/)、そしてそのUIである[WebODM](https://www.opendronemap.org/webodm/)といったソフトウェアが無料で利用できます。今回はこのWebODMをインストールします。
# Docker Desktop for Windowsの利用
WebODMを動作させるためには、[Docker](https://docker.com)コンテナ環境の導入が必要になります。

従来DockerをWindows OSで動かすためには、Windows 10 ProなどHyper-Vハイパーバイザを利用できるOSバージョンの利用が必要でした。Windows 10 HomeではHyper-Vが使えないため、代替策として[Oracle VM Virtualbox](https://www.virtualbox.org/)などの仮想化ソリューションとDocker Toolboxとの組み合わせを利用するなどが用いられていたようです。

しかし今年に入って、Windows 20H1(2004)バージョンからWSL 2 (Windows Subsystem for Linux 2) 仮想化環境が利用できるようになりました。このWSL2環境を導入することで、Windows 10 Home環境でもDocker ToolboxではなくDocker Desktop for Windowsを動作させられるようになります。

2019年頃に書かれたドキュメント類には、Docker Toolboxの利用について解説してある記事などが多く、WSL2によるWebODM環境の構築を説明したページを見つけることができませんでしたのでこのエントリを書くことにしました。Docker Toolboxはすでに開発を終えているので、本手順での環境構築をおすすめします。

# 導入手順
## Windows 10にWSL2を導入する 
- BIOS(UEFI) の設定で、仮想化支援機能であるIntel VTやAMD-V機能が有効化されていることを確認します。
- Docker ToolboxやVirtualBoxが入っていたらアンインストールします。
- [WSL2](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)をインストールします。ディストリビューションには、Ubuntu 20.04 LTSを選択しました。念の為 `% sudo apt update && sudo apt upgrade `でシステムを最新化しておきましょう。

## Docker Desktop, Git, Python3のインストール
下記のWindowsアプリケーションをインストールします。
- [Docker Desktop for Windows](https://hub.docker.com/editions/community/docker-ce-desktop-windows/)
- [Git Gui Client](https://git-scm.com/download/win)
- [Python 3.9.0](https://www.python.org/downloads/release/python-390/) Add Python 3.9 to PATHにチェックします。

## WebODMのインストール
WebODMの[Installation and Getting Started](https://docs.opendronemap.org/installation.html)に従ってインストールしていきます。
- Git Guiを開き、Clone Existing Repositoryを選択します。
- Source Locationに、https://github.com/OpenDroneMap/WebODM と入力します。
- Target Directoryにて、ターゲットフォルダを指定します。![pic3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157684/20a26554-a3c7-b8bf-3bf8-46940f3a0c1c.png)
- Cloneを選択します。
- Repository menuからCreate Desktop Iconを選択してデスクトップアイコンを作ります。

#WebODMを使う
- Git GuiのRepository menuから、Git Bashを選択します。
- 表示されたBashターミナルに`$ ./webodm.sh start&`と入力してWebODMをスタートさせます。初回起動時には、不足しているソフトウェアのインストールが自動的に行われます。![pic4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157684/645022a3-e881-348d-2419-d1853a3d1219.png)
- ブラウザを開き、http://localhost:8000 を開きます。
- ユーザ名とパスワードを入れると、WebODMの管理画面になります。![pic11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157684/6fd10898-0207-bc81-3408-b02e947ce6eb.png)
- 撮影画像を読み込ませると、点群データやオルソモザイク画像などを出力できるようになります（下の画像は点群データではなく、モザイク処理を施してあります）。
![pic17-s.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157684/fe0f7b52-44c1-888e-9d1f-df78b8c630fa.png)
- WebODMを終了する際は、`./webodm.sh stop`と入力します。

##追記1：仮想ディスクの場所を変更する
データ処理の途中で起動ドライブであるSSDが溢れてしまったので、対処します。

Docker Desktop for Windowsでは、標準ではCドライブに仮想ディスク領域（.vhdx形式）を作成しますが、これを別の物理ディスクであるDドライブ（HDD）に移動します。

- Docker Desktopのタスクトレイ アイコンからQuit Docker Desktopを選びDockerを停止させます。
- Windows PowerShell（管理者モード）にて下記コマンドを実行し、ディスクを移動させます。

```
> wsl --shutdown 
> wsl --export docker-desktop-data D:\opt\Docker\docker-desktop-data.tar
> wsl --unregister docker-desktop-data
> wsl --import docker-desktop-data D:\opt\Docker D:\opt\Docker\docker-desktop-data.tar
```
##追記2：仮想ディスクを圧縮する
PowerShellで作業します。デフォルトでは仮想ディスクはホームディレクトリのAppData配下にあります。

```
> wsl --shutdown 
> diskpart
DISKPART> select vdisk file ="C:\Users\Username\AppData\Local\Docker\wsl\data\ext4.vhdx"
DISKPART> compact vdisk
```

##追記3：他のマシンからアクセスできるようにする
WebODMを動かしているマシンに、LAN内の他のマシンからウェブブラウザ経由でアクセスすることができます。もちろんファイアウォールやIPアドレスを適切に設定すれば、外部からアクセスさせることも可能です。


- Windows Defender ファイアウォールで、詳細設定→受信の規則→新しい規則… を選択
- プライベートネットワークで、TCP ポート8000を設定
![2020-11-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157684/46257530-08fc-c623-bb9d-817ca5301dab.png)

- 下記の内容でバッチファイル(.BAT) を作成します。画面例ではSSHなども通せるように、ポート8000以外の転送設定も行っています。

```
wsl -d Ubuntu -u root exec service ssh restart
for /F %%i in ('wsl -d Ubuntu exec hostname -I') do set ip=%%i
netsh interface portproxy delete v4tov4 listenport=22
netsh interface portproxy delete v4tov4 listenport=80
netsh interface portproxy delete v4tov4 listenport=3000
netsh interface portproxy delete v4tov4 listenport=8000
netsh interface portproxy add    v4tov4 listenport=22 connectaddress=%ip%
netsh interface portproxy add    v4tov4 listenport=80 connectaddress=%ip%
netsh interface portproxy add    v4tov4 listenport=3000 connectaddress=%ip%
netsh interface portproxy add    v4tov4 listenport=8000 connectaddress=%ip%d

```

- 作成したバッチファイルを管理者権限で実行すれば、http://(マシンに割り振られたIPアドレス):8000 でアクセス可能になります。
- Windowsログイン時に自動実行させたいならば、タスクスケジューラで新規タスク→ ログオン時、遅延時間30秒、最上位の特権で動作させるようにします。
![2020-11-24 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157684/7397c433-0fc3-ea23-6183-a8b83d269e8f.png)