|
|
| import torch |
|
|
| import os |
|
|
|
|
| import os |
| import json |
| import torch |
| import numpy as np |
|
|
| from scipy.spatial.transform import Rotation as R |
|
|
| import pdb |
|
|
| def compute_relative_pose_matrix2( |
| pose_a, |
| pose_b |
| ) -> np.ndarray: |
| """ |
| 计算两个相机姿态(7元数组)之间的相对位姿,输出3×4相机矩阵 [R_rel | t_rel] |
| |
| 数学定义:相对位姿描述“从姿态A到姿态B的变换”,即: |
| - 若点P在姿态A的相机坐标系下坐标为P_A,在姿态B的相机坐标系下坐标为P_B, |
| 则满足 P_B = R_rel @ P_A + t_rel(R_rel为相对旋转矩阵,t_rel为相对平移向量) |
| |
| 参数: |
| pose_a: 参考姿态A,形状(7,)的数组/list,格式[tx_a, ty_a, tz_a, qx_a, qy_a, qz_a, qw_a] |
| - tx_a/ty_a/tz_a: 姿态A在世界坐标系的位置(平移向量) |
| - qx_a/qy_a/qz_a/qw_a: 姿态A的朝向(单位四元数,右手坐标系) |
| pose_b: 目标姿态B,格式与pose_a完全一致 |
| |
| 返回: |
| 3×4的相对位姿相机矩阵,前3列是3×3相对旋转矩阵R_rel,第4列是3×1相对平移向量t_rel |
| |
| 异常: |
| ValueError: 若输入姿态形状/格式不正确,或四元数非单位四元数 |
| """ |
| |
| |
| |
| |
| pose_a = np.asarray(pose_a, dtype=np.float64) |
| pose_b = np.asarray(pose_b, dtype=np.float64) |
| |
| if pose_a.shape != (7,): |
| raise ValueError(f"姿态A需为(7,)数组,实际输入形状{pose_a.shape}") |
| if pose_b.shape != (7,): |
| raise ValueError(f"姿态B需为(7,)数组,实际输入形状{pose_b.shape}") |
| |
| |
| t_a = pose_a[:3] |
| q_a = pose_a[3:] |
| t_b = pose_b[:3] |
| q_b = pose_b[3:] |
| |
| |
| q_a_norm = np.linalg.norm(q_a) |
| q_b_norm = np.linalg.norm(q_b) |
| if not np.isclose(q_a_norm, 1.0, atol=1e-4): |
| raise ValueError(f"姿态A的四元数非单位四元数,模长为{q_a_norm:.6f}(需接近1.0)") |
| if not np.isclose(q_b_norm, 1.0, atol=1e-4): |
| raise ValueError(f"姿态B的四元数非单位四元数,模长为{q_b_norm:.6f}(需接近1.0)") |
| |
| |
| |
| |
| |
| rot_a = R.from_quat(q_a) |
| rot_b = R.from_quat(q_b) |
| |
| |
| |
| rot_rel = rot_b * rot_a.inv() |
| R_rel = rot_rel.as_matrix() |
| |
| |
| |
| |
| |
| |
| |
| R_a_T = rot_a.inv().as_matrix().T |
| t_rel = R_a_T @ (t_b - t_a) |
| |
| |
| |
| |
| |
| relative_cam_matrix = np.hstack([R_rel, t_rel.reshape(3, 1)]) |
| |
| return relative_cam_matrix |
|
|
|
|
| def compute_relative_pose_matrix(pose1, pose2): |
| """ |
| 计算相邻两帧的相对位姿,返回3×4的相机矩阵 [R_rel | t_rel] |
| |
| 参数: |
| pose1: 第i帧的相机位姿,形状为(7,)的数组 [tx1, ty1, tz1, qx1, qy1, qz1, qw1] |
| pose2: 第i+1帧的相机位姿,形状为(7,)的数组 [tx2, ty2, tz2, qx2, qy2, qz2, qw2] |
| |
| 返回: |
| relative_matrix: 3×4的相对位姿矩阵,前3列是旋转矩阵R_rel,第4列是平移向量t_rel |
| """ |
| |
| t1 = pose1[:3] |
| q1 = pose1[3:] |
| t2 = pose2[:3] |
| q2 = pose2[3:] |
| |
| |
| rot1 = R.from_quat(q1) |
| rot2 = R.from_quat(q2) |
| rot_rel = rot2 * rot1.inv() |
| R_rel = rot_rel.as_matrix() |
| |
| |
| R1_T = rot1.as_matrix().T |
| t_rel = R1_T @ (t2 - t1) |
| |
| |
| relative_matrix = np.hstack([R_rel, t_rel.reshape(3, 1)]) |
| |
| return relative_matrix |
|
|
| encoded_data = torch.load( |
| os.path.join('/share_zhuyixuan05/zhuyixuan05/spatialvid/fdb39216-0d15-5f0f-a78f-c599913a4a2e_0000600_0000900', "encoded_video.pth"), |
| weights_only=False, |
| map_location="cpu" |
| ) |
|
|
| cam_data_ori = np.load('./poses.npy') |
|
|
| cam_data_seq_ori = cam_data_ori |
| print(cam_data_seq_ori.shape) |
| print('---------------------------') |
| cam_data = encoded_data['cam_emb'] |
|
|
| cam_data_seq = cam_data_seq_ori |
| cam_data_seq_inter = cam_data['extrinsic'] |
| print(cam_data_seq_inter.shape) |
| keyframe_original_idx = list(range(10)) |
|
|
| relative_cams = [] |
|
|
| for idx in keyframe_original_idx: |
| cam_prev = cam_data_seq[idx] |
| cam_next = cam_data_seq[idx+1] |
|
|
| relative_cam = compute_relative_pose_matrix2(cam_prev,cam_next) |
|
|
| relative_cams.append(torch.as_tensor(relative_cam[:3,:])) |
| relative_cam = compute_relative_pose_matrix2(cam_data_seq_inter[0],cam_data_seq_inter[-1]) |
|
|
| relative_cams.append(torch.as_tensor(relative_cam[:3,:])) |
|
|
| print(relative_cams[-1]) |
|
|
|
|