【旧版】mapillary_tools を使ってアクションカムで撮った写真をMapillaryに投稿する

## この記事の内容は古くなっています
2018年5月に mapillary_tools にメジャーバージョンアップがあり、最新版は使い方が大きく変わっています。GPX以外の位置情報を取り込めたり、動画から静止画を切り出してアップロードまで自動化できるようになりました。新しいバージョンの使い方は[こちら](https://qiita.com/kudarisenmon/items/e1c0c9fc439dd5ec5a11)です。

[Mapillary](http://www.mapillary.com/map) はストリートビューをクラウドソーシングで作るサービスです。通常はスマートフォンのアプリを使って撮影したものを共有するのですが、GPSロガーで取ったログとアクションカムやデジカメのタイムラプスモードで撮影した静止画を合わせてスクリプトで一括アップロードできます。
日本には美しい四季がありますので、皆さんの身近な場所や旅行先でたくさん撮って共有してください。Mapillaryのストリートビューは [OpenStreetMap](https://www.openstreetmap.org/) の編集にも使えますので自由な地図の充実にもつながります。

## タイムラプス撮影とGPSログについて
私はGoPro Hero3 Silver Editionを使っています。3,680×2,760ピクセルでインターバル2秒で撮影しています。自動車につけて撮影する場合、流れの速い道路ではSDカードの容量が許せばインターバルは1秒のほうがいいかもしれません。
GoPro以外のカメラでも１秒または２秒間隔で静止画のインターバル撮影ができるものなら同じ要領でできると思います。
GPSロガーはGPX形式が出力できるものであればどんなものでも良いと思います。私は GARMIN fenix を使っています。ログの取得間隔を撮影間隔より短くしておきます。

## 動作環境
Linux Mint 18 Sarah(Python 2.7.12)で動かしてます。たぶんDebian、Ubuntuも似たようなものと思います。
MacOSXの上でのインストール方法は[公式ドキュメント](https://github.com/mapillary/mapillary_tools/blob/master/python/README.md)に書かれています。

```
$ cat /etc/issue
Linux Mint 18 Sarah \n \l
$ python --version
Python 2.7.12
```

## 環境構築
必要なパッケージをインストールしてから、GitHub からブランチ指定して mapillary_tools の旧版をクローンします。

```
$ sudo apt-get install git python-pyexiv2 python-pip python-exif python-pil python-dateutil python-setuptools
$ mkdir ~/src
$ cd ~/src
$ git clone -b add_extra_MAPdata https://github.com/mapillary/mapillary_tools.git
```

#### Python の依存ライブラリをビルド・インストール

```
$ sudo pip install -r requirements.txt
```

#### 環境変数設定スクリプトを作成
スクリプトが動作するために必要な環境変数をセットするスクリプトを作成します。

```
$ mkdir ~/bin
$ vi ~/bin/mapillary.sh
```

##### 環境変数設定シェルスクリプトの内容
| 項目 | 設定内容 | 
|:-----------|:------------:|
| MAPILLARY_EMAIL | Mapilarry にログインする時に使っているメールアドレス |
| MAPILLARY_PASSWORD | Mapilarry にログインする時に使っているパスワード |
| MAPILLARY_USERNAME | Mapilarry に登録したユーザ名 |
| MAPILLARY_PERMISSION_HASH | [Manual Uploads](http://www.mapillary.com/map/upload/im) のページ下部にある値を写す |
| MAPILLARY_SIGNATURE_HASH | [Manual Uploads](http://www.mapillary.com/map/upload/im) のページ下部にある値を写す |

```sh:mapillary.sh
export MAPILLARY_EMAIL="hogehoge@example.com"
export MAPILLARY_PASSWORD="yourpasswd"
export MAPILLARY_USERNAME="下り専門"
export MAPILLARY_PERMISSION_HASH="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export MAPILLARY_SIGNATURE_HASH="xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

#### アップロードしない重複した写真の置き場所を用意
remove-duplicates.py のヘルプにかかれていますが、アップロードスクリプトはディレクトリを再帰的に処理するため、重複した写真の置き場はアップロード対象ディレクトリの上位に置く必要があります。

```
$ mkdir ~/duplicate
```

### ディレクトリ構成(例)

```/home/kudarisenmon
├── bin
│   └── mapillary.sh
├── duplicate
├── mapillary
│   ├── 108GOPRO
│   │   ├── G0069921.JPG
│   │   ├── G0069922.JPG
│   │   ├── G0069923.JPG
│   ～～～（省略）
│   │   └── G0069998.JPG
│   └── 2016-04-09_150103.gpx
├── src
│   └── mapillary_tools
│       ├── README.md
│       ～～～（省略）
```


## Mapillaryに必要な情報を付与してアップロードする手順
環境構築後、次回はここから実行すればOKです。3ステップです。

####  環境変数を読みこむ
.bash_profile で設定するようにしてしまえば毎回実行する必要ありません。

```
$ source ~/bin/mapillary.sh
```

#### ジオタグを（再帰的に）付与する

```
$ python ~/src/mapillary_tools/python/geotag_from_gpx.py ~/mapillary/ ~/mapillary/2016-04-09_150103.gpx 
```


#### 重複した写真を除外する
クルマに取り付けて信号待ちや渋滞で動いていなかったため同じ場所の写真がたくさん撮れてしまったものを除外します。

```
$ python ~/src/mapillary_tools/python/remove_duplicates.py ~/mapillary/108GOPRO/ ~/duplicate/
```

#### プリプロセスとアップロードを実行する
プリプロセスはグループを分割したり、コンパス（撮影方角）の計算や独自タグの付与をしているみたいです。

```
$ python ~/src/mapillary_tools/python/upload_with_preprocessing.py ~/mapillary/
```

最後に [y] を入力してトランザクションをコミットします。
「Uploads:」の中の「success:」や「failed:」がいつも 0 です。

```
========= Summary of your uploads ==============
Sequences:
  groups:       4
  total:        2037
Uploads:
  total uploads this run: 2037
  total:        0
  success:      0
  failed:       0
==================================================
You can now preview your uploads at http://www.mapillary.com/map/upload/im

Finalizing upload will submit all successful uploads and ignore all failed and duplicates.
If all files were marked as successful, everything is fine, just press 'y'.
Finalize upload? [y/n]: y
```

## スクリプト実行の補足
upload_with_preprocessing.py には --remove_duplicates オプションがあるとドキュメントに書かれているのですが、私の環境ではうまく動作しません。そのため個別に remove_duplicates.py を実行しています。
この remove_duplicates.py の仕様？が微妙な感じで geotag_from_gpx.py と upload_with_preprocessing.py は再帰的に処理してくれるのに対して指定したディレクトリの直下しか処理してくれません。
撮影した枚数が多くてDCIM配下のDCFフォルダが複数にわかれてしまう場合は最初に同じフォルダにまとめるか remove_duplicates.py を複数回実行することになります。
仕様じゃなくて使い方が間違ってる？ようだったら教えてください。

## 中断と再実行、並列処理について
upload_with_preprocessing.py は途中で割り込みで停止して、もう一度実行することで再開（レジューム）できます。
停止後レジュームせずに途中までのデータを削除したい場合はブラウザから [Manual Uploads](http://www.mapillary.com/map/upload/im) にアクセスしてキャンセルできます。
Manual Uploads は一人1セッションまでみたいです。ブラウザからアップロードしているときにアップロードスクリプトを実行したり、アップロードスクリプトを並列で2つ実行することはできないみたいです。