見出し画像

Drogger MJpegで抽出した画像をPIX4Dmaticで扱えるようにする


課題

Drogger MJpegで抽出ちゅうしゅつした画像がぞうをPIX4Dmaticで処理しょりする場合ばあいに、MJpegの設定せっていによっては画像がぞう読み込よみこむことができない。また、画像がぞう回転方向かいてんほうこうはフライトログから読み込よみこ必要ひつようがあるが、現状げんじょうのMJpegフライトログはRealityScanにせてあるため、そのままではPIX4Dmaticであつかうフォーマットと適合てきごうしない。

解決策

MJpegの設定を適切なものにする。
Pythonスクリプト等で、フライトログをPIX4Dmaticに適したフォーマットに整形する。

注意点

以下は、とりあえず処理できる、といった程度の仮の設定。
実用上は、検証点との比較などを行い、さらに設定を詰める必要がある。
また、今後のDrogger MJpegのアップデートによっても変更が予想される。

以下は、Drogger GパッケージにGoProをマウントしたハードウェアセッティングを想定している。Droggerとカメラの位置関係次第で、回転角の符号等が異なる場合がある。

MJpegのバージョンはVer 0.4.0を想定している。
Ver 0.3.0以前を使用した場合、抽出された画像の向きが適切でない場合がある。

MJpegでの処理設定

出力タブ

  • 出力座標系は任意だが、PIX4Dmaticでのフライトログのインポート時に適切な座標系を選択する必要がある。

  • 以下では、フライトデータ --> 出力座標系「WGS84」、高さにJPGEO2024の標高を使うを「オフ」として進める。

  • GパッケージとGoProの組み合わせでは、通常、「Yaw方向を180°回転させる」を有効にする。

外部プログラムタブ

  • exiftoolを使用 --> カメラメーカーとカメラモデルを指定

  • Ver 0.4.0 現在、GoProと一部スマホ以外は、MJpegでカメラモデルの書き込みができない。それ以外のカメラを使用する場合は、後から自分で書き込む必要がある(または、GoPro以外でもGoProと書き込んでしまって通るかもしれない)。

flightlog.txtの改変

フライトログをPix4Dmaticに読み込むために、適切なフォーマットに変更する。
変更点は以下の通り。

水平精度をまとめる

PIX4Dmaticでは、画像の位置精度はX,Yそれぞれではなく、単一の水平精度として読み込む。
`LongitudeAccuracy, LatitudeAccuracy`を、`Horizontal accuracy`(ヘッダー名は適当)などとしてひとつにする。

  • MJpegで出力される水平精度はX,Yで同じ値なため、整形の際にどちらかを破棄すれば良い。

Pitch角を整形する

MJpegで出力される値とPIX4Dmaticで扱うPitch角の基準が異なるため、Pitchの値を(X)としたときに、f(x) = 90 - (x) になるようにPitchの値を書き換える。

それぞれのPitch角は次のようになっている。

  • MJpegでは、真下が +90°、水平が 0°、真上が -90°

    • ただし、Droggerとカメラの剛体接続の方法によって異なる。PIX4Dmaticにいったん読み込んだあと、3Dビューでカメラの姿勢を確認しながら、現地のカメラ姿勢と近くなるPitch角の値を探すと良い。

  • PIX4Dmaticは、真下が 0°、水平が +90°、真上が +180°

    • これはカメラによって変更は無い(と思う)。

上記で改変した値を含め、フライトログの列を以下のように並べ替える。

  • `Name, Latitude, Longitude, Altitude, Yaw, Pitch, Roll, Horizontal accuracy, AltitudeAccuracy`

処理するためのPythonスクリプト

# ChatGPT o3

import csv
from pathlib import Path

INFILE  = Path("flightlog.txt")
OUTFILE = Path("flightlog_reformatted.txt")

with INFILE.open(newline="", encoding="utf-8") as fin, \
     OUTFILE.open("w", newline="", encoding="utf-8") as fout:

    reader = csv.reader(fin)
    writer = csv.writer(fout)

    # ---- 1. ヘッダを解析 -------------------------------------------------
    header_raw = next(reader)
    if not header_raw or not header_raw[0].lstrip().startswith("#"):
        raise RuntimeError("First line must be a header beginning with '#'.")
    header = [h.lstrip("# ").strip() for h in header_raw]

    # 列インデックスを取得
    idx = {name: header.index(name) for name in (
        "Name", "Longitude", "Latitude", "Altitude",
        "LongitudeAccuracy", "LatitudeAccuracy", "AltitudeAccuracy",
        "Yaw", "Pitch", "Roll"
    )}

    # ---- 2. 目的のヘッダ順を定義 ----------------------------------------
    new_header = [
        "# Name",              # 先頭だけ "# " を再付与
        "Latitude",
        "Longitude",
        "Altitude",
        "Yaw",
        "Pitch",
        "Roll",
        "Horizontal accuracy",  # 改名
        "AltitudeAccuracy"
    ]
    writer.writerow(new_header)

    # ---- 3. 各行を変換して書き出す --------------------------------------
    for row in reader:
        if not row:            # 空行はスキップ
            continue

        # Pitch の数値変換と置き換え -------------------------------------
        try:
            pitch_val  = float(row[idx["Pitch"]])
            new_pitch  = 90.0 - pitch_val
            row[idx["Pitch"]] = f"{new_pitch:g}"   # 余分な 0 を付けない書式
        except ValueError:
            # 数値でなければ(例:空文字やヘッダ行など)そのまま出力
            pass

        new_row = [
            row[idx["Name"]],
            row[idx["Latitude"]],        # Longitude / Latitude を実質的に入れ替え
            row[idx["Longitude"]],
            row[idx["Altitude"]],
            row[idx["Yaw"]],
            row[idx["Pitch"]],           # 変換済み
            row[idx["Roll"]],
            row[idx["LongitudeAccuracy"]],  # Horizontal accuracy
            row[idx["AltitudeAccuracy"]]
        ]
        writer.writerow(new_row)

print(f"Done! Output written to: {OUTFILE.resolve()}")

PIX4Dmaticでの処理手順

フライトログの読み込み

  1. 画像をインポート

  2. "ファイル --> インポート --> 画像の位置と向き" から、上記で改変したフライトログを指定して読み込む。

    • 今回の場合、水平座標系は「WGS84 EPSG:4326」、鉛直座標系は「Ellipsoidal height over WGS 84」とする。

    • MJpegの設定で平面直角座標等を指定した場合は、それに応じた設定にする。

キャリブレーション

テンプレート

  • 「PIX4Dcatch」や「3Dモデル」などを選択

パイプライン

  • 「信頼性の高い位置と向き情報」「スケーラブル標準」などを選択

  • それぞれ、フライトログで読み込んだ値に対する重み付けが異なる。

カメラ内部パラメータ

  • 撮影機材に準じた値にする。

  • 実際と乖離しすぎるとキャリブレーション不良の原因となる。

参考リンク

いいなと思ったら応援しよう!