[Insight-users] Comparing AffineTransform and CenteredAffineTransform
Gavin Baker
gavinb+xtk at cs . mu . OZ . AU
Mon, 13 Oct 2003 19:41:06 +1000
--HlL+5n6rz5pIUxbD
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Hello,
I have been working with the ResampleImageFilter, and got some unexpected
results with the transforms. From reading the docs, it seems that
CenteredAffineTransform is simply an AffineTransform that rotates about the
specified center point.
So I wrote a test case (attached) to explore the difference between an
AffineTransform and a CenteredAffineTransform. All it is supposed to do is
rotate the input data about the center of the image.
The AffineTransform does a:
translate( -center )
rotate( angle )
translate( center )
While the CenteredAffineTransform does a:
set center( center )
rotate( angle )
I would have expected the output to be the same for both. However the
output of the CenteredAffineTransform ends up translated off to the side,
when no translation has been specified (and is not merely size/2).
Have I missed something here? Any insights appreciated...
Thanks,
:: Gavin
--
Gavin Baker Computer Vision Lab (CVMIL)
http://www . cs . mu . oz . au/~gavinb University of Melbourne
--HlL+5n6rz5pIUxbD
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="test_centered.cxx"
#include <itkImage.h>
#include <itkCastImageFilter.h>
#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>
#include <itkExtractImageFilter.h>
#include <itkResampleImageFilter.h>
#include <itkAffineTransform.h>
#include <itkCenteredAffineTransform.h>
int main( int argc, char* argv[] )
{
if ( argc < 4 )
{
std::cerr << "usage: test_centered <in> <out_a> <out_c>" << std::endl;
return 1;
}
// Pixels ______________________________________________________________
typedef unsigned short
InputPixelType;
typedef unsigned short
InternalPixelType;
typedef unsigned short
OutputPixelType;
// Images ______________________________________________________________
enum { Dimension = 3 };
typedef itk::Image<
InputPixelType,
Dimension > InputImageType;
typedef itk::Image<
OutputPixelType,
Dimension > OutputImageType;
// Pipeline ____________________________________________________________
typedef itk::ImageFileReader<
InputImageType > ReaderType;
typedef itk::ResampleImageFilter<
InputImageType,
OutputImageType > ResampleType;
typedef itk::AffineTransform<
double,
3> AffineType;
typedef itk::CenteredAffineTransform<
double,
3> CenteredAffineType;
typedef itk::ImageFileWriter<
OutputImageType > WriterType;
// Construct pipeline __________________________________________________
ReaderType::Pointer _reader = ReaderType::New();
ResampleType::Pointer _resample_a = ResampleType::New();
ResampleType::Pointer _resample_c = ResampleType::New();
AffineType::Pointer _xform_a = AffineType::New();
CenteredAffineType::Pointer _xform_c = CenteredAffineType::New();
WriterType::Pointer _writer_a = WriterType::New();
WriterType::Pointer _writer_c = WriterType::New();
// Connect pipeline ____________________________________________________
_reader->SetFileName( argv[1] );
_resample_a->SetInput( _reader->GetOutput() );
_resample_a->SetTransform( _xform_a );
_writer_a->SetInput( _resample_a->GetOutput() );
_resample_c->SetInput( _reader->GetOutput() );
_resample_c->SetTransform( _xform_c );
_writer_c->SetInput( _resample_c->GetOutput() );
_writer_a->SetFileName( argv[2] );
_writer_c->SetFileName( argv[3] );
// Set parameters _______________________________________________________
_reader->Update();
ResampleType::SizeType in_size =
_reader->GetOutput()->GetLargestPossibleRegion().GetSize();
std::cout << "Input volume size: " << in_size << std::endl;
float rot_angle = 0.7; // radians
// Affine ______________________________________________________________
AffineType::OutputVectorType center_a;
center_a[0] = in_size[0]/2;
center_a[1] = in_size[1]/2;
center_a[2] = in_size[2]/2;
_xform_a->Translate( -center_a );
_xform_a->Rotate( 0, 1, rot_angle );
_xform_a->Translate( center_a );
_resample_a->SetDefaultPixelValue( 86 ); // Get Smart!
_resample_a->SetSize(in_size);
std::cout << "Center point: " << center_a << std::endl;
_xform_a->Print(std::cout);
// Centered ____________________________________________________________
CenteredAffineType::InputPointType center_c;
center_c[0] = center_a[0];
center_c[1] = center_a[1];
center_c[2] = center_a[2];
_xform_c->SetCenter( center_c );
_xform_c->Rotate( 0, 1, rot_angle );
_resample_c->SetDefaultPixelValue( 86 );
_resample_c->SetSize(in_size);
_xform_c->Print(std::cout);
// Save the output ______________________________________________________
try
{
std::cout << "Saving AffineTransform result..." << std::endl;
_writer_a->Update();
std::cout << "Saving CenteredAffineTransform result..." << std::endl;
_writer_c->Update();
}
catch( itk::ExceptionObject& excep )
{
std::cerr
<< "Exception caught !\n"
<< excep << std::endl
;
}
return 0;
}
--HlL+5n6rz5pIUxbD--