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

rama rama at robots.ox.ac.uk
Tue Sep 20 12:37:03 EDT 2005


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
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>>
>



More information about the Insight-users mailing list