[Insight-users] Volume not perfectly rotated

Nic itk at fete.ch
Sat Oct 13 10:50:27 EDT 2007


Hi Luis,
    here's my code and image information below. I use actually hig res
images resized in x and y (=> 512x512), z dimensions was not changed.
Voxel dimensions for 2048x2048 where 0.0915751 x 0.0915751 x 0.64427 um.
My code is using actually using multiresregistration, but I'm ending a Gui
allowing to set x and y translation and rotation around z-axis through a
"dual channel slides superposition window", in order to my initial
transformation as near as possible giving the registration program these
three intial values + begin and end overlapping blocks images numbers (for
overlapping volumes centers computation).
Thus, perhaps multiresregistration won't be useful anymore, multithreading
normalizedcorrelation would be more useful (I'm studying the
MatchCardinalityImageToImageMetric for this purpose).

Thanks, nic

Image (00000000029A5A50)
  RTTI typeinfo:   class itk::Image<unsigned char,3>
  Reference Count: 4
  Modified Time: 22365
  Debug: Off
  Observers:
    none
  Source: (00000000029B60B0)
  Source output index: 0
  Release Data: Off
  Data Released: False
  Global Release Data: Off
  PipelineMTime: 130
  UpdateMTime: 11277
  LargestPossibleRegion:
    Dimension: 3
    Index: [0, 0, 0]
    Size: [512, 512, 137]
  BufferedRegion:
    Dimension: 3
    Index: [0, 0, 0]
    Size: [512, 512, 137]
  RequestedRegion:
    Dimension: 3
    Index: [0, 0, 0]
    Size: [512, 512, 137]
  Spacing: [0.3663, 0.3663, 0.64427]
  Origin: [0, 0, 0]
  Direction:
1 0 0
0 1 0
0 0 1

  PixelContainer:
    ImportImageContainer (000000000116BBD0)
      RTTI typeinfo:   class itk::ImportImageContainer<unsigned
long,unsigned char>
      Reference Count: 1
      Modified Time: 315
      Debug: Off
      Observers:
        none
      Pointer: 000000000116BC20
      Container manages memory: true
      Size: 35913728
      Capacity: 35913728
Image (00000000029A5790)
  RTTI typeinfo:   class itk::Image<unsigned char,3>
  Reference Count: 6
  Modified Time: 22366
  Debug: Off
  Observers:
    none
  Source: (00000000029B6200)
  Source output index: 0
  Release Data: Off
  Data Released: False
  Global Release Data: Off
  PipelineMTime: 11291
  UpdateMTime: 22328
  LargestPossibleRegion:
    Dimension: 3
    Index: [0, 0, 0]
    Size: [512, 512, 136]
  BufferedRegion:
    Dimension: 3
    Index: [0, 0, 0]
    Size: [512, 512, 136]
  RequestedRegion:
    Dimension: 3
    Index: [0, 0, 0]
    Size: [512, 512, 136]
  Spacing: [0.3663, 0.3663, 0.64427]
  Origin: [0, 0, 0]
  Direction:
1 0 0
0 1 0
0 0 1

  PixelContainer:
    ImportImageContainer (000000000116BAF0)
      RTTI typeinfo:   class itk::ImportImageContainer<unsigned
long,unsigned char>
      Reference Count: 1
      Modified Time: 11446
      Debug: Off
      Observers:
        none
      Pointer: 000000000116BB40
      Container manages memory: true
      Size: 35651584
      Capacity: 35651584

----- Original Message ----- 
From: "Luis Ibanez" <luis.ibanez at kitware.com>
To: "Nic" <itk at fete.ch>
Cc: "Insight Users" <insight-users at itk.org>
Sent: Friday, October 12, 2007 10:11 PM
Subject: Re: [Insight-users] Volume not perfectly rotated


>
> Hi Nic,
>
> Can you please post your code to the list ?
>
> and also post the basic information about your image ?
>
> The best way of doing this is to send the output of:
>
>      reader->GetOutput()->Print( std::cout );
>
>
>    Thanks
>
>
>       Luis
>
>
> -----------------
> Nic wrote:
>> Hi Luis,
>>    I replace my quaternion code with your code, but I get exactly the
>> same result, the first slide (magenta ) is half cut, sic..
>> http://itk.fete.ch/perso/testCodeLuis01.jpg
>>
>>
>>
>> ----- Original Message ----- From: "Luis Ibanez"
>> <luis.ibanez at kitware.com>
>> To: "Nic" <itk at fete.ch>
>> Cc: "Insight Users" <insight-users at itk.org>
>> Sent: Thursday, October 11, 2007 5:44 PM
>> Subject: Re: [Insight-users] Volume not perfectly rotated
>>
>>
>>>
>>> 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
>>>
>>>
>>
>>
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: recalage3DMultiRes.zip
Type: application/octet-stream
Size: 8740 bytes
Desc: not available
Url : http://public.kitware.com/pipermail/insight-users/attachments/20071013/788d059e/recalage3DMultiRes-0001.obj


More information about the Insight-users mailing list