タイムラプス動画ファイルからMapillary用の静止画を生成し、位置情報を付けてMapillaryにアップする手順(まとめ)
動作確認環境:
- Linux MINT 18.3
- Windows 10 HOME エディション
Dockerを利用して説明していますので、LinuxとWindowsの双方で同じ手順で動作します。MacOSでも同じように動作するはずです。
撮影編はこちらを参照 → 「撮影編 Mapillary用のタイムラプス動画を撮影する方法のまとめ」
1. 撮影モードの設定
1.1 タイムラプスモード設定
- 間隔は1秒
GPSロガーのロギング間隔を1秒間に設定するのでそれに合わせてタイムラプスも1秒間隔で撮影する。
最小0.5秒に設定することができるが、切り出したJPEGに撮影時刻を割り当てる際に1秒単位でしか設定することができないため、1秒間隔で十分
1.2 手順概要
動画からMapillaryへアップロードするには、下記のステップ毎の処理が必要
- タイムラプス動画を撮影する
- 動画ファイルから一定間隔の静止画(JPEG)ファイルを生成する
- 生成された静止画ファイルの更新日時を撮影時刻に書き換える
- JPEGファイルの撮影時刻とGPSロガーの時刻情報を突き合わせて JPEGのExif情報に位置情報を書き込む
- カメラとGPSロガーとのタイミング調整を行う
- 不要なイメージを削除する
- Mapillary-toolsを使って Mapillary サイトにJPEGファイルを一括アップロードする。
これらの処理ごとに Java,Pyson,FFMPEG などのソフトウェアのインストールと設定が必要になります。
インストールと設定は、稼働させるOS毎に異なるため、説明が煩雑になるし、それぞれのOS毎の動作検証をすることもできません。
そこで、ここでは Docker を活用しています。
Dockerコンテナ上でシステムを構築して動作検証を行えば、あとはLinuxだろうとMacOSだろうと、なんとWindowsでさえ全く同じ手順で動作させることができます。
個々では Dockerイメージ'haya4/movie2jpg'を使って説明をします。
2. 動画ファイルから一定間隔の静止画(JPEG)ファイルを生成する
撮影された動画ファイルから1秒間隔の静止画を取り出します。
- ソースとなる動画ファイルはタイムラプス撮影されたものに限定されるわけではありませんが、多分動くはずです。他の撮影方法で撮影された動画の動作確認は行っていません。
2.1 Docker 'haya4/movie2jpg' のインストールとビルド
Docker 'haya4/movie2jpg'
初回に限りDockerのインストールとビルドが必要です。
2.1.1 Dockerのインストール
- ここでは Docker についての説明は省略します。各自ネットで調べてください。
- Dockerをインストールしてください。インストール手順はネットで調べてください。
2.1.2 dockerイメージの build
-
Movie2jpg-master.zip をダウンロードして解凍する
フォルダMovie2jpg-master
が作成される -
作成されたフォルダ
Movie2jpg-master
をホームディレクトリ直下に移動する -
Terminal
(Windowsの場合はDocker Quickstart Terminal
)に下記コマンドを打ち込む(build)
cd ~
cd $(pwd)/Movie2jpg-master
mkdir -p mapi
mkdir -p mapi/Movie
mkdir -p mapi/img
cp Movie2jpg.ini mapi/Movie
docker build -t movie2jpg .
小一時間かかります
2.2 動画ファイルのセット
撮影した動画ファイルを所定の場所に配置します。
~/Movie2jpg-master
┃
┗━ ~/Movie2jpg-master/mapi
┃
┣━ ~/Movie2jpg-master/mapi/img
┃
┗━ ~/Movie2jpg-master/mapi/Movie
┃
┣━ Movie2jpg.ini
┣━ XXXX.mp4
┗━ YYYY.mp4
フォルダ ~/Movie2jpg-master/mapi/Movie
に
- **動画(MP4)**ファイルを配置する。
-
Movie2jpg.ini
を配置する。
Movie2jpg.ini の設定例
[FFMPEG]
FFMPEG_OUTPUT_FRAME_RATE=30
- 1.0秒間隔で撮影した場合はFFMPEG_OUTPUT_FRAME_RATE=30 (fps=30) とすると1.0間隔の静止画が取り出せる
2.3 静止画の切り出し処理を実行 - Docker run
実行: Terminal
(Windowsの場合はDocker Quickstart Terminal
)に下記コマンドを打ち込む
cd ~/Movie2jpg-master
docker run -it -v $(pwd)/mapi:/mnt/mapi:rw movie2jpg java -cp .:/root/Movie2jpg.jar:/root/commons-imaging-1.0-20170205.201009-115.jar movie2jpg.Movie2jpg ./Movie/Movie2jpg.ini
実行すると、「Movie2jpg」が起動され、~/Movie2jpg-master/mapi/Movie
フォルダ内の「動画(MP4)」ファイルごとに
ffmpeg -ss 0 -i $(mp4 file) -f image2 -vf fps=$(FFMPEG_OUTPUT_FRAME_RATE) $(output file)
が内部で実行されます。
完了すると、~/Movie2jpg-master/mapi/img
フォルダの下にMP4ファイル名と同じ名前のフォルダが作成され、その中に切り出されたJPEG画像が生成されます。
~/Movie2jpg-master
┃
┗━ ~/Movie2jpg-master/mapi
┃
┣━ ~/Movie2jpg-master/mapi/img
┃ ┣━ XXXX
┃ ┃ ┣━ 00001.jpg
┃ ┃ ┣━ 00002.jpg
┃ ┃ ┣━ :
┃ ┃ ┗━ 01861.jpg
┃ ┃
┃ ┗━ YYYY
┃ ┣━ 00001.jpg
┃ ┣━ 00002.jpg
┃ ┣━ :
┃ ┗━ 02408.jpg
┃
┗━ ~/Movie2jpg-master/mapi/Movie
┃
┣━ XXXX.mp4
┗━ YYYY.mp4
3. 連番JPEGファイルに撮影時刻を割り付ける
生成された連番JPEGファイルに撮影時刻を書き込む必要が有ります。
私の自作したソフトウェア Restamp(Movie2jpg) を使って連番JPEGのファイル更新日時を撮影時刻に変換する方法を紹介します。
3.1 仕組み/原理
- 一定間隔で撮影された連番ファイルの任意の2枚の撮影時刻を設定します。
- 2枚の中間にあるファイルの数を数えて、各ファイルの撮影間隔を精確に算出します。
- 算出された撮影間隔と2枚の撮影時刻を元に、他のすべての撮影時刻を算出し、JPEGファイルのファイル更新日時(updatetime)を撮影時刻に書き換えます。
もし、カメラの時刻合わせに失敗していたり、時間ウォーターマークを設定し忘れた場合は、撮影時刻推定方法 を参照してください。
時間ウォーターマークが設定されている場合は、下記の方法で抽出されたイメージファイルに撮影時刻を設定することができます。
3.2 時間ウォーターマークを使ったファイル更新日時の再設定
-
同様にして、もうひとつの別の画像のウォーターマークを読み取る(最後の方のファイルを選択する)
-
コマンドラインを作る
コマンドライン:
(1) 冒頭
「docker run -it -v $(pwd)/mapi:/mnt/mapi:rw movie2jpg java -cp .:/root/Movie2jpg.jar:/root/commons-imaging-1.0-20170205.201009-115.jar osm.jp.gpx.Restamp
」
固定文字列
(2) ディレクトリ
連番ファイルが格納されたディレクトリ
例:「./img/20180407_135053A
」
(3) 最初の方のファイル名 と 撮影日時
ファイル名
と 撮影日時
「撮影日時」は書式 yyyy-MM-dd'T'HH:mm:ss'Z'
として9時間前の時刻を入力する(例: 2018-05-13T04:29:16Z
)
例:「00239.jpg 2018-04-07T05:54:47Z
」
(4) 最後の方のファイル名 と 撮影日時
ファイル名
撮影日時
「撮影日時」は書式 yyyy-MM-dd'T'HH:mm:ss'Z'
として9時間前の時刻を入力する(例: 2018-05-13T04:29:16Z
)
例:「01725.jpg 2018-04-07T05:19:36Z
」
cd ~/Movie2jpg-master
docker run -it -v $(pwd)/mapi:/mnt/mapi:rw movie2jpg java -cp .:/root/Movie2jpg.jar:/root/commons-imaging-1.0-20170205.201009-115.jar osm.jp.gpx.Restamp ./img/20180407_135053A 00239.jpg 2018-04-07T05:54:47Z 01725.jpg 2018-04-07T05:19:36Z
ターミナルにコマンドラインを貼り付けて実行すると、JPEGファイルのファイル更新日時が「撮影日時」に書き換わります。
4. GPSログとJPEGの更新日付を付きあわせてJPEGのEXiFに位置情報を書き込む
撮影日時がファイルの更新日時に設定されると、GPXファイルとファイル更新日時を付きあわせてJPEGのEXIFに書き込む方法は無数に有ります。
使い慣れたツールを使って JPEGファイルのEXiF情報に位置情報を書き込んでください。
4.1 AdjustTime2を使う
ここでは 私の自作ツールを使ってEXiFに位置情報を書き込む方法を説明します。
-
Java実行環境をインストールしてください。インストール方法は割愛します。
-
AdjustTime2をダウンロードする
-
ダウンロードした ZIPファイルをホームディレクトリ(
~/AdjustTime2
)に展開する -
コマンドを叩いて 起動する
Terminal
(Windowsの場合はDocker Quickstart Terminal
)に下記コマンドを打ち込む
cd ~
cd AdjustTime2
chmod +x AdjustTime2.sh
./AdjustTime2.sh
-
AdjustTime2 の画面が開いたら、「選択」ボタンを押して連番JPEGファイルが格納されているフォルダを対象フォルダフィールドにセットする → 「次へ」
-
GPXフォルダ に「
~/Movie2jpg-master/mapi/gpx
」をセットして、「次へ」
フォルダを設定した時は、そのフォルダ内のすべてのGPXファイルをひも付けの対象とします。
GPXファイルを指定した時は、指定されたGPXファイルのみひも付けの対象とします。
- 「EXIFの変換をする」にチェックをつける
~/Movie2jpg-master
┃
┗━ ~/Movie2jpg-master/mapi
┃
┗━ ~/Movie2jpg-master/mapi/gpx
┃
┗━ ~/Movie2jpg-master/mapi/gpx/XXX
┣━ 00001.jpg
┣━ 00002.jpg
┣━ :
┗━ 01861.jpg
EXiFが付与されたファイルが ~/Movie2jpg-master/mapi/gpx
に作成されます。
6. カメラとGPSロガーとのタイミング調整を行う
カメラもGPSロガーも正確な時刻と同期させていれば 撮影時刻=GPS位置 が一致するようにみえますが、実際には カメラとロガーとの相性の関係によって、組み合わせによっては2〜6秒ほどのズレが生じます。
次にこのズレの補正方法を示します。
-
Java実行環境をインストールしてください。インストール方法は割愛します。
-
**JOSM**をインストールしてください。インストール方法は割愛します。
-
**JOSM**を起動する
-
再度、JOSMを起動して「EXIFが作成されたフォルダ``/mapi/gpx/XXX`」内のすべてのファイルをドラッグ&ドロップする
- 横断歩道のゼブラが足元にあることを確認できます。
8. 不要なイメージを削除する
Mapillary-toolsでも重複画像を削除する機能は有りますが、絶対にアップしたくないヤバイ画像や信号待ち等の画像は手動で削除してしまいましょう
- この例では高架下で信号待ちをしたせいでGPSの奇跡が大きくズレています。停止中の画像はすべて削除してしまいましょう。
9. 'Mapillary-tools'を使ってMapillaryに一括大量アップロード
元ネタはここから引用しています
ここでは Docker を使った方法を紹介します。
9.1 mapillary.sh のセットアップと再ビルド
Docker 'mapillary_tools'
'mapillary_tools'は Dockerイメージ 'haya4/Movie2jpg' に含まれています。
初回に限りmapillary.shのセットアップが必要です。
- テキストエディタを使って
~/Movie2jpg-master/mapillary.sh
ファイルを下記の内容に書き換えてください
export MAPILLARY_EMAIL="hoge@mail.com"
export MAPILLARY_PASSWORD="password"
export MAPILLARY_USERNAME="yourname"
export MAPILLARY_PERMISSION_HASH="....=="
export MAPILLARY_SIGNATURE_HASH="....="
python /source/mapillary_tools/python/remove_duplicates.py /mnt/mapi/img/m/ /mnt/mapi/img/duplicate/
python /source/mapillary_tools/python/upload_with_preprocessing.py /mnt/mapi/img/m/
Mapillary へログインし、「Developer」のページを表示させ、そこに記載された項目をmapillary.sh
に設定してください。
- MAPILLARY_EMAIL Mapilarry にログインする時に使っているメールアドレス
- MAPILLARY_PASSWORD パスワード
- MAPILLARY_USERNAME ユーザー名
- MAPILLARY_PERMISSION_HASH
- MAPILLARY_SIGNATURE_HASH
-
Terminal
(Windowsの場合はDocker Quickstart Terminal
)に下記コマンドを打ち込む (rebuild)
cd ~/Movie2jpg-master
docker build -t movie2jpg .
9.2 'mapillary_tools'の設定
~/Movie2jpg-master
┃
┗━ ~/Movie2jpg-master/mapi
┃
┗━ ~/Movie2jpg-master/mapi/img
┃
┣━ ~/Movie2jpg-master/mapi/img/m
┃ ┣━ 00001.jpg
┃ ┣━ 00002.jpg
┃ ┣━ :
┃ ┗━ 01861.jpg
┃
┗━ ~/Movie2jpg-master/mapi/img/duplicate
-
「~/Movie2jpg-master/mapi/img/m」フォルダにMapillaryにアップしたいJPEGファイルを置く
(「~/Movie2jpg-master/mapi/gpx」に作成されたEXiFが付与されたファイルが入ったフォルダを「~/Movie2jpg-master/mapi/img/m」フォルダに変更する) -
「~/Movie2jpg-master/mapi/img/duplicate」フォルダに重複ファイルが置かれる
9.3 Docker 'mapillary_tools'の実行
cd ~/Movie2jpg-master
docker run -it -v $(pwd)/mapi:/mnt/mapi:rw movie2jpg /bin/bash /root/mapillary.sh
docker run -it -v $(pwd)/mapi:/mnt/mapi:rw movie2jpg chmod 777 -R /mnt/mapi
-v $(pwd)/mapi:/mnt/mapi:rw
PCのフォルダ(~/mapi)をコンテナのフォルダ(/mnt/mapi)にマウントする
# cd /root
# sh ./mapillary.sh
# :
#
これで Mapillary へのアップロードが完了しました。
調子にのってガバガバアップロードしてると契約しているインターネットプロパイダから帯域制限を食らうので注意してください。