4DGaussians/utils/pose_utils.py
2023-12-02 14:13:12 +08:00

92 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import numpy as np
from scipy.spatial.transform import Rotation as R
from scene.utils import Camera
from copy import deepcopy
def rotation_matrix_to_quaternion(rotation_matrix):
"""将旋转矩阵转换为四元数"""
return R.from_matrix(rotation_matrix).as_quat()
def quaternion_to_rotation_matrix(quat):
"""将四元数转换为旋转矩阵"""
return R.from_quat(quat).as_matrix()
def quaternion_slerp(q1, q2, t):
"""在两个四元数之间进行球面线性插值SLERP"""
# 计算两个四元数之间的点积
dot = np.dot(q1, q2)
# 如果点积为负,取反一个四元数以保证最短路径插值
if dot < 0.0:
q1 = -q1
dot = -dot
# 防止数值误差导致的问题
dot = np.clip(dot, -1.0, 1.0)
# 计算插值参数
theta = np.arccos(dot) * t
q3 = q2 - q1 * dot
q3 = q3 / np.linalg.norm(q3)
# 计算插值结果
return np.cos(theta) * q1 + np.sin(theta) * q3
def bezier_interpolation(p1, p2, t):
"""在两点之间使用贝塞尔曲线进行插值"""
return (1 - t) * p1 + t * p2
def linear_interpolation(v1, v2, t):
"""线性插值"""
return (1 - t) * v1 + t * v2
def smooth_camera_poses(cameras, num_interpolations=5):
"""对一系列相机位姿进行平滑处理,通过在每对位姿之间插入额外的位姿"""
smoothed_cameras = []
smoothed_times = []
total_poses = len(cameras) - 1 + (len(cameras) - 1) * num_interpolations
time_increment = 10 / total_poses
for i in range(len(cameras) - 1):
cam1 = cameras[i]
cam2 = cameras[i + 1]
# 将旋转矩阵转换为四元数
quat1 = rotation_matrix_to_quaternion(cam1.orientation)
quat2 = rotation_matrix_to_quaternion(cam2.orientation)
for j in range(num_interpolations + 1):
t = j / (num_interpolations + 1)
# 插值方向
interp_orientation_quat = quaternion_slerp(quat1, quat2, t)
interp_orientation_matrix = quaternion_to_rotation_matrix(interp_orientation_quat)
# 插值位置
interp_position = linear_interpolation(cam1.position, cam2.position, t)
# 计算插值时间戳
interp_time = i*10 / (len(cameras) - 1) + time_increment * j
# 添加新的相机位姿和时间戳
newcam = deepcopy(cam1)
newcam.orientation = interp_orientation_matrix
newcam.position = interp_position
smoothed_cameras.append(newcam)
smoothed_times.append(interp_time)
# 添加最后一个原始位姿和时间戳
smoothed_cameras.append(cameras[-1])
smoothed_times.append(1.0)
print(smoothed_times)
return smoothed_cameras, smoothed_times
# # 示例:使用两个相机位姿
# cam1 = Camera(np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]), np.array([0, 0, 0]))
# cam2 = Camera(np.array([[0, -1, 0], [1, 0, 0], [0, 0, 1]]), np.array([1, 1, 1]))
# # 应用平滑处理
# smoothed_cameras = smooth_camera_poses([cam1, cam2], num_interpolations=5)
# # 打印结果
# for cam in smoothed_cameras:
# print("Orientation:\n", cam.orientation)
# print("Position:", cam.position)