Hi, All :<br><br>I want to combine Affine transform and Mattes MI metric into my registration process.<br>The process is fine to work but the result of registration is incorrect.<br>I think this is caused by some coefficients setting that is not suitable for my application,
<br>but how to determine a applicable coefficients that is very suffering for me.<br>So, I wish any experienced friends can give me some indication that including how to set:<br>OptimizerScales (specially translation Scale) <---How to set ???
<br>MaximumStepLength <---How to set ???<br>
MinimumStepLength <---How to set ???<br>NumberOfHistogramBins (now I set 20~50 in typically)<br>NumberOfSpatialSamples (now I set 20% of image pixels )<br><br><br>My code is posting as below:<br>Regards.<br><br>class CommandIterationUpdate : public itk::Command
<br>{<br>public:<br> typedef CommandIterationUpdate Self;<br> typedef itk::Command Superclass;<br> typedef itk::SmartPointer<Self> Pointer;<br> itkNewMacro( Self );<br>protected:<br> CommandIterationUpdate() {};
<br>public:<br> typedef itk::RegularStepGradientDescentOptimizer OptimizerType;<br> typedef const OptimizerType * OptimizerPointer;<br><br> void Execute(itk::Object *caller, const itk::EventObject & event)
<br> {<br> Execute( (const itk::Object *)caller, event);<br> }<br><br> void Execute(const itk::Object * object, const itk::EventObject & event)<br> {<br> OptimizerPointer optimizer = <br> dynamic_cast< OptimizerPointer >( object );
<br> if( ! itk::IterationEvent().CheckEvent( &event ) )<br> {<br> return;<br> }<br> std::cout << optimizer->GetCurrentIteration() << " ";<br> std::cout << optimizer->GetValue() << " ";
<br> std::cout << optimizer->GetCurrentPosition();<br> <br> // Print the angle for the trace plot<br> vnl_matrix<double> p(2, 2);<br> p[0][0] = (double) optimizer->GetCurrentPosition()[0];
<br> p[0][1] = (double) optimizer->GetCurrentPosition()[1];<br> p[1][0] = (double) optimizer->GetCurrentPosition()[2];<br> p[1][1] = (double) optimizer->GetCurrentPosition()[3];<br> vnl_svd<double> svd(p);
<br> vnl_matrix<double> r(2, 2);<br> r = svd.U() * vnl_transpose(svd.V());<br> double angle = asin(r[1][0]);<br> std::cout << " AffineAngle: " << angle * 45.0 / atan(1.0) << std::endl;
<br> }<br>};<br><br>int main( int argc, char *argv[] )<br>{<br> if( argc < 4 )<br> {<br> std::cerr << "Missing Parameters " << std::endl;<br> std::cerr << "Usage: " << argv[0];
<br> std::cerr << " fixedImageFile movingImageFile outputImagefile" << std::endl;<br> return 1;<br> }<br><br> const unsigned int Dimension = 2;<br> typedef float PixelType;
<br><br> typedef itk::Image< PixelType, Dimension > FixedImageType;<br> typedef itk::Image< PixelType, Dimension > MovingImageType;<br><br> typedef itk::AffineTransform< <br> double,
<br> Dimension > TransformType;<br><br> typedef itk::RegularStepGradientDescentOptimizer OptimizerType;<br><br> typedef itk::MattesMutualInformationImageToImageMetric< <br>
FixedImageType, <br> MovingImageType > MetricType;<br><br> typedef itk:: LinearInterpolateImageFunction< <br> MovingImageType,
<br> double > InterpolatorType;<br> typedef itk::ImageRegistrationMethod< <br> FixedImageType, <br> MovingImageType > RegistrationType;
<br> <br> MetricType::Pointer metric = MetricType::New();<br> OptimizerType::Pointer optimizer = OptimizerType::New();<br> InterpolatorType::Pointer interpolator = InterpolatorType::New();<br>
RegistrationType::Pointer registration = RegistrationType::New();<br><br> registration->SetMetric( metric );<br> registration->SetOptimizer( optimizer );<br> registration->SetInterpolator( interpolator );
<br><br> TransformType::Pointer transform = TransformType::New();<br> registration->SetTransform( transform );<br><br> typedef itk::ImageFileReader< FixedImageType > FixedImageReaderType;<br> typedef itk::ImageFileReader< MovingImageType > MovingImageReaderType;
<br> FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New();<br> MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New();<br> fixedImageReader->SetFileName( argv[1] );
<br> movingImageReader->SetFileName( argv[2] );<br><br><br> registration->SetFixedImage( fixedImageReader->GetOutput() );<br> registration->SetMovingImage( movingImageReader->GetOutput() );<br>
fixedImageReader->Update();<br><br> registration->SetFixedImageRegion( <br> fixedImageReader->GetOutput()->GetBufferedRegion() );<br><br> typedef itk::CenteredTransformInitializer< <br> TransformType,
<br> FixedImageType, <br> MovingImageType > TransformInitializerType;<br> TransformInitializerType::Pointer initializer = TransformInitializerType::New();
<br> initializer->SetTransform( transform );<br> initializer->SetFixedImage( fixedImageReader->GetOutput() );<br> initializer->SetMovingImage( movingImageReader->GetOutput() );<br> initializer->MomentsOn();
<br> initializer->InitializeTransform();<br> <br> registration->SetInitialTransformParameters( <br> transform->GetParameters() );<br><br> typedef OptimizerType::ScalesType OptimizerScalesType;
<br> OptimizerScalesType optimizerScales( transform->GetNumberOfParameters() );<br><br>//----------------------------------------------------------------------------- // How to determine these ?<br> metric->SetNumberOfHistogramBins( 50 );
<br> metric->SetNumberOfSpatialSamples( 10000 );<br> metric->ReinitializeSeed( 76926294 );<br><br> double translationScale = 1.0 / 1000.0;<br> optimizerScales[0] = 1.0;<br> optimizerScales[1] = 1.0;<br> optimizerScales[2] =
1.0;<br> optimizerScales[3] = 1.0;<br> optimizerScales[4] = translationScale;<br> optimizerScales[5] = translationScale;<br> optimizer->SetScales( optimizerScales );<br><br> double steplength = 1; //0.1<br> unsigned int maxNumberOfIterations = 200;
<br> optimizer->SetMaximumStepLength( steplength ); <br> optimizer->SetMinimumStepLength( 0.0001 ); //0.0001<br> optimizer->SetNumberOfIterations( maxNumberOfIterations );<br>//-----------------------------------------------------------------------------
<br><br><br> optimizer->MinimizeOn();<br><br> <br> CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New();<br> optimizer->AddObserver( itk::IterationEvent(), observer );<br><br> try <br> {
<br> registration->StartRegistration(); <br> } <br> catch( itk::ExceptionObject & err ) <br> { <br> std::cerr << "ExceptionObject caught !" << std::endl; <br> std::cerr << err << std::endl;
<br> return -1;<br> } <br><br><br><br>//-----------------------------------------------------------<br> OptimizerType::ParametersType finalParameters = <br> registration->GetLastTransformParameters();
<br><br> const double finalRotationCenterX = transform->GetCenter()[0];<br> const double finalRotationCenterY = transform->GetCenter()[1];<br> const double finalTranslationX = finalParameters[4];<br> const double finalTranslationY = finalParameters[5];
<br><br> const unsigned int numberOfIterations = optimizer->GetCurrentIteration();<br> <br> const double bestValue = optimizer->GetValue();<br> std::cout << "Result = " << std::endl;<br> std::cout << " Center X = " << finalRotationCenterX << std::endl;
<br> std::cout << " Center Y = " << finalRotationCenterY << std::endl;<br> std::cout << " Translation X = " << finalTranslationX << std::endl;<br> std::cout << " Translation Y = " << finalTranslationY << std::endl;
<br> std::cout << " Iterations = " << numberOfIterations << std::endl;<br> std::cout << " Metric value = " << bestValue << std::endl;<br> <br>