我正在尝试估计两组点之间的3D旋转矩阵,我想通过计算协方差矩阵的SVD(例如C)来做到这一点,如下所示:

U,S,V = svd(C)
R = V * U^T


在我的情况下,C3x3。我为此使用Eigen的JacobiSVD模块,直到最近才发现它以列主格式存储矩阵。这让我感到困惑。

因此,在使用Eigen时,我应该做:
V*U.transpose()V.transpose()*U

另外,旋转是精确的,直到改变与最小奇异值对应的U列的正负号,使得R的行列式为正。假设最小奇异值的索引为minIndex

因此,当行列式为负数时,由于列的主要混乱,我应该这样做:

U.col(minIndex) *= -1 or U.row(minIndex) *= -1

谢谢!

最佳答案

这与存储行为主或列主存储的矩阵无关。 svd(C)给您:

U * S.asDiagonal() * V.transpose() == C


因此,最接近R的旋转C为:

R = U * V.transpose();


如果要将R应用于点p(存储为列向量),则可以执行以下操作:

q = R * p;


现在,您是否对R感兴趣或对它的逆向R.transpose()==V.transpose()*U取决于您。

奇异值缩放U的列,因此您应该反转列以获得det(U)=1。同样,与存储布局无关。

10-08 08:55