How to compute camera positions in the same coordinate system as the exported Gaussian splat (.ply)? #3748
-
|
Hello! I’m trying to understand the coordinate relationship between COLMAP, Nerfstudio and the exported Gaussian splat (.ply). My goal is to compute the 3D position of a camera (i.e. the location where an image was taken) in the same coordinate system as the exported Gaussian splat (.ply). My current approach is:
My assumption is that applying the However, the camera positions I compute do not seem to match the splat geometry as expected. So my main question is: Are the coordinates of the exported Gaussian splat ( Or is the Below is the code I currently use to compute camera positions in viewer space. def load_colmap_poses_raw(scene_name):
sparse = DATASET_PATH / scene_name / "sparse/0"
images = read_images_binary(sparse / "images.bin")
poses = {}
F = np.diag([1,-1,-1]) # OpenCV -> OpenGL
for img in images.values():
R = img.qvec2rotmat()
t = img.tvec
C = -R.T @ t
pose = np.eye(4)
pose[:3,:3] = F @ R.T
pose[:3,3] = F @ C
poses[Path(img.name).name] = pose
return posesdef load_scene_transforms(scene_name):
transform_file = DATASET_PATH / scene_name / "dataparser_transforms.json"
if not transform_file.exists():
raise FileNotFoundError(f"Not found: {transform_file}")
with open(transform_file) as f:
data = json.load(f)
T_raw = np.array(data.get("transform", np.eye(4)))
if T_raw.shape == (3, 4):
T = np.eye(4)
T[:3, :] = T_raw
else:
T = T_raw.copy()
return T, float(data["scale"])def get_camera_in_viewer_space(scene_name, image_name):
"""
Returns the position (xyz) and rotation quaternion (xyzw) of the given
image's camera expressed in this scene's viewer space.
"""
poses = load_colmap_poses_raw(scene_name)
T, scale = load_scene_transforms(scene_name)
if image_name not in poses:
raise ValueError(f"{image_name} not found in {scene_name}")
# Apply nerfstudio normalisation
viewer_pose = T @ poses[image_name]
viewer_pose[:3, 3] *= scale
position = viewer_pose[:3, 3].tolist()
quat = Rotation.from_matrix(viewer_pose[:3, :3]).as_quat().tolist() # xyzw
return position, quat |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
Found the solution to my issue. The problem was in my This resulted in a double coordinate transformation, which caused incorrect camera positions. The fix was simply to remove the redundant conversion and directly apply the scene transform and scale: def get_camera_position(scene_name, image_name):
poses = load_colmap_poses_raw(scene_name)
T, scale = load_scene_transforms(scene_name)
pose = poses[image_name]
C_gl = pose[:3, 3] # already OpenGL
C_ns = T[:3, :3] @ C_gl + T[:3, 3]
C_ns = scale * C_ns
return C_nsThis resolved the alignment issues completely. |
Beta Was this translation helpful? Give feedback.
Found the solution to my issue.
The problem was in my
get_camera_in_viewer_space()function. I was incorrectly converting camera coordinates to OpenGL space, even though the poses exported from COLMAP were already aligned to the OpenGL coordinate system.This resulted in a double coordinate transformation, which caused incorrect camera positions.
The fix was simply to remove the redundant conversion and directly apply the scene transform and scale: