|
|
|
|
|
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]) |
|
|
|
|
|
|