mirror of
https://github.com/nerfstudio-project/nerfstudio.git
synced 2026-11-12 19:04:03 +08:00
Merge 8f9443f84e into 50e0e3c70c
This commit is contained in:
2 files changed
+56
-17
No files matched your search
@@ -104,35 +104,39 @@ def cameras2nerfds(
|
||||
cameras = json.loads(f.read())
|
||||
|
||||
camera_ids = list(cameras.keys())
|
||||
if len(camera_ids) > 1:
|
||||
raise ValueError("Only one camera is supported")
|
||||
if len(camera_ids) != 1:
|
||||
raise ValueError("Expected exactly one ODM camera")
|
||||
camera_id = camera_ids[0]
|
||||
camera = cameras[camera_id]
|
||||
data = {}
|
||||
if camera["projection_type"] in ["brown", "perspective"]:
|
||||
projection_type = camera["projection_type"]
|
||||
if projection_type in ["brown", "perspective"]:
|
||||
data["camera_model"] = CAMERA_MODELS["perspective"].value
|
||||
elif camera["projection_type"] in ["fisheye", "fisheye_opencv"]:
|
||||
elif projection_type in ["fisheye", "fisheye_opencv"]:
|
||||
data["camera_model"] = CAMERA_MODELS["fisheye"].value
|
||||
elif camera["projection_type"] in ["spherical", "equirectangular"]:
|
||||
elif projection_type in ["spherical", "equirectangular"]:
|
||||
data["camera_model"] = CAMERA_MODELS["equirectangular"].value
|
||||
else:
|
||||
raise ValueError("Unsupported ODM camera model: " + data["camera_model"])
|
||||
raise ValueError("Unsupported ODM camera model: " + projection_type)
|
||||
|
||||
sensor_dict = {}
|
||||
s = {"w": int(camera["width"]), "h": int(camera["height"])}
|
||||
s: Dict[str, float] = {"w": int(camera["width"]), "h": int(camera["height"])}
|
||||
|
||||
s["fl_x"] = camera.get("focal_x", camera.get("focal")) * max(s["w"], s["h"])
|
||||
s["fl_y"] = camera.get("focal_y", camera.get("focal")) * max(s["w"], s["h"])
|
||||
if projection_type in ["spherical", "equirectangular"]:
|
||||
s["fl_x"] = s["w"] / 2.0
|
||||
s["fl_y"] = s["h"]
|
||||
s["cx"] = s["w"] / 2.0
|
||||
s["cy"] = s["h"] / 2.0
|
||||
else:
|
||||
scale = max(s["w"], s["h"])
|
||||
s["fl_x"] = camera.get("focal_x", camera.get("focal")) * scale
|
||||
s["fl_y"] = camera.get("focal_y", camera.get("focal")) * scale
|
||||
s["cx"] = camera.get("c_x", 0.0) * scale + (s["w"] - 1.0) / 2.0
|
||||
s["cy"] = camera.get("c_y", 0.0) * scale + (s["h"] - 1.0) / 2.0
|
||||
|
||||
s["cx"] = camera["c_x"] + (s["w"] - 1.0) / 2.0
|
||||
s["cy"] = camera["c_y"] + (s["h"] - 1.0) / 2.0
|
||||
|
||||
for p in ["k1", "k2", "p1", "p2", "k3"]:
|
||||
for p in ["k1", "k2", "p1", "p2", "k3", "k4"]:
|
||||
if p in camera:
|
||||
s[p] = camera[p]
|
||||
|
||||
sensor_dict[camera_id] = s
|
||||
|
||||
shots_dict = {}
|
||||
reconstruction = None
|
||||
|
||||
@@ -182,7 +186,7 @@ def cameras2nerfds(
|
||||
|
||||
frame = {}
|
||||
frame["file_path"] = image_filename_map[fname].as_posix()
|
||||
frame.update(sensor_dict[camera_id])
|
||||
frame.update(s)
|
||||
|
||||
frame["transform_matrix"] = transform.tolist()
|
||||
frames.append(frame)
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
"""Regression tests for OpenSfM camera intrinsics in ODM conversions."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from nerfstudio.process_data.odm_utils import cameras2nerfds
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"camera, expected",
|
||||
[
|
||||
({"projection_type": "perspective", "focal": 0.5}, {"fl_x": 400, "cx": 399.5, "cy": 299.5}),
|
||||
({"projection_type": "brown", "focal": 0.5, "c_x": 0.1, "c_y": -0.05}, {"cx": 479.5, "cy": 259.5}),
|
||||
(
|
||||
{"projection_type": "brown", "width": 600, "height": 800, "focal": 0.5, "c_x": 0.1, "c_y": -0.05},
|
||||
{"fl_x": 400, "fl_y": 400, "cx": 379.5, "cy": 359.5},
|
||||
),
|
||||
({"projection_type": "fisheye_opencv", "focal": 0.5, "k4": 0.004}, {"k4": 0.004}),
|
||||
({"projection_type": "spherical"}, {"fl_x": 400, "fl_y": 600, "cx": 400, "cy": 300}),
|
||||
],
|
||||
)
|
||||
def test_odm_intrinsics(tmp_path, camera, expected):
|
||||
cameras_path = tmp_path / "cameras.json"
|
||||
cameras_path.write_text(json.dumps({"camera": {"width": 800, "height": 600, **camera}}))
|
||||
reconstruction_path = tmp_path / "reconstruction.json"
|
||||
shot = {"rotation": [0, 0, 0], "translation": [0, 0, 0]}
|
||||
reconstruction_path.write_text(json.dumps([{"shots": {"sample.jpg": shot}}]))
|
||||
cameras2nerfds(
|
||||
{"sample": Path("sample.jpg")}, cameras_path, tmp_path / "shots.geojson", reconstruction_path, tmp_path
|
||||
)
|
||||
frame = json.loads((tmp_path / "transforms.json").read_text())["frames"][0]
|
||||
for key, value in expected.items():
|
||||
assert frame[key] == pytest.approx(value)
|
||||
Reference in new issue
Block a user