如何将 Eigen Jacobi SVD 与 Eigen Affine Matrix 结合使用

Posted

技术标签:

【中文标题】如何将 Eigen Jacobi SVD 与 Eigen Affine Matrix 结合使用【英文标题】:How to use Eigen Jacobi SVD with Eigen Affine Matrix 【发布时间】:2018-06-17 20:49:56 【问题描述】:

问题:我正在尝试使用 Eigen JacobiSVD 模块计算旋转矩阵的 SVD,以计算旋转矩阵的单值分解。

预期:我应该能够将 Eigen::Affine3d 类型的旋转矩阵传递给 svd 方法,然后使用 SVD 中的 U 和 V 生成一个新的 Eigen 类型的旋转矩阵::Affine3d。

观察到 svd 方法不接受我的 tSixDof 矩阵作为可接受的参数。

问题为什么我不能使用仿射矩阵作为输入?有没有更好的方法来执行这个操作?

// Resolve numerical errors in the rotation matrix by implementing the 
// orthogonal procrustes problem algorithm.

void SixDof::resolveRotation()

   //initial SixDof
   SixDof tSixDof;

   Eigen::Index n = tSixDof.rows();
   Eigen::Index m = tSixDof.rows();

   Eigen::Matrix3d U;
   Eigen::Matrix3d V;
   Eigen::Matrix3d R;

   Eigen::JacobiSVD<Eigen::Matrix3d> svd(tSixDof.rotation() 
   Eigen::ComputeFullU | Eigen::ComputeFullV);
   U = svd.matrixU();
   V = svd.matrixV();

   R = U*V.transpose();
   //Resolved SixDof
   tSixDof.rotation() = R;

 

SixDof 类

class SixDof : public Eigen::Affine3d 

public:
SixDof();
SixDof(const Eigen::Affine3d& aOther);
void resolveRotation();
;

【问题讨论】:

【参考方案1】:

3x3 旋转矩阵不是 Affine3D 变换。来自文档:“通用仿射变换由内部是 (Dim+1)^2 矩阵的 Transform 类表示。”。要执行 Procrustes 来调整嘈杂的旋转矩阵 M,您需要使用 3x3 特征矩阵(存储 M)调用 svd。

【讨论】:

谢谢,是的,我现在意识到了这一点,我现在正在使用方法 tSixDof.rotation() 而不是 tSixDof。但是,我不知道如何设置 SixDof 使用的旋转矩阵的元素。有什么想法吗? 您的问题不清楚,因为您没有给出 SixDoF 的类定义。 我刚刚添加了定义。感谢您的帮助。 我真的不会扩展 Affine 类。您的签名表明您没有向其添加任何额外有用的功能,最好避免继承 Eigen 类型。如果您的仿射变换矩阵是 A,您将通过 A.matrix().block(0,0,3,3) 获得嘈杂的旋转分量 谢谢 A.matrix().block(0,0,3,3) 是我需要的!

以上是关于如何将 Eigen Jacobi SVD 与 Eigen Affine Matrix 结合使用的主要内容,如果未能解决你的问题,请参考以下文章

为啥用 Eigen 和 OpenCV 计算的 SVD 左奇异向量具有不同的符号

Eigen学习之简单线性方程与矩阵分解

eigen奇异值分解是哪个函数

cv::Mat 转换为特征矩阵并返回

Eigen解线性方程组

矩阵奇异值分解简介及C++/OpenCV/Eigen的三种实现