やること
写真や動画をフォトグラメトリで処理すると、被写体の3D化と同時に、カメラの位置と向きの推定もしてくれます。このカメラ情報をCSV形式で出力したいのですが、私が使用しているフォトグラメトリソフトの3DF ZephyrはCSVに対応していませんでした。そこで、Blender経由での出力を試みます。
Blenderにカメラをインポート
フォトグラメトリソフトからエクスポートしたカメラ情報をBlenderにインポートしました。カメラが300個ほど並んでいます。カメラ情報には座標と回転角が含まれていますが、法線情報は(たぶん)含まれていません。法線は計算によって別途求める必要があります。
CSV出力Pythonコード
Blenderには標準でCSVを出力する機能がないため、Pythonコードを書いて対応しました。以下のコードをBlenderのテキストエディターにコピペして実行すると、カメラの座標と法線をCSV形式で出力できます。
import bpy
import csv
import os
from mathutils import Vector
# 現在のBlenderファイルのパスを取得
blend_file_path = bpy.data.filepath
blend_file_dir = os.path.dirname(blend_file_path)
# CSVファイルの保存先パスを設定
csv_path = os.path.join(blend_file_dir, 'camera_info.csv')
# カメラオブジェクトを取得
cameras = [obj for obj in bpy.data.objects if obj.type == 'CAMERA']
# カメラを名前の昇順でソート
cameras.sort(key=lambda x: x.name)
# CSVファイルに書き込むデータ
csv_data = [['Camera Name', 'Location X', 'Location Y', 'Location Z', 'Forward Vector X', 'Forward Vector Y', 'Forward Vector Z']]
for camera in cameras:
# カメラの位置を取得
location = camera.location
# カメラの向き(前方ベクトル)を取得し正規化
forward_vector = camera.matrix_world.to_3x3() @ Vector((0, 0, -1))
forward_vector.normalize()
# コンソールに表示
print(f"Camera Name: {camera.name}")
print(f"Location: X={location.x}, Y={location.y}, Z={location.z}")
print(f"Normalized Forward Vector (Normal): X={forward_vector.x}, Y={forward_vector.y}, Z={forward_vector.z}\n")
# CSVデータに追加
csv_data.append([camera.name, location.x, location.y, location.z, forward_vector.x, forward_vector.y, forward_vector.z])
# CSVファイルに書き込み
with open(csv_path, 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerows(csv_data)
print(f"CSVファイルにすべてのカメラの位置と法線を出力しました。保存先: {csv_path}")
まとめ
カメラ座標と法線をCSV形式で出力できました。このデータがあれば、撮影者の移動経路を推定できそうです。