Download GeometryForcing/utils/camera_rotation_utils.py from BonanDing/worldmem-baseline-evals: direct link, hf CLI and curl.
- Browser
- Download file 2.91 kB
-
https://huggingface.co/BonanDing/worldmem-baseline-evals/resolve/main/GeometryForcing/utils/camera_rotation_utils.py
- Command line
-
hf download hf://BonanDing/worldmem-baseline-evals/GeometryForcing/utils/camera_rotation_utils.py
-
curl -L -o camera_rotation_utils.py https://huggingface.co/BonanDing/worldmem-baseline-evals/resolve/main/GeometryForcing/utils/camera_rotation_utils.py
2.91 kB
| """ | |
| camera rotation utils: | |
| follow the https://github.com/xizaoqu/WorldMem/issues/8 | |
| given the first camera pose, got a rotation sequence | |
| """ | |
| import torch | |
| import math | |
| import torch | |
| import math | |
| def rotate_single_pose_y(pose: torch.Tensor, seq_length: int) -> torch.Tensor: | |
| import math | |
| device = pose.device | |
| # [0:4] | |
| print(pose.shape) | |
| fx = pose[0:1] | |
| fy = pose[1:2] | |
| cx = pose[2:3] | |
| cy = pose[3:4] | |
| pad_1 = pose[4:5] | |
| pad_2 = pose[5:6] | |
| print(pad_1, pad_2, fx, fy, cx, cy) | |
| R = torch.stack([ | |
| pose[6:9], # R row 0 | |
| pose[10:13], # R row 1 | |
| pose[14:17], # R row 2 | |
| ], dim=0) # [3, 3] | |
| t = torch.stack([ | |
| pose[9], # t_x | |
| pose[13], # t_y | |
| pose[17], # t_z | |
| ], dim=0).reshape(3, 1) # [3, 1] | |
| thetas = torch.linspace(0, 2 * math.pi, seq_length, device=device) | |
| # 预先生成所有 R_y 矩阵,避免循环内重复创建tensor | |
| cos_t = torch.cos(thetas) | |
| sin_t = torch.sin(thetas) | |
| zeros = torch.zeros_like(thetas) | |
| ones = torch.ones_like(thetas) | |
| R_ys = torch.stack([ | |
| torch.stack([cos_t, zeros, sin_t], dim=1), | |
| torch.stack([zeros, ones, zeros], dim=1), | |
| torch.stack([-sin_t, zeros, cos_t], dim=1), | |
| ], dim=1) # [seq_length, 3, 3] | |
| print(fx.shape) # torch.Size([1]) | |
| rotated_poses = [] | |
| for R_y in R_ys: | |
| # 绕着 自己的y轴旋转式 | |
| R_new = R @ R_y # [3, 3] | |
| # 绕着 世界坐标系的y轴旋转 | |
| # R_new = R_y @ R # [3, 3] | |
| # 如果想旋转t,用 t_new = R_y @ t,否则保持不变 | |
| t_new = t # or t_new = R_y @ t | |
| # print(R_new[0].shape,t_new[0:1].shape) # torch.Size([3, 1]) | |
| cam_pose = torch.cat( | |
| [fx, fy, cx, cy, pad_1, pad_2, | |
| R_new[0], t_new[0], | |
| R_new[1], t_new[1], | |
| R_new[2], t_new[2]], dim=0 | |
| ) | |
| print(cam_pose) # torch.Size([18]) | |
| rotated_poses.append(cam_pose) | |
| return torch.stack(rotated_poses, dim=0) # [seq_length, 18] | |
| if __name__ == "__main__": | |
| from pathlib import Path | |
| camera_poses_dir="data/real-estate-10k-rotate-100/test_poses" | |
| files = sorted(Path(camera_poses_dir).glob("*.pt")) | |
| print(f"Found {len(files)} camera pose files in {camera_poses_dir}") | |
| for file in files: | |
| camera_poses = torch.load(file) | |
| print(f"Processing {file} with shape {camera_poses.shape}") | |
| # Rotate camera poses | |
| rotated_poses = rotate_single_pose_y(camera_poses[0], seq_length=256).squeeze(0) # [B, N, 16]() | |
| # Save rotated poses | |
| output_file = Path("data/real-estate-10k-rotate-100/test_poses") / file.name | |
| output_file.parent.mkdir(parents=True, exist_ok=True) | |
| torch.save(rotated_poses, output_file) | |
| print(f"Saved rotated poses to {output_file} with shape {rotated_poses.shape}") |