[Insight-users] Registration of US and CT images
Anders Almås
andersal@stud.ntnu.no
Tue May 11 10:33:00 EDT 2004
Hi!
I am performing registration of US images and CT images in 3D. So far I
am only using Mattes mutual information metric. Now my ragistration is
only performed on a perfect aligned set of US and CT images. What I do
is to initially rotate and translate the CT image and try to registrate
it such that the translated/rotated image is aligned again. First i
used the Centered Affine transform, but that gave only results which
was sometimes ok for only rotation. Then when I only tested for
translations the translation transform worked quite good. At present
time I am testing the VersorRigid3DTransform. This one works ok at
translations and it seems that it manages rotations in one direction.
My question for VersorRigid3DTransform is how it should be initialized?
I send the code so that any one can comment it... Is it the
optimizerscales which are the problem. Or is it really that I perform
an affine transformation/rotation that makes it difficult to registrate
it back? I hope anyone can help me about this...
The size of the images is 256*256*176 with spacing 1.453,1.453 and 2
Here follows the code for the registration:
std::cout<<"Here starts the registration process..."<<std::endl;
//TranslationTransform
// typedef itk::TranslationTransform<double, ImageDimension>
TranslationType;
//Rigid3DTransform
typedef itk::VersorRigid3DTransform<double> TranslationType;
// typedef itk::CenteredAffineTransform< double, ImageDimension >
TranslationType;
//Transform filters
//Optimizer filters
typedef itk::VersorRigid3DTransformOptimizer OptimizerType;
// typedef itk::RegularStepGradientDescentOptimizer
OptimizerType;
//Image Function filters
typedef itk::LinearInterpolateImageFunction<ImageType, double >
InterpolatorType;
//Metric filter
typedef itk::MattesMutualInformationImageToImageMetric< ImageType,
ImageType > MetricType;
//typedef itk::MutualInformationImageToImageMetric<ImageType,ImageType
> MetricType;
//RegistrationMethod
//typedef itk::ImageRegistrationMethod< ImageType, ImageType >
RegistrationType;
typedef itk::MultiResolutionImageRegistrationMethod< ImageType,
ImageType > RegistrationType;
typedef itk::MultiResolutionPyramidImageFilter<ImageType,ImageType >
FixedImagePyramidType;
typedef itk::MultiResolutionPyramidImageFilter<ImageType,ImageType >
MovingImagePyramidType;
typedef OptimizerType::ScalesType OptimizerScalesType;
TranslationType::Pointer transform2 = TranslationType::New();
OptimizerType::Pointer optimizer = OptimizerType::New();
InterpolatorType::Pointer interpolator2 = InterpolatorType::New();
RegistrationType::Pointer registration = RegistrationType::New();
MetricType::Pointer metric = MetricType::New();
FixedImagePyramidType::Pointer fixedImagePyramid =
FixedImagePyramidType::New();
MovingImagePyramidType::Pointer movingImagePyramid =
MovingImagePyramidType::New();
typedef itk::CenteredTransformInitializer< TranslationType, ImageType,
ImageType > TransformInitializerType;
TransformInitializerType::Pointer initializer =
TransformInitializerType::New();
initializer->SetTransform( transform2 );
initializer->SetFixedImage( range->GetOutput());
// initializer->SetFixedImage( gaussian->GetOutput());
initializer->SetMovingImage( filter->GetOutput() );
//initializer->SetMovingImage( ctimage );
initializer->MomentsOn();
initializer->InitializeTransform();
typedef TranslationType::VersorType VersorType;
typedef VersorType::VectorType VectorType;
VersorType rotation;
VectorType axis;
axis[0] = 0.0;
axis[1] = 0.0;
axis[2] = 1.0;
const double angle = 0;
rotation.Set( axis, angle );
transform2->SetRotation( rotation );
axis[0] = 1.0;
axis[1] = 0.0;
axis[2] = 0.0;
rotation.Set( axis, angle );
transform2->SetRotation( rotation );
axis[0] = 0.0;
axis[1] = 1.0;
axis[2] = 0.0;
// const double angle = 0;
rotation.Set( axis, angle );
transform2->SetRotation( rotation );
//transform2->SetIdentity();
registration->SetTransform(transform2);
registration->SetOptimizer( optimizer );
registration->SetInterpolator( interpolator2 );
registration->SetMetric( metric );
registration->SetFixedImagePyramid( fixedImagePyramid );
registration->SetMovingImagePyramid( movingImagePyramid );
OptimizerScalesType optimizerScales(
transform2->GetNumberOfParameters() );
std::cout<<"Number of parametres:
"<<transform2->GetNumberOfParameters()<<std::endl;
optimizerScales[0] = 1.0;
optimizerScales[1] = 1.0;
optimizerScales[2] = 1.0;
optimizerScales[3] = 1.0/1000;
optimizerScales[4] = 1.0/1000;
optimizerScales[5] = 1.0/1000 ;
optimizer->SetScales( optimizerScales );
optimizer->MaximizeOn();
registration->SetFixedImage( range->GetOutput()); //US IMAGE EDGE
MAP
registration->SetMovingImage( filter->GetOutput() ); // CTimage
gaussian blurred translated and rotated...
registration->SetFixedImageRegion(
range->GetOutput()->GetBufferedRegion() );
typedef RegistrationType::ParametersType ParametersType;
/*
ParametersType initialParameters( transform->GetNumberOfParameters()
);
initialParameters[0] = 0.0; // Initial offset in mm along X
initialParameters[1] = 0.0; // Initial offset in mm along Y
initialParameters[2] = 0.0; // Initial offset in mm along Z
*/
registration->SetInitialTransformParameters(
transform2->GetParameters() );
metric->SetNumberOfHistogramBins( par[7] ); // 20
metric->SetNumberOfSpatialSamples( par[8] ); //10000
optimizer->SetNumberOfIterations( par[6] ); // Tested from 300 - 800
iterations
CommandIterationUpdate::Pointer observer =
CommandIterationUpdate::New();
optimizer->AddObserver( itk::IterationEvent(), observer );
typedef RegistrationInterfaceCommand<RegistrationType> CommandType;
CommandType::Pointer command = CommandType::New();
registration->AddObserver( itk::IterationEvent(), command );
registration->SetNumberOfLevels( par[9] ); //Tested from 3-5 levels..
try
{
registration->StartRegistration();
}
catch( itk::ExceptionObject & err )
{
std::cout << "ExceptionObject caught !" << std::endl;
std::cout << err << std::endl;
return input;
}
ParametersType finalParameters =
registration->GetLastTransformParameters();
unsigned int numberOfIterations = optimizer->GetCurrentIteration();
double bestValue = optimizer->GetValue();
// Print out results
//
std::cout << "Result = " << std::endl;
std::cout << " Iterations = " << numberOfIterations << std::endl;
std::cout << " Metric value = " << bestValue << std::endl;
//std::cout << " Stop Condition = " << optimizer->GetStopCondition()
<< std::endl;
I really hope somebody can help me with some advice. Maybe is it that my
parameters is set wrong??
Regards
Anders
More information about the Insight-users
mailing list