[Insight-users] itkMatrix error: discards qualifiers??
Luis Ibanez
luis.ibanez at kitware.com
Tue Mar 30 10:35:25 EDT 2010
Hi Michiel,
This is actually the reason why using Euler angles is a bad idea.
The lack of a standard for the order of
application of the individual rotations.
plus their vulnerability to the gimbal lock problem:
http://en.wikipedia.org/wiki/Gimbal_lock
http://en.wikipedia.org/wiki/Gimbal_lock#Loss_of_a_degree_of_freedom_with_Euler_angles
---
I would strongly encourage you to use itk::Versors instead.
Versors (Unit Quaternions) are an unambiguous representation of
rotations.
Regards,
Luis
------------------------------------------------------------------------
On Tue, Mar 30, 2010 at 9:11 AM, michiel mentink
<michael.mentink at st-hughs.ox.ac.uk> wrote:
> in
> /itkEuler3DTransform.txx
> the rotation is applied either in X Y Z order, or Z X Y order (standard),
> where Y rotation is applied first.
>
> Indeed, if I try different orders of rotation, I get different outcomes. I
> suppose this is due to round-off
> errors.
> Why is Z X Y chosen as the standard way of multiplication?
>
>
> Z Y X
> image->GetDirection():
> 0.999695 0.0171452 0.0177517
> -0.0174497 0.999701 0.0171452
> -0.0174524 -0.0174497 0.999695
>
> X Y Z
> image->GetDirection():
> 0.999695 0.0174497 0.0174524
> -0.0177543 0.99969 0.0174497
> -0.0171425 -0.0177543 0.999695
>
> Z X Y
> image->GetDirection():
> 0.99969 0.0174497 0.0177543
> -0.0177543 0.999695 0.0171425
> -0.0174497 -0.0174524 0.999695
>
> cheers,
>
> Michael
>
>
>
>
>
> On Tue, Mar 30, 2010 at 12:18 PM, michiel mentink
> <michael.mentink at st-hughs.ox.ac.uk> wrote:
>>
>> ah just after posting I found it (figures!)
>>
>> complete and correct code now:
>>
>> const ImageType::DirectionType & direction = image->GetDirection()
>> std::cout << "direction: " << std::endl << direction << std::endl <<
>> std::endl;
>>
>> float angleX, angleY, angleZ;
>> angleX = angleY = angleZ = 1 * vnl_math::pi / 180.0; //
>> in this case: rotation = 1 degree
>>
>> const double cx = vcl_cos(angleX);
>> const double sx = vcl_sin(angleX);
>>
>> typedef itk::Matrix<double,3,3> Matrix;
>> Matrix RotationX;
>> Matrix FinalRotation = image->GetDirection();
>>
>> std::cout << "sin: " << sx << " Cos: " << cx << std::endl;
>>
>> RotationX[0][0] = 1; RotationX[0][1] = 0; RotationX[0][2] = 0;
>> RotationX[1][0] = 0; RotationX[1][1] = cx; RotationX[1][2] = sx;
>> RotationX[2][0] = 0; RotationX[2][1] = -sx; RotationX[2][2] = cx;
>>
>> FinalRotation = direction*RotationX;
>>
>> std::cout << "image->GetDirection(): " << std::endl <<
>> image->GetDirection() << std::endl;
>> std::cout << "RotationX: " << std::endl << RotationX << std::endl;
>> std::cout << "FinalRotation: " << std::endl << FinalRotation <<
>> std::endl;
>>
>> image->SetDirection(FinalRotation);
>>
>> std::cout << "image->GetDirection(): " << std::endl <<
>> image->GetDirection() << std::endl;
>>
>>
>> cheers, Michael
>>
>>
>>
>>
>>
>> On Tue, Mar 30, 2010 at 12:10 PM, michiel mentink
>> <michael.mentink at st-hughs.ox.ac.uk> wrote:
>>>
>>> Hello Frederic,
>>>
>>> thanks for your suggestion.
>>>
>>> although my code was working, I tried your suggestion. Unfortunately, it
>>> produces
>>>
>>> error: no match for ‘operator*’ in
>>> ‘image.itk::SmartPointer<TObjectType>::operator-> [with TObjectType =
>>> itk::Image<float, 3u>]()->itk::ImageBase<VImageDimension>::GetDirection
>>> [with unsigned int VImageDimension = 3u] * RotationX’
>>>
>>>
>>> Anyway, I forgot to mention to use:
>>>
>>> float angleX, angleY, angleZ;
>>> angleX = angleY = angleZ = 1 * (3.14/180);
>>>
>>> (multiply by pi and divide by 180 degrees, because ITK internally works
>>> with radians instead of degrees)
>>>
>>> Which leads me to the question: vnl has a pi constant, and I remember
>>> vaguely having seen it somewhere as vnl::PI or something.
>>> Does anyone know how to convince vnl to hand me pi constant?
>>>
>>> cheers, Michael
>>>
>>>
>>>
>>> On Tue, Mar 30, 2010 at 11:55 AM, Frederic Perez <fredericpcx at gmail.com>
>>> wrote:
>>>>
>>>> Hello Michiel,
>>>>
>>>> perhaps you could use a const Matrix object after all, since it looks to
>>>> me that FinalRotation is first built with image->GetDirection() but this
>>>> value is not actually used, and that the signature of itk::Image's is
>>>> SetDirection(const DirectionType direction).
>>>>
>>>> So here you are, my quickly written proposal (caution, I haven't
>>>> compiled it):
>>>>
>>>> float angleX, angleY, angleZ;
>>>> angleX = angleY = angleZ = 5;
>>>>
>>>> const double cx = vcl_cos(angleX);
>>>> const double sx = vcl_sin(angleX);
>>>>
>>>> typedef itk::Matrix<double,3,3> Matrix;
>>>> Matrix RotationX;
>>>> // Matrix FinalRotation = image->GetDirection(); -- Commented now
>>>>
>>>> RotationX[0][0] = 1; RotationX[0][1] = 0; RotationX[0][2] = 0;
>>>> RotationX[1][0] = 0; RotationX[1][1] = cx; RotationX[1][2] = sx;
>>>> RotationX[2][0] = 0; RotationX[2][1] = -sx; RotationX[2][2] = cx;
>>>>
>>>> const Matrix FinalRotation = direction*RotationX;
>>>>
>>>> std::cout << "image->GetDirection(): " << std::endl <<
>>>> image->GetDirection() << std::endl;
>>>> std::cout << "RotationX: " << std::endl << RotationX << std::endl;
>>>> std::cout << "FinalRotation: " << std::endl << FinalRotation <<
>>>> std::endl;
>>>>
>>>> image->SetDirection(FinalRotation);
>>>>
>>>> std::cout << "image->GetDirection(): " << std::endl <<
>>>> image->GetDirection() << std::endl;
>>>>
>>>> Cheers,
>>>>
>>>> Frederic
>>>>
>>>
>>
>
>
More information about the Insight-users
mailing list