イントロ
GoPRO動画に記録されたGPSデータの抽出の方法を説明したサイトは多いが,「分割された動画のGPSデータを結合する」,「GPSデータの間引くを行う」といった操作の説明は少ない.
本記事ではなるべくローカル環境でしかもGUIソフトになるべく依存せずにLinuxコマンド操作でデータを処理する方法を紹介する.
ある程度,自力で環境構築,コマンドの意味を調べられるがGPXデータを一括でバッチ処理的に扱い,任意の点数でデータの間引きまで行いたい人向け.
GOPROからGPS情報を抽出する.
次のコマンドで0:3を手掛かりにGPSデータが抽出される.
Go言語を使用する.
#!/bin/sh
GOPRO2GPX_FILE=~/bin/gopro2gpx
GOPRO2GPX_FILE=/home/user/go/bin/gopro2gpx
if [ $# -lt 1 ]; then
echo "Usage: $0 <input_movie_file> [<output_dir>]"
exit 1
fi
IN_FILE_EXT=$1
IN_FILE=${IN_FILE_EXT##*/}
IN_BASE=${IN_FILE%.*}
OUT_DIR=${IN_FILE_EXT%/*}
if [ $# -ge 2 ]; then
OUT_DIR=$2
fi
ffmpeg -y -i "${IN_FILE_EXT}" -codec copy -map 0:3 -f rawvideo "${OUT_DIR}/${IN_BASE}.bin"
${GOPRO2GPX_FILE} -i "${OUT_DIR}/${IN_BASE}.bin" -o "${OUT_DIR}/${IN_BASE}.gpx"
複数の動画データがある場合には,つぎのスクリプトで全実行することができる.
rm -rf comp
mkdir comp
ls ./base/*MP4 | awk '{sub(".MP4","")}{print $1}' | awk '{printf "./a.sh %s.MP4 ./comp \n", $0, NR}'
ls ./base/*MP4 | awk '{sub(".MP4","")}{print $1}' | awk '{printf "./a.sh %s.MP4 ./comp \n", $0, NR}'|sh
rm ./comp/*bin
複数のGoProから抽出したGPS情報を結合する.
先頭から9行目と後ろから3行目の情報を省いた上で,テキストデータを順番につなぎ合わせていく.
tmp1,tmp2には省いた9行目,3行目までの情報をあらかじめ用意しておく.
rm -rf ./comp
mkdir ./comp
cat ./tmp1 > ./comp/all.gpx
ls ./base/*gpx | awk '{printf "cat %s | tail -n +9 | head -n -3 >> ./comp/all.gpx\n", $0, NR}'
ls ./base/*gpx | awk '{printf "cat %s | tail -n +9 | head -n -3 >> ./comp/all.gpx\n", $0, NR}' | sh
cat ./tmp2 >> ./comp/all.gpx
GoProGPSデータの間引き
10点毎に1つのデータにしたいなら
INT=10, MOD=50とすればよい.
GPXファイルの行数は5行1組となっており,
json形式であるため最初と最後の行のタブインデントを揃えるなどしている.
rm -rf ./comp
mkdir ./comp
rm -rf ./tmp
mkdir ./tmp
ls ./base/*gpx | awk '{printf "cat %s | tail -n +9 | head -n -3 >> ./tmp/tmp.gpx\n", $0, NR}'
ls ./base/*gpx | awk '{printf "cat %s | tail -n +9 | head -n -3 >> ./tmp/tmp.gpx\n", $0, NR}' | sh
echo "---"
FILE1="./tmp/tmp.gpx"
FILE2="./tmp/tmp_int.gpx"
numLine=1
MOD=50 #MOD=INT*5
MOD=100 #MOD=INT*5
echo "INT:"$INT
cat $FILE1 | while read line
do
if [ $(($numLine % $MOD)) -eq 1 ];then
echo $'\t' $'\t' $'\t' $line >> ./tmp/tmp_int.gpx
elif [ $(($numLine % $MOD)) -ge 2 ] && [ $(($numLine % $MOD)) -le 4 ] ;then
echo $'\t' $'\t' $'\t' $'\t' $line >> ./tmp/tmp_int.gpx
elif [ $(($numLine % $MOD)) -eq 5 ] ;then
echo $'\t' $'\t' $'\t' $line >> ./tmp/tmp_int.gpx
fi
numLine=$((numLine + 1)) # 行数を1加算
done
echo "---"
cat ./tmp1 > ./comp/all.gpx
cat $FILE2 >> ./comp/all.gpx
cat ./tmp2 >> ./comp/all.gpx
<trkpt lat="38.0000000" lon="140.0000000">
<ele>1000.000</ele>
<time>2022-04-04T04:43:19.585Z</time>
<cmt>GpsAccuracy: 494; GpsFix: 3</cmt>
</trkpt>
<trkpt lat="38.0000000" lon="140.0000000">
<ele>1000.000</ele>
<time>2022-04-04T04:43:19.639Z</time>
<cmt>GpsAccuracy: 494; GpsFix: 3</cmt>
</trkpt>
補足
- あらかじめ「GoPro動画連番リネーム」なで時系列順に並ぶようにファイル名を編集しておくことが必要.以下のページが参考になる.
-
GoProからGPSデータを抽出するのにGO言語を用いている.
-
GoProのGPSサンプリングレートは約20Hzなので,20点毎のデータ間引きをしても十分に滑らかな軌跡をたどることができる.データは20分の1となり,これだけでGoogleEarthの動作は結構軽くなる.
-
GPSデータの抽出方法は以下を参照した.GO言語関連の方法はこちらにすでに全部書いてある.