OpenDroneMap-ODM/opendm/camera.py

73 wiersze
2.7 KiB
Python

import os, json
from opendm import log
def get_cameras_from_opensfm(reconstruction_file):
"""
Extract the cameras from OpenSfM's reconstruction.json
"""
if os.path.exists(reconstruction_file):
with open(reconstruction_file, 'r') as fin:
reconstructions = json.loads(fin.read())
result = {}
for recon in reconstructions:
if 'cameras' in recon:
for camera_id in recon['cameras']:
# Strip "v2" from OpenSfM camera IDs
new_camera_id = camera_id
if new_camera_id.startswith("v2 "):
new_camera_id = new_camera_id[3:]
result[new_camera_id] = recon['cameras'][camera_id]
# Remove "_prior" keys
keys = list(result[new_camera_id].keys())
for k in keys:
if k.endswith('_prior'):
result[new_camera_id].pop(k)
return result
else:
raise RuntimeError("%s does not exist." % reconstruction_file)
def get_opensfm_camera_models(cameras):
"""
Convert cameras to a format OpenSfM can understand
(opposite of get_cameras_from_opensfm)
"""
if isinstance(cameras, dict):
result = {}
for camera_id in cameras:
# Quick check on IDs
if len(camera_id.split(" ")) < 6:
raise RuntimeError("Invalid cameraID: %s" % camera_id)
# Add "v2" to camera ID
if not camera_id.startswith("v2 "):
osfm_camera_id = "v2 " + camera_id
else:
osfm_camera_id = camera_id
# Add "_prior" keys
camera = cameras[camera_id]
prior_fields = ["focal","focal_x","focal_y","c_x","c_y","k1","k2","p1","p2","k3"]
valid_fields = ["id","width","height","projection_type"] + prior_fields + [f + "_prior" for f in prior_fields]
keys = list(camera.keys())
for param in keys:
param_prior = param + "_prior"
if param in prior_fields and not param_prior in camera:
camera[param_prior] = camera[param]
# Remove invalid keys
keys = list(camera.keys())
for k in keys:
if not k in valid_fields:
camera.pop(k)
log.ODM_WARNING("Invalid camera key ignored: %s" % k)
result[osfm_camera_id] = camera
return result
else:
raise RuntimeError("Invalid cameras format: %s. Expected dict." % str(cameras))