GoProのGPSデータを抽出・結合・間引き処理する方法．(Linux環境)

## イントロ

GoPRO動画に記録されたGPSデータの抽出の方法を説明したサイトは多いが，「分割された動画のGPSデータを結合する」，「GPSデータの間引くを行う」といった操作の説明は少ない．
本記事ではなるべくローカル環境でしかもGUIソフトになるべく依存せずにLinuxコマンド操作でデータを処理する方法を紹介する．
ある程度，自力で環境構築，コマンドの意味を調べられるがGPXデータを一括でバッチ処理的に扱い，任意の点数でデータの間引きまで行いたい人向け．



## GOPROからGPS情報を抽出する．


次のコマンドで0:3を手掛かりにGPSデータが抽出される．
Go言語を使用する．

```:a.sh
#!/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"

```

複数の動画データがある場合には，つぎのスクリプトで全実行することができる．

```:multi.sh
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行目と後ろから３行目の情報を省いた上で，テキストデータを順番につなぎ合わせていく．
tmp1,tmp2には省いた９行目，３行目までの情報をあらかじめ用意しておく．


```:merge.sh
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データの間引き

１０点毎に１つのデータにしたいなら
INT=10, MOD=50とすればよい．

GPXファイルの行数は５行１組となっており，
json形式であるため最初と最後の行のタブインデントを揃えるなどしている．

```:merge.sh
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

```

```: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動画連番リネーム」なで時系列順に並ぶようにファイル名を編集しておくことが必要.以下のページが参考になる．

https://kamiyama-online.com/gopro-movie-renumbering-vbscript/

- GoProからGPSデータを抽出するのにGO言語を用いている．

- GoProのGPSサンプリングレートは約20Hzなので，20点毎のデータ間引きをしても十分に滑らかな軌跡をたどることができる．データは20分の１となり，これだけでGoogleEarthの動作は結構軽くなる．

- GPSデータの抽出方法は以下を参照した．GO言語関連の方法はこちらにすでに全部書いてある．

https://home.hiroshima-u.ac.jp/~tigawa/?p=1305

https://github.com/stilldavid/gopro-utils.git