SplatAnything / src /models /utils /geometry.py
ritianyu's picture
Publish preview-first SplatAnything demo for ZeroGPU
dc09dcc verified
Raw History Blame Contribute Delete
2.43 kB
# Modified for SplatAnything: inference-only release.
import torch
import numpy as np
from typing import Tuple
def depth_to_camera_coords(depthmap, camera_intrinsics):
"""
Convert depth map to 3D camera coordinates.
Args:
depthmap (BxHxW tensor): Batch of depth maps
camera_intrinsics (Bx3x3 tensor): Camera intrinsics matrix for each camera
Returns:
X_cam (BxHxWx3 tensor): 3D points in camera coordinates
valid_mask (BxHxW tensor): Mask indicating valid depth pixels
"""
(B, H, W) = depthmap.shape
device = depthmap.device
dtype = depthmap.dtype
camera_intrinsics = camera_intrinsics.float()
fx = camera_intrinsics[:, 0, 0]
fy = camera_intrinsics[:, 1, 1]
cx = camera_intrinsics[:, 0, 2]
cy = camera_intrinsics[:, 1, 2]
(v_grid, u_grid) = torch.meshgrid(torch.arange(H, dtype=dtype, device=device), torch.arange(W, dtype=dtype, device=device), indexing='ij')
u_grid = u_grid.unsqueeze(0)
v_grid = v_grid.unsqueeze(0)
z_cam = depthmap
x_cam = (u_grid - cx.view(B, 1, 1)) * z_cam / fx.view(B, 1, 1)
y_cam = (v_grid - cy.view(B, 1, 1)) * z_cam / fy.view(B, 1, 1)
X_cam = torch.stack([x_cam, y_cam, z_cam], dim=-1)
valid_mask = depthmap > 0.0
return (X_cam, valid_mask)
def depth_to_world_coords_points(depth_map: torch.Tensor, extrinsic: torch.Tensor, intrinsic: torch.Tensor, eps=1e-08) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
"""
Convert a batch of depth maps to world coordinates.
Args:
depth_map (torch.Tensor): (B, H, W) Depth map
extrinsic (torch.Tensor): (B, 4, 4) Camera extrinsic matrix (camera-to-world transformation)
intrinsic (torch.Tensor): (B, 3, 3) Camera intrinsic matrix
Returns:
world_coords_points (torch.Tensor): (B, H, W, 3) World coordinates
camera_points (torch.Tensor): (B, H, W, 3) Camera coordinates
point_mask (torch.Tensor): (B, H, W) Valid depth mask
"""
if depth_map is None:
return (None, None, None)
point_mask = depth_map > eps
(camera_points, _) = depth_to_camera_coords(depth_map, intrinsic)
R_cam_to_world = extrinsic[:, :3, :3]
t_cam_to_world = extrinsic[:, :3, 3]
world_coords_points = torch.einsum('bhwi,bji->bhwj', camera_points, R_cam_to_world) + t_cam_to_world[:, None, None, :]
return (world_coords_points, camera_points, point_mask)