-1

I'm trying to convert an Eigen 3x3 rotation matrix to a quaternion using this code:

//m_labelMatrix : raw data of vtk4x4 matrix4d.
//m_transformationMatrix : Eigen4x4 matrix4d. 
m_transformationMatrix = Eigen::Map<Eigen::Matrix4d>(m_labelMatrix);        
m_transformationMatrix.transposeInPlace();
//m_affinedMatrix : affine3d matrix. 
m_affinedMatrix = m_transformationMatrix;
auto label_pos = m_affinedMatrix.translation();
auto rotationMatrix = m_affinedMatrix.linear();
auto scaleX = rotationMatrix.col(0).norm();
auto scaleY = rotationMatrix.col(1).norm();
auto scaleZ = rotationMatrix.col(2).norm();

// Make my rotation matrix orthogonal.
rotationMatrix.col(0).normalize();
rotationMatrix.col(1).normalize();
rotationMatrix.col(2) = rotationMatrix.col(0).cross(rotationMatrix.col(1));
rotationMatrix.col(2).normalize();
rotationMatrix.col(0) = rotationMatrix.col(1).cross(rotationMatrix.col(2));
rotationMatrix.col(0).normalize();


Eigen::Quaterniond q(rotationMatrix);

But, when I try to convert back to rotation matrix i get the same matrix with some different values(I think it is an Eigen rounding problem):

  rotationMatrix = q.normalized().matrix();
  /*3.02303  0.484642 -0.124911  
  -0.559522   2.94976 -0.217941 
  0.259569   0.71415  0.984962  */ 
  • 2
    Your matrix is not a rotation matrix, it clearly includes non uniform scaling and a symmetry. – ggael Apr 23 '18 at 12:15
  • 1
    I find it hard to believe that `q.normalized().matrix();` will result in a matrix which is not orthonormal. Show your actual code and your actual output. (And as @ggael said: If the input matrix involves scaling and a reflection, the resulting quaternion is likely spurious ...) – chtz Apr 23 '18 at 13:12
  • Sorry, I updated my code to. I know that my matrix is not othrogonal i resolved this. –  Apr 24 '18 at 05:48
  • A cleaner way to extract the rotational part of a transformation is to use `m_affinedMatrix.rotation()`. And could you print the actual result of `q.normalized().matrix()`? – chtz Apr 24 '18 at 12:30

1 Answers1

0

There is a method for conversion the rotation matrix with noise https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation#Conversion_to_and_from_the_matrix_representation

"Fitting quaternions"

with Eigen , it will look like

Eigen::Matrix<Scalar, 4, 4> c;
c(0, 0) = xx - yy - zz; c(0, 1) = yx + xy; c(0, 2) = zx + xz; c(0, 3) = yz - zy;
c(1, 0) = yx + xy; c(1, 1) = yy - xx - zz; c(1, 2) = zy + yz; c(1, 3) = zx - xz;
c(2, 0) = zx + xz; c(2, 1) = zy + yz; c(2, 2) = zz - xx - yy; c(2, 3) = xy - yx;
c(3, 0) = yz - zy; c(3, 1) = zx - xz; c(3, 2) = xy - yx; c(3, 3) = xx + yy + zz;
c /= 3.0;

Eigen::SelfAdjointEigenSolver<Matrix44> es(c);
typename Vector4::Index maxIdx;
es.eigenvalues().maxCoeff(&maxIdx);
Vector4 xyzw = es.eigenvectors().col(maxIdx);
ggael
  • 28,425
  • 2
  • 65
  • 71
minorlogic
  • 1,872
  • 1
  • 17
  • 24