| | import os |
| | import json |
| | import numpy as np |
| |
|
| | from utils.math_utils import world_to_view, projection_matrix |
| |
|
| | |
| | def load_camera(camera_info): |
| | """Load camera parameters from camera info dictionary""" |
| | |
| | camera_id = camera_info["camera_id"] |
| | camera_to_world = np.asarray(camera_info["camera_to_world"], dtype=np.float64) |
| | |
| | |
| | camera_to_world[:3, 1:3] *= -1 |
| | |
| | |
| | world_to_camera = np.linalg.inv(camera_to_world).astype(np.float32) |
| | |
| | |
| | |
| | R = world_to_camera[:3, :3] |
| | T = world_to_camera[:3, 3] |
| | |
| | |
| | world_to_camera[3, 3] = 1. |
| | world_to_camera = world_to_camera.T |
| |
|
| | |
| | width = camera_info.get("width") |
| | height = camera_info.get("height") |
| | fx = camera_info.get("focal") |
| | fy = camera_info.get("focal") |
| | cx = width / 2 |
| | cy = height / 2 |
| | |
| | |
| | fovx = 2 * np.arctan(width / (2 * fx)) |
| | fovy = 2 * np.arctan(height / (2 * fy)) |
| | |
| | |
| | view_matrix = world_to_view(R=R, t=T) |
| | |
| | |
| | znear = 0.01 |
| | zfar = 100.0 |
| | proj_matrix = projection_matrix(fovx=fovx, fovy=fovy, znear=znear, zfar=zfar).T |
| | full_proj_matrix = world_to_camera @ proj_matrix |
| | |
| | |
| | tan_fovx = np.tan(fovx * 0.5) |
| | tan_fovy = np.tan(fovy * 0.5) |
| | |
| | camera_center = np.linalg.inv(world_to_camera)[3, :3] |
| | |
| | |
| | camera_model = camera_info.get("camera_model", "OPENCV") |
| | if camera_model == "OPENCV" or camera_model is None: |
| | camera_type = 0 |
| | elif camera_model == "OPENCV_FISHEYE": |
| | camera_type = 1 |
| | else: |
| | raise ValueError(f"Unsupported camera_model '{camera_model}'") |
| | |
| | |
| | distortion_params = [] |
| | for param_name in ["k1", "k2", "p1", "p2", "k3", "k4"]: |
| | distortion_params.append(camera_info.get(param_name, 0.0)) |
| | |
| | camera_params = { |
| | 'R': R, |
| | 'T': T, |
| | 'camera_center': camera_center, |
| | 'view_matrix': view_matrix, |
| | 'proj_matrix': proj_matrix, |
| | 'full_proj_matrix': full_proj_matrix, |
| | 'tan_fovx': tan_fovx, |
| | 'tan_fovy': tan_fovy, |
| | 'fx': fx, |
| | 'fy': fy, |
| | 'cx': cx, |
| | 'cy': cy, |
| | 'width': width, |
| | 'height': height, |
| | 'camera_to_world': camera_to_world, |
| | 'world_to_camera': world_to_camera, |
| | 'camera_type': camera_type, |
| | 'distortion_params': np.array(distortion_params, dtype=np.float32) |
| | } |
| | |
| | return camera_params |
| |
|
| | def load_camera_from_json(input_path, camera_id=0): |
| | """Load camera parameters from camera.json file""" |
| | camera_file = os.path.join(os.path.dirname(input_path), "cameras.json") |
| | if not os.path.exists(camera_file): |
| | print(f"Warning: No cameras.json found in {os.path.dirname(input_path)}, using default camera") |
| | return None |
| | |
| | try: |
| | with open(camera_file, 'r') as f: |
| | cameras = json.load(f) |
| | |
| | |
| | camera = next((cam for cam in cameras if cam["id"] == camera_id), cameras[0]) |
| | |
| | |
| | return load_camera(camera) |
| | |
| | except Exception as e: |
| | print(f"Error loading camera from cameras.json: {e}") |
| | return None |
| |
|
| | def load_camera_colmap(cam_info): |
| | """ |
| | Load camera from COLMAP format (dust3r output) with exact compatibility to original load_camera. |
| | |
| | Args: |
| | cam_info: Dictionary containing: |
| | - width, height: image dimensions |
| | - fx, fy: focal lengths |
| | - cx, cy: principal point |
| | - camera_id: unique identifier |
| | - R: rotation matrix (world-to-camera rotation) |
| | - T: translation vector (world-to-camera translation) |
| | - Optional: camera_model, distortion params |
| | """ |
| | |
| | camera_id = cam_info["camera_id"] |
| | |
| | |
| | R = cam_info['R'] |
| | T = cam_info['T'] |
| | |
| | |
| | world_to_camera = np.eye(4, dtype=np.float64) |
| | world_to_camera[:3, :3] = R |
| | world_to_camera[:3, 3] = T |
| | |
| | |
| | camera_to_world = np.linalg.inv(world_to_camera).astype(np.float64) |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | world_to_camera = np.linalg.inv(camera_to_world).astype(np.float32) |
| | |
| | |
| | width = cam_info.get("width") |
| | height = cam_info.get("height") |
| | fx = cam_info.get("fx", cam_info.get("focal", width * 0.7)) |
| | fy = cam_info.get("fy", cam_info.get("focal", height * 0.7)) |
| | cx = cam_info.get("cx", width / 2) |
| | cy = cam_info.get("cy", height / 2) |
| | |
| | |
| | fovx = 2 * np.arctan(width / (2 * fx)) |
| | fovy = 2 * np.arctan(height / (2 * fy)) |
| | |
| | |
| | view_matrix = world_to_view(R=R, t=T) |
| | |
| | |
| | znear = 0.01 |
| | zfar = 100.0 |
| | proj_matrix = projection_matrix(fovx=fovx, fovy=fovy, znear=znear, zfar=zfar).T |
| | full_proj_matrix = world_to_camera @ proj_matrix |
| | |
| | |
| | tan_fovx = np.tan(fovx * 0.5) |
| | tan_fovy = np.tan(fovy * 0.5) |
| | |
| | |
| | camera_center = camera_to_world[:3, 3] |
| | |
| | |
| | camera_model = cam_info.get("camera_model", "OPENCV") |
| | if camera_model == "OPENCV" or camera_model is None: |
| | camera_type = 0 |
| | elif camera_model == "OPENCV_FISHEYE": |
| | camera_type = 1 |
| | else: |
| | camera_type = 0 |
| | |
| | |
| | distortion_params = [] |
| | for param_name in ["k1", "k2", "p1", "p2", "k3", "k4"]: |
| | distortion_params.append(cam_info.get(param_name, 0.0)) |
| | |
| | |
| | camera_params = { |
| | 'R': R, |
| | 'T': T, |
| | 'camera_center': camera_center, |
| | 'view_matrix': view_matrix, |
| | 'proj_matrix': proj_matrix, |
| | 'full_proj_matrix': full_proj_matrix, |
| | 'tan_fovx': tan_fovx, |
| | 'tan_fovy': tan_fovy, |
| | 'fx': fx, |
| | 'fy': fy, |
| | 'cx': cx, |
| | 'cy': cy, |
| | 'width': width, |
| | 'height': height, |
| | 'camera_to_world': camera_to_world, |
| | 'world_to_camera': world_to_camera, |
| | 'camera_type': camera_type, |
| | 'distortion_params': np.array(distortion_params, dtype=np.float32) |
| | } |
| | |
| | return camera_params |
| |
|