[Insight-users] Volume not perfectly rotated
Luis Ibanez
luis.ibanez at kitware.com
Thu Oct 11 11:44:24 EDT 2007
Hi Nic,
It seems that you have not initialized the Center of Rotation of the
VersorRigid3DTransform.
By default that center is at (0,0,0), so it is likely that your image
if being flipped around the corner of the image, not around the center
of the image.
You may want to compute the center of the image in physical coordinates
and use that as the center of rotation for the VersorRigid3DTransform.
You will find examples on how to compute the center of the image in
the ITK Software Guide.
http://www.itk.org/ItkSoftwareGuide.pdf
It comes down to
for( i=0; i<3; i++)
{
Center[i] = Origin[i] + Size[i] * Spacing[i] / 2.0
}
-----
Also, Please aware that *you are not using the Quaternion correctly*.
//: Construct quaternion from Euler Angles,
// That is a rotation about the X axis, followed by Y, followed by
// the Z axis, using a fixed reference frame.
vnl_quaternion(T theta_X, T theta_Y, T theta_Z);
That is not the order of the rotational sequence that you are assuming.
It is too bad that so many people have grown used to Euler angles.
They are one of the *worst things* that have made their way in
computer graphics. They are clumsy and provide a very poor
representation of the SO(3) rotational space
http://en.wikipedia.org/wiki/SO%283%29
Euler angles have impoverished the understanding of generations of
engineers on the nature of rotational space and crippled them to
think in Cartesian schems instead of embracing the natural properties
of the rotational space. That results in uncountable pieces of software
that require "if" conditions when computing rotational components.
---------
The correct way of composing rotations in space when using
Quaternions is to define a quaternion for each one of the
intermediate rotations and then use the Quaternion composition
method:
vnl_quaternion::operator*() in VNL
or
itkVersor::operator*() in ITK
In your case:
> What I do is simply initialize the versorRigid3dTransform with a 180°
> rotation around y-axis and -94.55 rotation around z-axis.
You should do:
typedef itk::Versor<double> VersorType;
typedef VersorType::VectorType AxisType;
typedef VersorType::ValueType ValueType;
AxisType axis1; // Rotation Axis = Y
axis1[0] = 0.0;
axis1[0] = 1.0;
axis1[0] = 0.0;
ValueType angle1 = 3.141516...
VersorType versor1;
versor1.Set( axis1, angle1 ); // 180 degrees around Y
AxisType axis2; // Rotation Axis = Z
axis2[0] = 0.0;
axis2[0] = 0.0;
axis2[0] = 1.0;
ValueType angle2 = 3.141516 * ( -94.55 ) / 180.0;
VersorType versor2;
versor2.Set( axis2, angle2 ); // -94.55 degrees around Z
VersorType versor3 = versor2 * versor1;
The last variable "versor3" will contain the correct rotation
expressed in terms of a unit quaternion.
Note that most of the time, when people use Quaternions,
what they actually want to use are Versors.
Quaternions can represent rotation *and scaling* in space,
while Versors are limited to rotations. Versors are equivalent
to Unit-Quaternions.
You may want to read more about Quaternions and their properties:
http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
and the ITK Quaternion Tutorials:
http://www.itk.org/CourseWare/Training/QuaternionsI.pdf
http://www.itk.org/CourseWare/Training/QuaternionsII.pdf
Regards,
Luis
----------------
Nic wrote:
> Hi all,
> I have a strange behaviour I would like to correct in my initialisation.
> I used quaternion for rotation initialisation like this, as previously
> adviced :
>
> *******************************************************
> double RotX = angleX * vnl_math::pi / 180.0;
> double RotY = angleY * vnl_math::pi / 180.0;
> double RotZ = angleZ * vnl_math::pi / 180.0;
> vnl_quaternion<double> RR(RotX,RotY,RotZ);
> rotation.Set(RR);
> transform->SetRotation( rotation );
>
> [...]
> // Checking
> VersorType rotationInitiale = transform->GetVersor();
> vnl_vector_fixed<double,3> anglesEuleriensInitiaux =
> (rotationInitiale.GetVnlQuaternion()).rotation_euler_angles();
> cout << "Angles d'Euler (initiaux): " <<
> (anglesEuleriensInitiaux*180.0/vnl_math::pi) << endl;
>
> ********************************************************
>
> What I doesn't understand actually is why by flipping around X or Y axis
> by 180°, I get an "half image" at the beginning of the stack
> Is this behavious linked to the Quaternions ? Is there a special case
> for a pi angle ? Is there a way to avoid this behaviour ?
>
> Images:
> http://itk.fete.ch/perso/Rot_0_0_0.jpg
> http://itk.fete.ch/perso/Rot_0_180_0.jpg
> http://itk.fete.ch/perso/Rot_180_0_0.jpg
>
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Insight-users mailing list
> Insight-users at itk.org
> http://www.itk.org/mailman/listinfo/insight-users
More information about the Insight-users
mailing list