[Insight-users] Affine transform based registration in 3D
Luis Ibanez
luis.ibanez at kitware.com
Fri Dec 11 10:36:50 EST 2009
Hi Marco,
You got most of it right.
The rotation aspect, however, requires a bit more work.
The AffineTransform can give you a combination of
* Shearing
* Scaling
* Rotation
So, first you must separate the rotational part of the Matrix
from the rest (scaling and shearing). This can be done by
using Polar decomposition, for Details, please See:
http://www.cmake.org/pipermail/insight-users/2006-August/019025.html
Once you extract the Orthogonal matrix (that represents
rotation) out of the Affine Matrix, you can feed it into a
Versor, by using the method:
versor.SetMatrix( orthogonalMatrix )
and finally, from the Versor, you can get:
double angle = versor.GetAngle();
VectorType rotationAxis = versor.GetAxis();
that will tell you how many *radians* is the current Affine
transform rotating, and around what axis in space.
Regards,
Luis
-----------------------------------
On Fri, Dec 11, 2009 at 9:41 AM, marco giordano <marco.giord at gmail.com> wrote:
> Hi,
>
> I am running an Affine transform registration in 3D (basically
> ImageRegistration9.cxx).
>
> In order to support 3D mode, appart from some obvious changes, I did the
> following:
>
> Extend the optimizer scale:
>
> ....
> optimizerScales[0] = 1.0;
> optimizerScales[1] = 1.0;
> optimizerScales[2] = 1.0;
> optimizerScales[3] = 1.0;
> optimizerScales[4] = 1.0;
> optimizerScales[5] = 1.0;
> optimizerScales[6] = 1.0;
> optimizerScales[7] = 1.0;
> optimizerScales[8] = 1.0;
> optimizerScales[9] = translationScale;
> optimizerScales[10] = translationScale;
> optimizerScales[11] = translationScale;
> ...
>
>
> Get the full set of final parameters to print out
>
> ....
> const double finalRotationCenterX = transform->GetCenter()[0];
> const double finalRotationCenterY = transform->GetCenter()[1];
> const double finalRotationCenterZ = transform->GetCenter()[2];
> const double finalTranslationX = finalParameters[9];
> const double finalTranslationY = finalParameters[10];
> const double finalTranslationZ = finalParameters[11];
> ....
>
> Then I guess I must retrieve the rotation angle by SVD
> which I guess it is run on the 3x3 matrix but I do not know in which order I
> must pick up the value. I am not sure that I got
> this right but my guess would be:
>
> (Guess)
> vnl_matrix<double> p(3, 3);
> p[0][0] = (double) finalParameters[0];
> p[0][1] = (double) finalParameters[1];
> p[0][2] = (double) finalParameters[2];
>
> p[1][0] = (double) finalParameters[3];
> p[1][1] = (double) finalParameters[4];
> p[1][2] = (double) finalParameters[5];
>
> p[2][0] = (double) finalParameters[6];
> p[2][1] = (double) finalParameters[7];
> p[2][2] = (double) finalParameters[8];
>
>
> vnl_svd<double> svd(p);
> vnl_matrix<double> r(3, 3);
> r = svd.U() * vnl_transpose(svd.V());
> double angle = asin(r[1][0]);
>
> std::cout << " Scale 1 = " << svd.W(0) <<
> std::endl;
> std::cout << " Scale 2 = " << svd.W(1) <<
> std::endl;
> std::cout << " Scale 3 = " << svd.W(3) <<
> std::endl;
> std::cout << " Angle (degrees) = " << angle * 45.0 / atan(1.0) <<
> std::endl;
>
>
> Does that make sense ?
>
> I would appreciate some help on that.
>
> Thank you
>
> --
> Marco G.
>
>
> _____________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Kitware offers ITK Training Courses, for more information visit:
> http://www.kitware.com/products/protraining.html
>
> Please keep messages on-topic and check the ITK FAQ at:
> http://www.itk.org/Wiki/ITK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.itk.org/mailman/listinfo/insight-users
>
>
More information about the Insight-users
mailing list