[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