奇异值分解(SVD)在3D骨骼旋转中的应用:原理与实现

奇异值分解(SVD)在3D骨骼旋转中的应用:原理与实现

引言

在做在三维计算机视觉的人物姿态识别的项目过程中,遇到一个问题,摄像头只有一个,只采集了一个正面的数据,但是在实际测试过程中,摄像头的位置可能是人物的其他角度,比如30度或者随机。为了做数据增强,将这些采集的数据3D骨骼数据,全部做每个角度旋转的数据增强。

一、 实现思路

在 3D 空间中,对骨骼数据进行旋转通常有两种场景:

  1. 已知目标角度:直接构造旋转矩阵并相乘。
  2. 已知目标姿态(但不知具体角度):通过 SVD 求解最优旋转矩阵(Kabsch 算法)。

该项目符合场景 1 的设定,但使用场景 2 的算法流程。具体思路如下:

  1. 定义数据 :构建一个 N×3N \times 3N×3 的矩阵存储 3D 骨骼关节坐标。
  2. 中心化:将骨骼中心点平移至原点,消除平移分量,仅保留旋转信息。
  3. 构造目标 :根据指定角度(如 30°)构造真实的旋转矩阵 RtrueR_{true}Rtrue,生成旋转后的目标数据 YYY。
  4. SVD 求解 :计算原始数据与目标数据的交叉协方差矩阵 H=XTYH = X^T YH=XTY,对其进行 SVD 分解,按公式 R=VUTR = V U^TR=VUT 提取纯旋转矩阵。
  5. 应用旋转 :将求得的旋转矩阵 RRR 乘回原始数据,完成旋转对齐。

二、 代码实现

以下代码仅定义了一个变量 skeleton 作为 3D 骨骼数据,其余均为过程变量。

python 复制代码
import numpy as np

==

1. 定义 3D 骨骼数据 (6个关节, xyz坐标)

==

skeleton = np.array([
    [0, 0, 0],    # 髋部
    [0, 10, 0],   # 脊柱
    [5, 10, 0],   # 右肩
    [-5, 10, 0],  # 左肩
    [5, 20, 0],   # 右肘
    [-5, 20, 0]   # 左肘
], dtype=float)

==

2. 中心化(消除平移,聚焦旋转)

==

centroid = skeleton.mean(axis=0)
skeleton_centered = skeleton - centroid

==

3. 设定目标角度并构造真实旋转矩阵

==

angle = np.radians(30)  # 转为弧度
绕 Y 轴旋转的矩阵(右手系顺时针)

R_true = np.array([
    [np.cos(angle), 0, np.sin(angle)],
    [0, 1, 0],
    [-np.sin(angle), 0, np.cos(angle)]
])

生成旋转后的目标数据(模拟已知目标姿态)

skeleton_target = skeleton_centered @ R_true.T

==

4. 利用 SVD 求解旋转矩阵 (Kabsch 算法)

==

4.1 计算交叉协方差矩阵 H

H = skeleton_centered.T @ skeleton_target

4.2 对 H 进行 SVD 分解

U, S, Vt = np.linalg.svd(H)
V = Vt.T

4.3 组合出纯旋转矩阵 R_svd

R_svd = V @ U.T

4.4 确保是纯旋转(行列式为 +1,避免反射)

if np.linalg.det(R_svd) < 0:
    V[:, -1] *= -1
    R_svd = V @ U.T

==

5. 应用 SVD 求得的旋转矩阵

==

skeleton_rotated = skeleton_centered @ R_svd.T + centroid

验证结果

print("SVD 求得的旋转矩阵是否与真实矩阵一致:", np.allclose(R_svd, R_true))

三、 原理解析

Q1: 代码中的 @ 运算符是什么意思?

@ 是 Python 中用于矩阵乘法的运算符。

  • 对于 NumPy 数组,A @ B 等价于 np.dot(A, B)。
  • 它执行的是线性代数中的矩阵乘法(行乘列求和),而非逐元素相乘(* 运算符)。
  • 在代码中,skeleton_centered.T @ skeleton_target 执行了 (3×N)×(N×3)(3 \times N) \times (N \times 3)(3×N)×(N×3) 的乘法,得到一个 3×33 \times 33×3 的矩阵。

Q2: np.linalg.svd 背后的数学原理是什么?

np.linalg.svd(H) 对矩阵 HHH 进行奇异值分解,将其拆解为三个矩阵的乘积:

H=UΣVT H = U \Sigma V^T H=UΣVT

  • UUU:左奇异向量矩阵(m×mm \times mm×m,正交矩阵)。
  • Σ\SigmaΣ:奇异值矩阵(m×nm \times nm×n,对角线为非负实数,按降序排列)。
  • VTV^TVT:右奇异向量矩阵的转置(n×nn \times nn×n,正交矩阵)。

数值计算原理 :SVD 通常通过求解 HTHH^T HHTH 和 HHTH H^THHT 的特征值与特征向量来间接获得。对 HTHH^T HHTH 做特征分解,其特征向量构成 VVV,特征值的平方根构成 Σ\SigmaΣ;对 HHTH H^THHT 做特征分解,其特征向量构成 UUU。

Q3: 为什么在进行奇异值分解之前要计算协方差矩阵 HHH?

计算 H=XTYH = X^T YH=XTY 是为了将"寻找最优旋转"这一几何问题转化为"最大化矩阵迹"的代数问题。

  • 目标函数 :我们希望找到旋转矩阵 RRR 使得 ∥XR−Y∥F2\| X R - Y \|_F^2∥XR−Y∥F2 最小。
  • 化简 :展开后可得,最小化该误差等价于最大化 tr(RT(XTY))\text{tr}(R^T (X^T Y))tr(RT(XTY)),即 tr(RTH)\text{tr}(R^T H)tr(RTH)。
  • SVD 的作用 :数学上已证明,对于正交矩阵 RRR,使得 tr(RTH)\text{tr}(R^T H)tr(RTH) 最大化的解是 R=VUTR = V U^TR=VUT(其中 H=UΣVTH = U \Sigma V^TH=UΣVT)。因此,计算 HHH 是为了给 SVD 提供一个能够解码出最优旋转的"关系矩阵"。

Q4: 为什么协方差矩阵是 H = skeleton_centered.T @ skeleton_target 这样计算的?

这涉及矩阵乘法的维度与内积的几何意义。

  • 维度匹配 :skeleton_centered 是 N×3N \times 3N×3,转置后为 3×N3 \times N3×N。与目标 N×3N \times 3N×3 相乘,得到 3×33 \times 33×3 的矩阵 HHH。
  • 元素含义 :HHH 的第 iii 行第 jjj 列元素为 Hij=∑k=1NXkiYkjH_{ij} = \sum_{k=1}^N X_{ki} Y_{kj}Hij=∑k=1NXkiYkj。这表示源点集的第 iii 个坐标轴与目标点集的第 jjj 个坐标轴之间的内积。
  • 协方差本质 :在中心化后,内积正比于两个向量之间的协方差。HHH 打包了原始坐标系与目标坐标系之间所有轴的对应关系,描述了从一个空间到另一个空间的线性变换强度与方向。

Q5: 为什么需要检查 np.linalg.det(R_svd) < 0 并修正?

SVD 分解得到的 UUU 和 VVV 是正交矩阵,因此 R=VUTR = V U^TR=VUT 也是正交矩阵,但它可能包含反射(即行列式为 −1-1−1)。

  • 纯旋转要求 :在三维空间中,纯旋转矩阵的行列式必须为 +1+1+1。
  • 修正方法 :若 det⁡(VUT)<0\det(V U^T) < 0det(VUT)<0,则将 VVV 的最后一列乘以 −1-1−1(等价于在 Σ\SigmaΣ 中引入一个负号),重新计算 R=VUTR = V U^TR=VUT,此时行列式变为 +1+1+1,确保得到的是纯旋转而非反射变换。
相关推荐
追烽少年x2 小时前
从零构建一个3D点云预览器:Python + PySide6 + pyqtgraph 实战
python·3d
西红柿炖牛腩3541 天前
Three.js 模型体积优化:Draco/Meshopt 压缩与 DRACOLoader 配置的 4 个步骤
javascript·3d·性能优化
JAI科研1 天前
CT重建(二) | 3D高斯泼溅:实时渲染的革命
图像处理·人工智能·计算机视觉·3d·视觉检测·ct重建
李游Leo1 天前
HarmonyOS 7 + Spatial Recon Kit-C++:3DGS 输入帧内参与位姿的版本一致性门禁【鸿蒙心迹】
c++·3d·harmonyos
HwJack202 天前
【共创稿事节】HarmonyOS 7空间信息层级:焦点、景深与注意力引导
3d·华为·harmonyos·空间计算
小师兄吃牛肉2 天前
ANSYS EMA3D 2025 R2 专业安装详解:系统级电磁兼容与电磁干扰仿真平台全解析
3d
HwJack202 天前
【共创稿事节】HarmonyOS 7是3DGS 端侧重建:空间建模类应用的设计机会
3d·华为·harmonyos
I Am a robert girl2 天前
从频率到几何:GA-EIRFS 如何重新思考长尾 3D 检测的采样逻辑
3d·3d目标检测·nuscenes·lidar·数据采样·长尾分布·类别不平衡
李游Leo3 天前
HarmonyOS 7 + Spatial Recon Kit-Core File Kit:3DGS 重建产物的原子发布与中断恢复【鸿蒙心迹】
3d·华为·harmonyos