sanjeev mk
sanjeev mk

Reputation: 4346

Eigen library, Jacobi SVD

I'm trying to estimate a 3D rotation matrix between two sets of points, and I want to do that by computing the SVD of the covariance matrix, say C, as follows:

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

C in my case is 3x3 . I am using the Eigen's JacobiSVD module for this and I only recently found out that it stores matrices in column-major format. So that has had me confused.

So, when using Eigen, should I do: V*U.transpose() or V.transpose()*U ?

Additionally, the rotation is accurate upto changing the sign of the column of U corresponding to the smallest singular value,such that determinant of R is positive. Let's say the index of the smallest singular value is minIndex .

So when the determinant is negative, because of the column major confusion, should I do:

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

Thanks!

Upvotes: 0

Views: 1789

Answers (1)

ggael
ggael

Reputation: 29265

This has nothing to do with matrices being stored row-major or column major. svd(C) gives you:

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

so the closest rotation R to C is:

R = U * V.transpose();

If you want to apply R to a point p (stored as column-vector), then you do:

q = R * p;

Now whether you are interested R or its inverse R.transpose()==V.transpose()*U is up to you.

The singular values scale the columns of U, so you should invert the columns to get det(U)=1. Again, nothing to do with storage layout.

Upvotes: 2

Related Questions