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

Luis Ibanez luis.ibanez at kitware.com
Wed Sep 28 13:58:56 EDT 2005


Hi Rama,

It is much simpler to use the

        CenteredTransformInitializer
http://www.itk.org/Insight/Doxygen/html/classitk_1_1CenteredTransformInitializer.html


This class will compute the center of the image for you
and set it in the transfrom that you are using.

Note that you can compute the center based on the Geometry
of the image, or based on the Image Moments (center of mass).

You will find many examples on the use of the CenteredTransform
Initializer in the ITK Software Guide

     http://www.itk.org/ItkSoftwareGuide.pdf


In particular in the Image Registration chapter.

The source code of the associated examples can be found in
the directory

            Insight/Examples/Registration



    Regards,


       Luis



-----------------
rama wrote:
> Hi, Now I got the thing working. I am able to rotate the array cube 
> about its center point. thanks to Marius. When I made the center point 
> like this,
> 
> TransformType::InputPointType centerPoint;
> centerPoint[0] = (xNumPixels/2) * PixelXWidth;    //It took me some time 
> to understand ITK's coord. system.
> centerPoint[1] = (yNumPixels/2) * PixelYWidth;
> centerPoint[2] = (zNumPixels/2) * PixelZWidth;
> transform->SetCenter(centerPoint);
> 
> it worked. But it only worked with VersorRigid3DTransform. It did not 
> work with either AffineTransform or VersorTransform.
> 
> But there is a memory leak at the place where I am collecting my data back.
> I am collecting my data back after rotation like this,
> 
> InputImage::PixelContainer *container;
> container=resampler->GetOutput()->GetPixelContainer();
> tempBuffer=container->GetImportPointer();
> 
> where tempBuffer is the buffer which is passed to the 'resmapler' and it 
> is allocated like this,
> 
> unsigned char *tempBuffer;
> tempBuffer = new unsigned char[size[0]*size[1]*size[2]];
> 
> and InputImage is declared like this.
> 
> const unsigned int Dimension=3;
> typedef unsigned char InputPixelType;
> typedef itk::Image<InputPixelType, Dimension> InputImage;
> 
> The problem is, I am getting a memory leak with the tempBuffer even 
> though I try to delete it with delete operator like this, delete [] 
> tempBuffer.
> 
> Luis before, hinted me that when using this pixel container it is very 
> important to set Container Manage Memory flag to 'false' like this,
> container->SetContainerManageMemory(false); So, that the buffer doesn't 
> get deallocated when it goes out of scope.
> 
> But I want the buffer to be deallocated and so I did not set that flag 
> to 'false'.
> 
> And I am getting a memory leak saying that the tempBuffer is not 
> deallocated.
> 
> How to deallocate that buffer. As the data is very huge, everytime I am 
> running the program, I am getting a very huge memory leak.
> 
> Even if I set the flag to 'true' I am getting this memory leak.
> 
> Can you please suggest me what to do here. I hope this error will be my 
> last one with ITK.
> 
> Thank you,
> Rama.
> 
> Marius Staring wrote:
> 
>> 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
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>>
>>
> 
> _______________________________________________
> 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