dockerでOpenSfMを動かす

#はじめに
　mapillary社が公開している、複数の静止画から３D点群を作成するOpenSfMについて紹介します。[Github](https://github.com/mapillary/OpenSfM "mapillary/OpenSfM")にはMac OSへのインストール方法が紹介されております。今回はdockerを使ってOpenSfMを動かす方法についてまとめてみます。
　dockerはWindows環境でも動かす事が可能ですので、より多くの方々にOpenSfMを楽しんでもらえればと思います。

#環境構築
##docker toolbox のインストール
 + docker-toolboxの紹介サイト
  英語ですが、docker-toolboxについてのわかりやすい説明があります。
  + Windows https://docs.docker.com/v1.8/installation/windows/
  + Mac OS X https://docs.docker.com/v1.8/installation/mac/
 + インストーラーのダウンロード
  + Windows [v1.9.1c](https://github.com/docker/toolbox/releases/download/v1.9.1c/DockerToolbox-.9.1c.exe)
  + Max OS X [v1.9.1c](https://github.com/docker/toolbox/releases/download/v1.9.1c/DockerToolbox-1.9.1c.pkg) 
 + インストールの注意
  +  Windows はWindows 7 以上が必要です。32bit環境にはインストール出来ません。
  +  インストーラーは200MB程度あります。余裕のあるPCでお試し下さい。
  
##OpenSfMのダウンロード

Githubの[mapillary/OpenSfM](https://github.com/mapillary/OpenSfM)から全てのデータをダウンロードしてください。ZIPアーカイブは[こちら](https://github.com/mapillary/OpenSfM/archive/master.zip)からもダウンロード可能です。
ダウンロードしたら解凍して下さい。

##Dockerの起動
docker-toolboxをインストールすると、Docker Quickstart Terminal とKinematicの２つのアプリケーションがインストールされます。

<img width="322" alt="スクリーンショット 2015-12-10 19.59.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/53918/a4b6c911-349b-9b4a-e980-6a39b4a109f0.png">

###Kinematicの立ち上げ

Kinematicのアイコンを選択して起動します。
起動すると下記のようなウインドウが開きます。
<img width="682" alt="スクリーンショット 2015-12-10 20.54.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/53918/a3b71f33-3527-8358-c2ba-1dbd23f3d8c6.png">

dockerにはDocker Hub というコンテナを共有するWebサービスがあり、自由にダウンロードしてそのまま実行することが出来ます。しかし、現時点では、検索フォームにOpenSfMと入力してもヒットしなかったので、Docker HubにはOpenSfMのコンテナは存在しないようです。

###DockerfileからDockerイメージの作成

GithubからダウンロードしてきたZIPにはdockerコンテナのイメージを作成するためのdockerfileがあります。
dockerfileは環境構築のレシピのようなもので、ビルドすると実行可能なdockerイメージが作成されます。

+ DOCKER CLIの起動
 + Kinematicsの左下の「DOCKER CLI」をクリックしてターミナルを起動します。
 
+ unzipしたOpenSfMのディレクトリに移動

```sh:
$ cd opensfm_tools-master
```

+ Dockerfile のビルド（数十分程度かかります）
 
```sh:
$ docker build -t opensfm:1.0 .
``` 
   docker build : イメージのビルドを実行する
   -t　: リポジトリ名とタグ名をつけるオプション
   opensfm:1.0 : イメージ名：タグ名
   . : Dockerfileの存在するファイルパス

膨大なメッセージが出力されますが、最後に「Successfully built ... 」が表示されれて完了します。

```shell-session
Removing intermediate container f389b732eae4
Step 6 : WORKDIR /
 ---> Running in 260d4f4d1f36
 ---> 60d1e04fe240
Removing intermediate container 260d4f4d1f36
Successfully built 60d1e04fe240
``` 

+ docker imageの確認
    + docker images コマンドでdocker内部のdockerイメージの一覧を取得します

```sh
$ docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
opensfm                       1.0                 60d1e04fe240        18 minutes ago      1.022 GB
ubuntu                        14.04               89d5d8e8bafb        43 hours ago        187.9 MB
```

ビルドしたイメージと同一の名称(今回は「opensfm」）があれば成功です。

### OpenSfMコンテナの起動

docker run コマンドでopensfmイメージを起動します。

#### docker とのファイル共有
コンテナ内部の環境と、PCのディレクトリを共有するために -v オプションでマウントします。

 -v PCのディレクトリパス:dockerコンテナのディレクトリパス

#### docker とのポートフォワード
コンテナ内部と通信するために、PC側のポートとコンテナ側のポートとの接続設定を -p オプションで設定します。

 -p PCのポート番号:dockerコンテナのポート番号

```sh
$ docker run -i -t -d -p 8080:8000 -v /Users/myname/tmp:/mnt/common opensfm:1.0 /bin/bash
```

dockerコンテナが起動すると、Kinematicの左側のタブに表示されます

<img width="754" alt="スクリーンショット 2015-12-10 23.08.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/53918/ca9718a5-504f-3d91-3092-2ede49fdea2c.png">

起動中のコンテナを選択すると、コンテナの情報にアクセス可能です

![スクリーンショット 2015-12-10 23.14.00.png](https://qiita-image-store.s3.amazonaws.com/0/53918/0e723baa-77b6-139a-42ed-dc81d69dc51d.png)

コンテナ接続用のIPアドレスとポート番号

+ SettingタブをクリックするとIPアドレスとポート番号の確認が出来ます。

<img width="596" alt="スクリーンショット 2015-12-11 0.30.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/53918/71f418d0-fc28-9b13-d1b9-d6ba010d2210.png">

上記では、IPアドレス 192.168.99.100 のポート番号 8080でアクセス可能であることが分かりました。実行環境によってはIPアドレスが異なる場合がございます。

これで環境構築が完了ですお疲れ様でした。

#OpenSfMの利用
dockerコンテナとして動作しているOpenSfMを動かしてみます。

 + excecボタンをクリックし、コンソールの起動します
  <img width="61" alt="スクリーンショット 2015-12-10 23.24.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/53918/daa1ee7e-6cc7-7fa7-b873-c4b46ee7fc50.png">

##ビルド
OpenSfMのソースが存在するディレクトリに移動します。

```sh
$ cd /source/OpenSfM
```

ビルドスクリプトの実行

```sh
$ python setup.py build
```

##実行
###ファイルの準備
OpenSfMでは、EXIF領域に緯度経度が記録されている複数のjpeg画像と、実行スクリプトの設定用のファイルが必要です。

 + ファイル構成

DATASET_NAME (フォルダ)
 ├ config.yaml
 └ images (フォルダ)
　　├ img1.jpg
　　├ img2.jpg

config.yaml は、ダウンロードしたZIPの中に保存されております。
imagesフォルダの内部の画像ファイル名称はなんでも構いません。
DATASET_NAME を「test1」とすると以下の様なパスになります。

PCのパス : /Users/myname/tmp/test1
コンテナ内部のパス : /mnt/common/test1

### 実行

上記のフォルダ名の例では下記のような実行コマンドになります。

```sh
$ bin/run_all /mnt/common/test1
```
### サンプルの実行
EXIF画像が手元にない場合は、デモ用の画像を用います
デモ画像は、/source/OpenSfM/data/lund

```sh
$ bin/run_all data/lund
```

### webサーバの起動

```sh
$ python -m SimpleHTTPServer
```

### webブラウザで確認
環境構築時に確認した接続用のIPアドレスとポートを確認しWebブラウザにアクセスします。

http://コンテナのIP:8080/viewer/reconstruction.html#file=/data/lund/reconstruction.meshed.json

<img width="755" alt="スクリーンショット 2015-12-11 0.36.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/53918/b9bf9f45-80f3-0e34-0eb2-4ae748a3cc66.png">

SfMができました！

#まとめ
dockerを用いてOpenSfMを動かしてみました。
ご利用のPCの中にコンテナという一種の仮想マシンを立てることで、環境構築の自動化を実現しました。dockerは慣れるまでとっつきにくく感じられることも多いかと思います。しかし、世界の人達と実行環境を共有を可能にするコンテナ技術は、最新技術の実行環境の迅速に構築する事が出来ます。