3. 刚体变换与位姿表示:旋转矩阵、欧拉角、四元数、平移向量,以及齐次变换矩阵的构建与分解

在3D视觉与手眼标定中,刚体变换是描述物体在三维空间中位置和姿态变化的核心数学工具。一个刚体在运动过程中,其内部任意两点之间的距离保持不变,这种变换由旋转(姿态)和平移(位置)两部分组成。本章将系统梳理旋转矩阵、欧拉角、四元数、平移向量以及齐次变换矩阵的数学定义、相互转换关系及工程应用。

3.1 旋转的三种主流表示方法

旋转描述了刚体坐标系相对于参考坐标系的朝向。在机器人学和计算机视觉中,最常用的三种表示方法为:旋转矩阵、欧拉角和四元数。每种方法都有其独特的优缺点,适用于不同的场景。

表示方法 维度 优点 缺点 典型应用
旋转矩阵 3×3 (9个参数) 无奇异性;可直接用于向量旋转;组合方便 参数冗余;不直观;需满足正交性约束 底层计算、OpenCV、PCL
欧拉角 3个角度 直观易理解;参数最少 存在万向锁(Gimbal Lock);顺序依赖 人机交互、飞行器姿态显示
四元数 4个参数 无奇异性;插值平滑;计算效率高 不直观;需归一化约束 机器人运动规划、SLAM、IMU融合

3.1.1 旋转矩阵

旋转矩阵 R 是一个3×3的正交矩阵,满足 RTR = I 且 det(R) = +1。它描述了从一个坐标系到另一个坐标系的线性映射。对于三维空间中的向量 v,旋转后的向量 v' 为:

v' = R · v

绕三个坐标轴的基本旋转矩阵如下:

  • 绕X轴旋转角度θ:
    Rx(θ) = [[1, 0, 0], [0, cosθ, -sinθ], [0, sinθ, cosθ]]
  • 绕Y轴旋转角度θ:
    Ry(θ) = [[cosθ, 0, sinθ], [0, 1, 0], [-sinθ, 0, cosθ]]
  • 绕Z轴旋转角度θ:
    Rz(θ) = [[cosθ, -sinθ, 0], [sinθ, cosθ, 0], [0, 0, 1]]
工程提示: 在手眼标定中,旋转矩阵是中间计算的标准形式。OpenCV的 cv::Rodrigues() 函数可实现旋转矩阵与旋转向量(轴角)之间的高效转换。

3.1.2 欧拉角

欧拉角将旋转分解为三个依次绕坐标轴的旋转。常见的顺序有 ZYX(偏航-俯仰-滚转)和 ZXZ 等。以 ZYX 顺序为例:

R = R_z(yaw) · R_y(pitch) · R_x(roll)

其中 yaw(偏航角)、pitch(俯仰角)、roll(滚转角)分别对应绕 Z、Y、X 轴的旋转角度。

万向锁问题: 当 pitch = ±90° 时,yaw 和 roll 的旋转轴重合,导致丢失一个自由度,姿态无法唯一确定。这是欧拉角在机器人控制中需要特别注意的陷阱。

3.1.3 四元数

四元数 q 由一个实部和三个虚部组成:q = w + xi + yj + zk,其中 w 为标量部分,(x, y, z) 为向量部分,且满足 w² + x² + y² + z² = 1。四元数表示绕单位向量 u 旋转角度 θ:

q = [cos(θ/2), u_x·sin(θ/2), u_y·sin(θ/2), u_z·sin(θ/2)]

四元数的乘法运算可组合旋转,且避免了欧拉角的奇异性,是机器人运动规划中的首选表示。

3.2 平移向量

平移向量 t = [tx, ty, tz]T 描述了坐标系原点之间的位移。在刚体变换中,平移与旋转是解耦的:旋转先作用于向量方向,平移再作用于位置。

对于空间中的一点 p,从坐标系 {A} 到坐标系 {B} 的变换为:

p_B = R_AB · p_A + t_AB

其中 R_AB 是 {A} 到 {B} 的旋转矩阵,t_AB 是 {A} 原点在 {B} 中的坐标。

3.3 齐次变换矩阵的构建与分解

为了将旋转和平移统一为线性运算,引入齐次变换矩阵 T,它是一个4×4的矩阵:

T = [[R, t],
     [0, 1]]

其中 R 为3×3旋转矩阵,t 为3×1平移向量,最后一行固定为 [0, 0, 0, 1]。使用齐次坐标 p̃ = [x, y, z, 1]T,变换可简洁表示为:

p̃_B = T_AB · p̃_A

齐次变换矩阵的逆矩阵为:

T_inv = [[R^T, -R^T · t],
         [0,   1]]

这避免了直接求逆的复杂计算,在标定中频繁使用。

核心公式: 齐次变换矩阵的链式法则 —— 若已知 T_AB 和 T_BC,则 T_AC = T_AB · T_BC。这是手眼标定中构建闭环方程的基础。

3.4 刚体变换关系图

下图展示了从旋转矩阵、欧拉角、四元数到齐次变换矩阵的完整转换路径,以及它们在手眼标定中的角色。

刚体变换表示方法转换关系图 刚体变换表示方法转换关系 旋转矩阵 R 3×3 正交矩阵 欧拉角 (yaw, pitch, roll) 直观但存在万向锁 四元数 q w + xi + yj + zk 平移向量 t [tx, ty, tz]^T 齐次变换矩阵 T T = [[R, t], [0, 1]] 4×4 转换 转换 说明:手眼标定中,通常使用四元数进行插值与优化,使用旋转矩阵进行底层计算,最终统一为齐次变换矩阵参与闭环求解。

3.5 齐次变换矩阵的分解

在实际标定中,经常需要从已知的齐次变换矩阵 T 中分解出旋转矩阵 R 和平移向量 t。分解过程非常直接:

R = T[0:3, 0:3]   # 左上角3×3子矩阵
t = T[0:3, 3]     # 右上角3×1子向量

进一步,若需要从 R 中提取欧拉角或四元数,可使用以下方法:

  • 旋转矩阵 → 欧拉角(ZYX顺序):
    pitch = asin(-R[2][0])
    yaw = atan2(R[1][0], R[0][0])
    roll = atan2(R[2][1], R[2][2])
  • 旋转矩阵 → 四元数:
    通过求解矩阵的迹和特征值,或使用标准转换公式。
代码示例: 使用Python和NumPy实现齐次变换矩阵的构建与分解。
import numpy as np

# 构建齐次变换矩阵
def build_transform(R, t):
    T = np.eye(4)
    T[0:3, 0:3] = R
    T[0:3, 3] = t.flatten()
    return T

# 分解齐次变换矩阵
def decompose_transform(T):
    R = T[0:3, 0:3]
    t = T[0:3, 3]
    return R, t

# 示例:绕Z轴旋转30度,平移(1, 2, 3)
theta = np.radians(30)
R = np.array([[np.cos(theta), -np.sin(theta), 0],
              [np.sin(theta),  np.cos(theta), 0],
              [0, 0, 1]])
t = np.array([1, 2, 3])
T = build_transform(R, t)
print("齐次变换矩阵:\n", T)

R_out, t_out = decompose_transform(T)
print("分解旋转矩阵:\n", R_out)
print("分解平移向量:\n", t_out)

3.6 刚体变换的链式法则与标定闭环

在手眼标定中,机器人末端执行器与相机之间的变换关系通常通过链式法则建立。设:

  • T_base_to_ee:机器人基座到末端执行器的变换(由机器人正运动学提供)
  • T_ee_to_cam:末端执行器到相机的变换(待标定的手眼矩阵)
  • T_cam_to_obj:相机到标定物体的变换(由视觉算法提供)
  • T_base_to_obj:机器人基座到标定物体的变换(固定不变)

闭环方程为:

T_base_to_ee · T_ee_to_cam · T_cam_to_obj = T_base_to_obj

通过多次移动机器人并记录对应的变换对,即可求解出 T_ee_to_cam。这正是下一章将要深入讲解的手眼标定核心算法。

关键总结: 刚体变换的数学基础是手眼标定的基石。旋转矩阵提供精确计算,四元数避免奇异性,齐次变换矩阵统一表达。掌握这些表示方法及其转换,是理解后续标定算法和实战案例的前提。