やっていていくつか特有の注意があるので書きます。
GoProにGPSデータの補完
GOProを水中に沈めて写真を撮る場合、水中では微弱なGPS電波の到達の期待は無理ですから、当然ながら写真のGPSはアテになりません。
GOPro 12からはGPSそのものが搭載されていません。
水上ドローンの場合、幸いにしてフライトコントローラーはGPSデータを持っています。 ですから、[カメラシャッターをきったタイミングで同時にGPSデータを保管し、陸上にあがってから取得したGPSデータを撮った写真に書き込めばいい]でしょう。
Drone kitを使ってGPSデータを取得するプログラムは以下。(gps.py)
from dronekit import connect as connection
from logging import getLogger
def getlocation():
log = getLogger("gopro-fc2")
"""
以下はテレメトリー接続しないとテストできない。
"""
connectstring = "tcp:127.0.0.1:5762" # sitl pre-defined
#connectstring = "/dev/ttyACM0,115200" #USB
vehicle = connection(connectstring, wait_ready=False)
vehicle.wait_ready('autopilot_version')
log.debug("connected Flight Controller")
# if failed, terminate program by ConnectionRefusedError
lat = vehicle.location.global_frame.lat
lon = vehicle.location.global_frame.lon
alt = vehicle.location.global_frame.alt
log.info("location: lat="+str(lat)+" lon="+str(lon)+ " alt="+str(alt))
vehicle.close()
return(lat, lon, alt)
if __name__ == "__main__":
x = getlocation()
print(x[0])
print(x[1])
print(x[2])
得たデータは撮影したJpegファイルに書き込みます。 そのコードは次のとおり
"""
exifの時刻情報を書き込む
"""
from GPSPhoto import gpsphoto
# 入力ファイル定義
listfile = "./piclist/20240508.txt" # 位置情報とファイルのリスト
imagefolder = "./100GOPRO/" # 写真のあるフォルダー
if __name__ == '__main__' :
# 属性リストを入手
with open(listfile, 'r') as f:
for line in f:
items = line.split(',')
l_date = items[0]
l_filename = items[1]
l_lat = items[2]
l_lon = items[3]
l_alt = items[4]
imagefile = imagefolder+l_filename
photo = gpsphoto.GPSPhoto(imagefile)
new_info = gpsphoto.GPSInfo((float(l_lat), float(l_lon)), alt=0)
new_filename = imagefolder+"n_"+l_filename
photo.modGPSData(new_info, new_filename)
print("New file generated: %s" % new_filename)
上のプログラムの場合だと、新しく”n_”のついた写真が作られます。EXIFの緯度経度データは変更されています。高度(altitude)は水上写真なのですべて0にしています。 EXIFデータの書き換えはいろいろな方法がありますが、GPSPhotoモジュールを使う方法がもっともシンプルだと思います。 Github検索していて、このモジュールをみつけた時はうれしかったな。
海底地図は既存の写真地図生成プログラムでは作れない
空を飛ぶドローンで空中から写真を取り、地図を作るという試みは極めてスタンダードになされています。
Ardupilotのドキュメント(3D Mapping)は読むべきページです。
Ardupilotでよく使われているものについては3D MappingのページにあるとおりODM(Open Drone Map)かAgisoftのMetashapeでしょう。
同じ方法を水中で行い、海底の状況の地図を作ることを考えます。 Ardupilotの3d mappingのページで紹介されているプログラムはいずれもGPSデータが写真に正しく書き込まれていることを前提としています。 AgisoftはGPSデータがなくてもマップを作れるとありますが、試すとメチャクチャでした。
オープンソースのWebODMを使ってみました。 ODMのドキュメントはこちら 。WebODMについてはWindows, Mac, LinuxそれぞれDockerを使ったインストールの方法が乗っているので、そのとおりやればOKです。
しかし、どのソフトウェアでも写真から地図を作ることはできませんでした。GPSデータは書き込んでいるにもかかわらず、です。
理由を説明します。写真から地図を作るアルゴリズムは、一枚の写真の特異点を抽出することから始まります。その特異点を他の写真でも抽出し、同じならば重ねるというやり方です。したがってマップを作る場合、写真は十分な重複が必要となります。70%から80%重なっていることが推奨されるのです。
このアルゴリズムの限界は特異点のほとんどない写真ばかりだと地図を作ることができないことを意味しています。おそらく平坦な砂漠の空撮をしてもマップは作れないと思われます。同様に海底は代わり映えしません。特異点を抽出することが困難なのです。
ですから、海底を写真で地図製作する場合、上で検討したような地図作成ソフトは使えないことは重要な情報として共有しておきます。
自作の必要があります。どうするか考え中。。。