Search code examples
c++computer-visioneigensvd

How to use Eigen Jacobi SVD with Eigen Affine Matrix


Problem :I am trying to calculate the SVD of a rotation matrix using the Eigen JacobiSVD module to calculate the single value decomposition of a rotation matrix.

Expected : I should be able to pass my rotation matrix of type Eigen::Affine3d to the svd method and then use the U and V from the SVD to produce a new rotation matrix of type Eigen::Affine3d.

Observed The svd method does not accpet my tSixDof matrix as an acceptable parameter.

Question Why can't I use an affine matrix as the input? Is there a better way to perform this operation?

// 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;

 }

The SixDof class

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

Solution

  • A 3x3 rotation matrix is not an Affine3D transform. From the documentation: "Generic affine transformations are represented by the Transform class which internally is a (Dim+1)^2 matrix.". To perform Procrustes for adjusting your noisy rotation matrix M you need to be calling svd with a 3x3 Eigen matrix (storing M).