[Insight-users] 3D Affine transformation
Luis Ibanez
luis . ibanez at kitware . com
Thu, 20 Nov 2003 13:45:00 -0500
Hi Petter,
You seem to be doing a number of manual
computations for making sure that the
rotation is made around the center of the
image.
You should use the CenteredAffineTransform
http://www . itk . org/Insight/Doxygen/html/classitk_1_1CenteredAffineTransform . html
instead of the AffineTransform.
http://www . itk . org/Insight/Doxygen/html/classitk_1_1AffineTransform . html
The CenteredAffine transform will do the
rotation center corrections for you.
You will find a description of this class
in the software guide
http://www . itk . org/ItkSoftwareGuide . pdf
Section 8.5.3, pdf-page 278.
where it is used in the context of image
registration.
Regards,
Luis
----------------------
Petter Risholm wrote:
> hi,
>
> I'm trying to do a 3D affine transformation on a 3D volume but am having
> huge difficulties getting a resonable result.
>
> When I run my program without doing any transformations (no rotation and
> no translation), the first slice of the output volume looks exactly like
> the input volume. However, the rest of the slices have no information
> except for the DefaultPixelValue.
>
> Is there something wrong with the resampling I'm doing?
>
> This program is just an extension to 3D of the ResampleImageFilter4 found
> in the examples.
>
> Next follows the metaheader for the volume, next is the code for my
> program.
>
> regards Petter Risholm
>
> NDims = 3 DimSize = 128 128 20
> ElementSpacing = 1 1 1
> Position = 0 0 0
> ElementByteOrderMSB = False
> ElementType = MET_USHORT
> HeaderSize = -1
> ElementDataFile = LIST 2
> Image_ref.raw
>
> int main( int argc, char * argv[] )
> {
> if( argc < 5 )
> {
> std::cerr << "Usage: " << std::endl;
> std::cerr << argv[0] << " inputImageFile outputImageFile degrees
> x-trans y-trans z-trans" << std::endl;
> return 1;
> }
>
> const unsigned int Dimension = 3;
> typedef unsigned short InputPixelType;
> typedef unsigned short OutputPixelType;
>
> typedef itk::Image< InputPixelType, Dimension > InputImageType;
> typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
>
> typedef itk::ImageFileReader< InputImageType > ReaderType;
> typedef itk::ImageFileWriter< OutputImageType > WriterType;
> reader->SetFileName( argv[1] );
> writer->SetFileName( argv[2] );
>
> const double angleInDegrees = atof( argv[3] );
> const int xtrans = atoi( argv[4] );
> const int ytrans = atoi( argv[5] );
> const int ztrans = atoi( argv[6] );
>
> typedef itk::ResampleImageFilter<
> InputImageType, OutputImageType > FilterType;
>
> FilterType::Pointer filter = FilterType::New();
>
> typedef itk::AffineTransform< double, Dimension > TransformType;
> TransformType::Pointer transform = TransformType::New();
>
> typedef itk::BSplineInterpolateImageFunction<
> InputImageType, double > InterpolatorType;
> InterpolatorType::Pointer interpolator = InterpolatorType::New();
>
> filter->SetInterpolator( interpolator );
>
> filter->SetDefaultPixelValue( 13 );
>
> reader->Update();
> const double * spacing = reader->GetOutput()->GetSpacing();
> const double * origin = reader->GetOutput()->GetOrigin();
> InputImageType::SizeType size =
> reader->GetOutput()->GetLargestPossibleRegion().GetSize();
> std::cout << "size: " << size << "\n";
> filter->SetOutputOrigin( origin );
> filter->SetOutputSpacing( spacing );
> filter->SetSize( size );
>
>
> filter->SetInput( reader->GetOutput() );
> writer->SetInput( filter->GetOutput() );
>
> TransformType::OutputVectorType translation1;
>
> const double imageCenterX = origin[0] + spacing[0] * size[0] / 2.0;
> const double imageCenterY = origin[1] + spacing[1] * size[1] / 2.0;
> const double imageCenterZ = origin[2] + spacing[2] * size[2] / 2.0;
>
> translation1[0] = -imageCenterX;
> translation1[1] = -imageCenterY;
> translation1[2] = -imageCenterZ;
>
> transform->Translate( translation1 );
>
> std::cout << "imageCenterX = " << imageCenterX << std::endl;
> std::cout << "imageCenterY = " << imageCenterY << std::endl;
> std::cout << "imageCenterZ = " << imageCenterZ << std::endl;
> TransformType::OutputVectorType axis;
> axis[0] = 0;
> axis[1] = 0;
> axis[2] = 1;
>
> const double degreesToRadians = atan(1.0) / 45.0;
> const double angle = angleInDegrees * degreesToRadians;
> transform->Rotate3D(axis, angle, false );
>
> TransformType::OutputVectorType translation2;
> translation2[0] = imageCenterX + xtrans;
> translation2[1] = imageCenterY + ytrans;
> translation2[2] = imageCenterZ + ztrans;
> transform->Translate( translation2, false );
>
> filter->SetTransform( transform );
>
> try
> {
> writer->Update();
> }
> catch( itk::ExceptionObject & excep )
> {
> std::cerr << "Exception catched !" << std::endl;
> std::cerr << excep << std::endl;
> }
> // Software Guide : EndCodeSnippet
> return 0;
> }
>
>
> _______________________________________________
> Insight-users mailing list
> Insight-users at itk . org
> http://www . itk . org/mailman/listinfo/insight-users
>