[Insight-users] confusion with specifying origin for 3D affine transformations - itkAffineTransform

Marius Staring marius at isi.uu.nl
Tue Sep 20 11:48:02 EDT 2005


Hi Rama,

you can get the desired image by using

    importFilter->GetOutput();

So

    importFilter->GetOutput()->TransformIndexToPhysicalPoint( 
centerInIndices ) ;

does the trick.

centerInIndices is not an itk::Point but an Index!

Note that itk::VersorTransform does (!) have the SetCenter(...) function 
in it by inheritance from the MatrixOffsetTransformBase. I am not sure 
though if you want to use this class, maybe you should use the 
Versor3DRigidTransform.

Regards,

Marius

rama wrote:

> Hi Marius,
>
> I want to clraify one thing that you said. You are suggesting me to 
> get the center point from Image like this,
> image->TransformIndexToPhysicalPoint( centerInIndices ) ;   //I 
> understood that centerInIndices is a itk::point
>
> But I don't have an Image class. I have only itk::ImportImageFilter 
> class which imports data from a C++ array.
> I gave this in my code. This ImportImageFilter gives data to the 
> ResampleImageFilter class.
>
> Now, how can I access the center point of this array in world 
> coordinates. This class does not have the 
> TransformIndexToPhysicalPoint(...) function.
> How can I get the center point in world coordinates from this class.
>
> Also, I tried itk::VersorTransform and itk::Versor3DRigidTransform. in 
> vain.
>
> itk::VersorTransform does not have SetCenter(...) function in it. 
> Versor3DRigidTransform has that function, but it is not giving me the 
> desired result when I specified the center point in this way,
> TransformType::InputPointType centerPoint;
> centerPoint[0] = (xNumPixels/2) * PixelXWidth;
> centerPoint[1] = - (yNumPixels/2) * PixelYWidth;
> centerPoint[2] = (zNumPixels/2) * PixelZWidth;
> transform->SetCenter(centerPoint);
>
> When I make this center point to (0.0, 0.0, 0.0) then, just I am 
> getting the previous result. The image is rotating about the corner of 
> the image.
>
> What else can I do.
>
> I just want to rotate the 3D cube around a point and I can't do it in 
> all the three ways I tried.
>
> For the last time I will try the SetParameters(...) function from the 
> VersorRigid3DTransform class. But I am not understanding how to get 
> the center point of the array in world coordinates.
>
> Can you please suggest me a way how to do it.
>
> Thank you,
> Rama.
>
> Marius Staring wrote:
>
>> Hi Rama,
>>
>> from the definition of Rotate3D:
>>
>>    http://www.itk.org/Doxygen/html/classitk_1_1AffineTransform.html#a3
>>
>> I understand that this function does not use the center of rotation. 
>> (I don't know why that is) You could try something like
>>
>>    affinetransform->SetCenter( image->TransformIndexToPhysicalPoint( 
>> centerInIndices ) );
>>    ParametersType parameters;
>>    parameters[ 0 ] = ..... etc, where the first 9 parameters are your 
>> matrix and the last 3 the translation
>>    affinetransform->SetParameters( parameters );
>>
>> The SetParameters() function does take into account the center.
>>
>> Hope this helps,
>>
>> Marius
>>
>> rama wrote:
>>
>>> Hi,
>>>
>>> I tried the SetCenter(...) method that you suggestd, but I am still 
>>> not getting rotations about that point.
>>>
>>> So, I have a cube of 160 X 144 X 208 pixels and I want to rotate it 
>>> by the point (80, 72, 104) around X-Axis.
>>>
>>> Here is the code that I wrote for setting the CenterPoint,
>>>
>>> TransformType::InputPointType centerPoint;
>>> centerPoint[0] = (xNumPixels/2) * PixelXWidth;
>>> centerPoint[1] = - (yNumPixels/2) * PixelYWidth;
>>> centerPoint[2] = (zNumPixels/2) * PixelZWidth;
>>> transform->SetCenter(centerPoint);
>>>
>>> I did this before I set the rotation values. Also, here I don't have 
>>> two images, like one fixed and other moving. I only have one single 
>>> cube and just I want to rotate it.
>>>
>>> But with the addition of above lines of code before setting the 
>>> rotation values (transform->SetRotation3D(rotation, angle, false)) 
>>> doesn't make any difference. Still the image is rotating about one 
>>> of the corners of the image. Not about its center point.
>>>
>>> Please see the images before and after rotations. 
>>> http://www.funnotes.net/img-before-rot.JPG    
>>> http://www.funnotes.net/img-after-rot.JPG  . This image is a Left 
>>> side view of the 3D cube (middle slice).
>>>
>>> You can see that image rotation is done about the Top-Left corner of 
>>> the image and not about the center point of the image (the center 
>>> point of cross).
>>>
>>> Can you please suggest what to do here.
>>>
>>> thank you,
>>> Rama.
>>>
>>> Marius Staring wrote:
>>>
>>>> No I mean
>>>>
>>>>    affinetransform->SetCenter( 
>>>> fixedImage->TransformIndexToPhysicalPoint( centerInIndices ) );
>>>>
>>>> See also
>>>>
>>>>    
>>>> http://www.itk.org/Doxygen/html/classitk_1_1MatrixOffsetTransformBase.html#z1307_0 
>>>>
>>>>
>>>> for what the SetCenter() does
>>>>
>>>> Regards,
>>>>
>>>> Marius
>>>>
>>>> rama wrote:
>>>>
>>>>> Hi Marius,
>>>>>
>>>>> you mean resampler->SetCenter(...) instead of 
>>>>> resampler->SetOrigin(...)? Then what about SetOrigin(...) in 
>>>>> itk::ImportImageFilter class. What does it do? Is it not necessary.
>>>>>
>>>>> Also by world coordinates, you mean the same values that I used 
>>>>> for SetOrigin(...) before.
>>>>> So, if I say resampler->SetOrigin((xNumPixels/2) * PixelXWidth, 
>>>>> (yNumPixels/2) * PixelYWidth, (zNumPixels/2) * PixelZWidth) will 
>>>>> it work.
>>>>>
>>>>> Still the doubt that I have is, which point to consider as the 
>>>>> origin while specifying the center point in world coordinates. If 
>>>>> the center point of image in world coordinates is (0,0,0) then 
>>>>> what is the extra need to specify a center point. This is bit 
>>>>> confusing. Can you elucidate it please?
>>>>>
>>>>> So, in world coordinates what will the center point of the 3D cube 
>>>>> considered as by the AffineTransform class. With respect to which 
>>>>> point should I specify the world coordinates of the center point.
>>>>>
>>>>> Can you please explain it a bit more.
>>>>>
>>>>> thank you,
>>>>> Rama Aravind.
>>>>>
>>>>> Marius Staring wrote:
>>>>>
>>>>>> Hi Rama,
>>>>>>
>>>>>> you have to use SetCenter(centerpoint) and not SetOrigin(). Make 
>>>>>> sure to give centerpoint in world coordinates.
>>>>>>
>>>>>> Regards,
>>>>>>
>>>>>> Marius Staring
>>>>>>
>>>>>> rama wrote:
>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I have a problem rotating a 3D image about ITS OWN center point 
>>>>>>> around X axis (take that Z axis is pointing into the screen).
>>>>>>>
>>>>>>> I have a 3D image with dimensions as 160 X 144 X 208 pixels in 
>>>>>>> X, Z and Y axis respectively.
>>>>>>>
>>>>>>> I want to rotate this image around X axis about its own center 
>>>>>>> point, that is, around the middle point of the image - (80, 72, 
>>>>>>> 104).  That is, the image should rotate around itself about X-Axis.
>>>>>>> But I am not getting that effect. The image is always rotating 
>>>>>>> around the point (0, 0, 0) of the array index.
>>>>>>>
>>>>>>> Here are the details.
>>>>>>>
>>>>>>> I am importing data from a C++ array like this using 
>>>>>>> itk::ImportImageFilter class.
>>>>>>>
>>>>>>> typedef itk::ImportImageFilter<InputPixelType, Dimension> 
>>>>>>> ImportImgFromArray;
>>>>>>> ImportImgFromArray::Pointer importFilter = 
>>>>>>> ImportImgFromArray::New();
>>>>>>> ImportImgFromArray::SizeType size;
>>>>>>> size[0]=xNumPixels;          //160
>>>>>>> size[1]=yNumPixels;          //208
>>>>>>> size[2]=zNumPixels;          //144
>>>>>>> ImportImgFromArray::IndexType start;
>>>>>>> start.Fill(0);
>>>>>>> ImportImgFromArray::RegionType region;
>>>>>>> region.SetIndex(start);
>>>>>>> region.SetSize(size);
>>>>>>> importFilter->SetRegion(region);
>>>>>>> double origin[Dimension];
>>>>>>> origin[0]=(xNumPixels/2) * PixelXWidth;
>>>>>>> origin[1]=(yNumPixels/2) * PixelYWidth;
>>>>>>> origin[2]=(zNumPixels/2) * PixelZWidth;
>>>>>>> importFilter->SetOrigin(origin);
>>>>>>> double spacing[Dimension];
>>>>>>> spacing[0]=PixelXWidth;
>>>>>>> spacing[1]=PixelYWidth;
>>>>>>> spacing[2]=PixelZWidth;
>>>>>>> importFilter->SetSpacing(spacing);
>>>>>>> importFilter->SetImportPointer(tempBuffer, 
>>>>>>> size[0]*size[1]*size[2], false);      //get data from a 
>>>>>>> tempBuffer - a C++ array - there is no error here
>>>>>>>
>>>>>>> I am setting the transformation like this,
>>>>>>>
>>>>>>> typedef itk::AffineTransform<double, Dimension> TransformType;
>>>>>>> TransformType::Pointer transform=TransformType::New();
>>>>>>>
>>>>>>> resampler->SetDefaultPixelValue(0);      //resampler is a 
>>>>>>> itk::ResampleImageFilter class
>>>>>>> resampler->SetSize(size);
>>>>>>> origin[0]=(xNumPixels/2) * PixelXWidth;
>>>>>>> origin[1]=(yNumPixels/2) * PixelYWidth;
>>>>>>> origin[2]=(zNumPixels/2) * PixelZWidth;
>>>>>>> resampler->SetOutputOrigin(origin);
>>>>>>> resampler->SetOutputSpacing(spacing);
>>>>>>>
>>>>>>> TransformType::OutputVectorType translation1;
>>>>>>> translation1[0]=-origin[0];
>>>>>>> translation1[1]=-origin[1];
>>>>>>> translation1[2]=-origin[2];
>>>>>>> transform->Translate(translation1);
>>>>>>>
>>>>>>> TransformType::OutputVectorType rotation;
>>>>>>> rotation[0]=1;   //rotate around X-Axis
>>>>>>> rotation[1]=0;
>>>>>>> rotation[2]=0;
>>>>>>> transform->Rotate3D(rotation, 
>>>>>>> m_cmnData->SagittalRotateZ(m_curDataSetListSel)*DegToRad, false);
>>>>>>>
>>>>>>> TransformType::OutputVectorType translation2;
>>>>>>> translation2[0]=origin[0];
>>>>>>> translation2[1]=origin[1];
>>>>>>> translation2[2]=origin[2];
>>>>>>> transform->Translate(translation2);
>>>>>>> resampler->SetTransform(transform);
>>>>>>>
>>>>>>> resampler->SetInput(importFilter->GetOutput());
>>>>>>> resampler->Update();
>>>>>>>
>>>>>>> These are my transformation settings. But when I try to rotate 
>>>>>>> it 10degrees either CW or CCW, I am getting the rotations around 
>>>>>>> the array index (0,0,0) not through the point that I specified 
>>>>>>> in the image.
>>>>>>>
>>>>>>> I was skeptical about the before and after translations of the 
>>>>>>> rotation. So, when I disabled those two translations before and 
>>>>>>> after it, the image just went out of bounds and I get only a 
>>>>>>> blank 3D cube.
>>>>>>> When I made the origin point to (0.0, 0.0, 0.0) even then the 
>>>>>>> image is just rotating around the array index (0,0,0).
>>>>>>>
>>>>>>> Can you please suggest me how can I get rotations for the 3D 
>>>>>>> cube around its center point (that is, the center point of the 
>>>>>>> cube). I want the whole cube rotate around itself about X-Axis. 
>>>>>>> Can you please suggest me what to do for that.
>>>>>>>
>>>>>>> thank you,
>>>>>>> Rama Aravind.
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> Insight-users mailing list
>>>>>>> Insight-users at itk.org
>>>>>>> http://www.itk.org/mailman/listinfo/insight-users
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>>
>>
>
>

-- 
Marius Staring
Image Sciences Institute
University Medical Centre Utrecht
Heidelberglaan 100, 3584 CX Utrecht, The Netherlands
phone: +31 (0)30 250 3186, fax: +31 (0)30 251 3399
marius at isi.uu.nl, http://www.isi.uu.nl/People/Marius



More information about the Insight-users mailing list