下面的旋转矩阵近似的函数,分别调用了numpy和Eigen里面的SVD函数,得到了不同的结果:
Matrix3d ProjectToSO3(Matrix3d mat)
{
JacobiSVD<Eigen::MatrixXd> svd(mat, ComputeThinU | ComputeThinV );
Matrix3d Vh = svd.matrixV(), U = svd.matrixU();
Matrix3d R = U*Vh.transpose();
return R;
}
U:
0.536118 0.594167 0.59962
0.0738052 -0.740602 0.667878
0.840911 -0.313806 -0.440903
def ProjectToSO3(mat):
U, s, Vh = np.linalg.svd(mat)
R = np.dot(U, Vh)
return R
U:
array([[ 0.53611771, -0.5941667 , -0.59961966],
[ 0.07380517, 0.74060215, -0.66787817],
[ 0.84091058, 0.31380629, 0.4409025 ]])
原因:
对于
A
=
U
Σ
V
T
A=U\Sigma V^T
A=UΣVT 与
A
=
−
U
Σ
(
−
V
T
)
A=-U\Sigma( -V^T)
A=−UΣ(−VT)等价,所以符号可能不同,而特征值顺序不同也会导致特征向量的顺序不同。
另外Eigen返回的是 V V V,而numpy是 V T V^T VT,这点需要注意。