Mapillaryへの動画データアップロード

投稿者: | 2016年12月16日

Mapillaryへの動画データアップロード手順

前回紹介したMapillaryですが、動画の投稿はまだ実験段階のようです。こちらに手順(英文)が公開されていますが、かなり面倒です。簡単に手順を整理すると以下になります。
  1. 動画から静止画を抽出する(上記手順ではVLCを使用)
  2. 抽出した静止画のEXIFに撮影時刻を追加(add_fix_dates.py)
  3. 別に採取したGPSトラックデータ(GPX)を使ってジオタグ情報を静止画に埋め込む(gpsprune)
  4. ジオタグ情報から向きを算出して静止画に埋め込む(interpolate_direction.py)
  5. できた静止画群を、Mapillaryサイトでプレビューしてアップロード。
ここで一番面倒なのが1.の静止画の抽出です。これをまともにやると撮影した実時間かかってしまいます。また、VLCの仕様で再生時のインターバルで静止画が生成されるため、何かの負荷で再生が止まったり、ノイズが乗ったりすると失敗となります(そうなると最初からやり直し)。
また、動画の撮影についてもバッテリーやSDカードの容量の問題。PC等での動画の保管についても、容量と画質の兼ね合いで迷う点が多いと思います。
ですので、今回は、これらの点を解決すべく検証を行いました。
なお、今回の検証に利用しているカメラは最近導入したGoPro HERO5 Session。360°撮影が可能なNikonのKeyMission360も惹かれたのですが、より小型なGoProを選んでみました。自転車へのセットアップはこんな感じ。
バッテリー給電しながらの撮影も可能なので、モバイルブースターとの併用でバッテリーの問題は解決です。ですので、あとはSD容量とアップロード手順の改善を考えます。

撮影モードについて

動画→静止画手順の効率化としてまず考えられるのは、タイムラプス撮影です。どのみちアップロードには数秒に1枚分しか使わないので、最初から必要な分しか撮影しないというもの。GoProには「タイムラプスビデオ」と「タイムラプスフォト」の2種類があります。
  • タイムラプスビデオ:出力は動画(MP4)。動画なので圧縮率は高め。
  • タイムラプスフォト:出力は静止画(JPG)。1枚1枚に撮影時刻が記録される。
つまりタイムラプスフォトを使うと、最初から2.の手順まで済んだ状態の画像データが得られるということになります。一方、タイムラプスビデオは圧縮率が高めで一連の撮影が1ファイルとなるという点で保管に有利ということになります。
また、GoPro HERO5 Sessionでは、タイムラプスビデオの画質が選べるのでいくつかをピックアップして試してみました。その結果が以下です。
撮影方法
データ
1秒あたりのMB
32GB撮影可能時間
Video: 1080HD
3.8GB/17分
3.7MB/秒
約2時間
TimeLaps Video(1080HD, 1shot/2sec)
59MB/16秒(実時間15分20秒相当)
0.064MB/秒
約140時間
TimeLaps Video(4K, 1shot/2sec)
693MB/56秒(実時間55分46秒相当)
0.2MB/秒
約40時間
TimeLaps Photo(1shot/2sec)
2.3MB/枚
1.2MB/秒
約6時間
抽出した静止画の品質比較も載せておきます。個人的には交差点名が認識できるというのが重要なので、そこに注目した画像をピックアップしました(撮影条件が違うのはご容赦)。
1. タイムラプスビデオ(1080HD撮影:614KB)

2. タイムラプスビデオ(4K撮影:1.4MB)

3. タイムラプスフォト(2.3MB)


この写真だと全てで交差点名は読み取れますが、撮影タイミングによって1080HDの画像は若干苦しいケースもあるので、個人的にはMapillary向けにはタイムラプスビデオ4Kでの撮影がベストかなと思っています。しばらくはこの撮影モードで運用してみます。

動画変換手順改善版

 上記でタイムラプスビデオ4Kがベストと書きましたが、4K画質かつ全てのフレームを静止画に落とす(VLCの設定Recording Ratioを1にする)と、私の環境(i7-6700 CPU @ 3.40GHz, 32GB Memory, 128GBのM.2 SSD搭載)では1.の手順がほぼ失敗する(再生、記録について行けず画像が乱れるor途中で異常終了)ということになってしまっています。
もともとVLCを使った手順というのが筋がよくなさそうなので調べたところ、動画→静止画変換にはffmpegを使う方が一般的ということが判明。早速試してみました。使用したオプションは以下。
ffmpeg -i video.mp4 -f image2 -qmin 1 -q 1 ${PHOTO_PATH}/frame%04d.jpg

これでタイムラプスビデオから簡単・確実に静止画抽出が可能になります。以下のようなスクリプトで、1.と2.の手順が少し楽になります。

#!/bin/bash

TOOL_PATH=/home/charilab/work/mapillary_tools/python
PHOTO_PATH=/home/charilab/mapillary/photos
INTERVAL=2
VIDEO_FILE=$1

ffmpeg -i ${VIDEO_FILE} -f image2 -qmin 1 -q 1 ${PHOTO_PATH}/frame%04d.jpg

BASEDATE=`stat ${VIDEO_FILE} | awk  '/^Modify/ {printf("%s %s", $2, $3)};' | awk -F '.' '{print $1}'`
python ${TOOL_PATH}/add_fix_dates.py ${PHOTO_PATH}/ "${BASEDATE}" ${INTERVAL}

gpspruneによるジオタグ追加時の注意点

もう一つ、注意したい点としては3.で画像にジオタグを添付するときの時刻の設定があります。EXIFの撮影時刻はなぜかタイムゾーンの考慮がなされておらず、一般的に現地時間が入っています。一方、GPSのトラックデータはGMTなので、補正が必要になります。具体的には、2.の手順でGMTで時刻を指定するか、gpspruneのcorrelate photo時の”Time Offset”設定で”Photo later than point”で9時間を設定する必要があります。