[Insight-users] registration .. convergence to fast ...

Luis Ibanez luis.ibanez at kitware.com
Thu Nov 18 11:27:05 EST 2004



Hi Lagaffe,


1) When you use MutualInformation, you should try to
    Maximize it, not to minimize it as you are requesting
    in your code:

             optimizer->MinimizeOn();

    you should rather have

             optimizer->MaximizeOn();


2) If the optimizer is terminating too early, that means
    that the convergence criteria that you set in the
    optimizer are too relaxed. You should therefore explore
    different values for :

            maximumStepLength
            minimumStepLength


3) Note that running a Gradient Descent optimizer in a
    cost function as noisy as Mutual Information will
    not behave in the monotonical way that you may want.


4) The translation scales are also a critical parameter
    of the registration. When you say that the result of
    the registration is "not really good"...

     did you observe a residual misregistration in the

                  rotation ?
                  translation ?
                  both ?



Regards,


    Luis



------------------
Mr Gaffe wrote:

> Hello,
> The program below is based on registration example and allow an 
> centeredAffineTransform with a iMattesMutualInformation metric...
> I test it with BrainT1SliceBorder20.png and 
> BrainProtonDensitySliceR10X13Y17S12.png. The result is not so bad, but 
> not really good ...
> I think the convergence is to fast ... I think I had to change some 
> parameters but I don't where ....
> Thanks for help
> lagaffe
> -----------------------------------
> Initial Transform Parameters
> [1, 0, 0, 1, 110.771, 131.272, -12.3588, -12.3721]
> 0   -0.494313   [1.03129, 0.0592011, 0.0384303, 1.04259, 110.771, 
> 131.272, -12.3226, -12.3418]
> 1   -0.506525   [1.01369, 0.0180759, 0.0374976, 1.04872, 110.772, 
> 131.273, -12.3427, -12.3341]
> 2   -0.497655   [1.01052, 0.00387624, 0.0555589, 1.08858, 110.771, 
> 131.272, -12.3573, -12.3215]
> 3   -0.476204   [0.985719, -0.0221933, 0.0718157, 1.08991, 110.771, 
> 131.271, -12.3836, -12.3058]
> 4   -0.46122   [0.952404, -0.0489021, 0.0696406, 1.07258, 110.77, 
> 131.27, -12.4026, -12.3026]
> 5   -0.46892   [0.951745, -0.0356225, 0.0613028, 1.05532, 110.771, 
> 131.271, -12.3971, -12.3096]
> 6   -0.476501   [0.942724, -0.0359882, 0.0670168, 1.05927, 110.771, 
> 131.271, -12.4003, -12.3057]
> 7   -0.476813   [0.934107, -0.0352334, 0.073106! 4, 1.05942, 110.77, 
> 131.27, -12.4026, -12.2995]
> 8   -0.481887   [0.9309, -0.0309813, 0.0819638, 1.0591, 110.77, 131.27, 
> -12.4014, -12.2926]
> 9   -0.485281   [0.927642, -0.0303667, 0.088813, 1.06742, 110.769, 
> 131.269, -12.4017, -12.2872]
> 10   -0.483528   [0.923046, -0.0309841, 0.0869023, 1.06398, 110.769, 
> 131.27, -12.4023, -12.2885]
> 11   -0.486905   [0.922546, -0.0292402, 0.0886269, 1.06479, 110.769, 
> 131.269, -12.4015, -12.287]
> 12   -0.486916   [0.920049, -0.0300743, 0.0896122, 1.06465, 110.769, 
> 131.269, -12.4027, -12.2863]
> 13   -0.489127   [0.917638, -0.0309204, 0.0903297, 1.06447, 110.769, 
> 131.269, -12.4037, -12.2851]
> 14   -0.490183   [0.918016, -0.0299934, 0.0909949, 1.06494, 110.769, 
> 131.269, -12.4031, -12.2844]
> 15   -0.489932   [0.918292, -0.0290254, 0.0916975, 1.06503, 110.769, 
> 131.269, -12.4! 024, -12.2837]
> Result =
>  Center X      = 110.769
>  Center Y      = 131.269
>  Translation X = -12.4024
>  Translation Y = -12.2837
>  Iterations    = 17
>  Metric value  = -0.490452
>  
> -----------------------
> source code if someone want it:
>  
>  
> 
> #include "itkImageRegistrationMethod.h"
> //#include "itkMeanSquaresImageToImageMetric.h"
> #include "itkMattesMutualInformationImageToImageMetric.h"
> #include "itkLinearInterpolateImageFunction.h"
> #include "itkRegularStepGradientDescentOptimizer.h"
> #include "itkImage.h"
> 
> #include "itkCenteredTransformInitializer.h"
> #include "itkCenteredAffineTransform.h"
> #include "itkImageFileReader.h"
> #include "itkImageFileWriter.h"
> #include "itkResampleImageFilter.h"
> #include "itkCastImageFilter.h"
> #include "itkSquaredDifferenceImageFilter.h"
> #include "itkCommand.h"
> class CommandIterationUpdate : public itk::Command
> {
> public:
>   typedef  CommandIterationUpdate   Self;
>   typedef  itk::Command             Superclass;
>   typedef itk::SmartPointer<Self>  Pointer;
>   itkNewMacro( Self );
> protected:
>   CommandIterationUpdate() {};
> public:
>   typedef itk::RegularStepGradientDescentOptimizer     OptimizerType;
>   typedef   const OptimizerType   *    OptimizerPointer;
>   void Execute(itk::Object *caller, const itk::EventObject & event)
>   {
>     Execute( (const itk::Object *)caller, event);
>   }
>   void Execute(const itk::Object * object, const itk::EventObject & event)
>   {
>     OptimizerPointer optimizer =
>                       dynamic_cast< OptimizerPointer >( object );
>     if( typeid( event ) != typeid( itk::IterationEvent ) )
>       {
>       return;
>       }
>       std::cout << optimizer->GetCurrentIteration() << "   ";
>       std::cout << optimizer->GetValue() << "   ";
>       std::cout << optimizer->GetCurrentPosition() << std::endl;
>   }
> };
> 
> int main( int argc, char *argv[] )
> {
>   if( argc < 4 )
>     {
>     std::cerr << "Missing Parameters " << std::endl;
>     std::cerr << "Usage: " << argv[0];
>     std::cerr << "   fixedImageFile  movingImageFile " << std::endl;
>     std::cerr << "   outputImagefile  [differenceOutputfile] 
> [differenceBeforeRegistration] " << std::endl;
>     std::cerr << "   [stepLength] [maxNumberOfIterations] "<< std::endl;
>     return 1;
>     }
>   const    unsigned int    Dimension = 2;
>   typedef  float           PixelType;
>   typedef itk::Image< PixelType, Dimension >  FixedImageType;
>   typedef itk::Image< PixelType, Dimension >  MovingImageType;
>  
>   typedef itk::CenteredAffineTransform<
>                                   double,
>                                   Dimension  >     TransformType;
>   typedef itk::RegularStepGradientDescentOptimizer       OptimizerType;
>   /*
>   typedef itk::MeanSquaresImageToImageMetric<
>                                     FixedImageType,
>                                     MovingImageType >    MetricType;
>   */
>   
>   typedef itk::MattesMutualInformationImageToImageMetric<
>                                           FixedImageType,
>                                           MovingImageType >    MetricType;
>   typedef itk:: LinearInterpolateImageFunction<
>                                     MovingImageType,
>                                     double          >    InterpolatorType;
>   typedef itk::ImageRegistrationMethod<
>                                     FixedImageType,
>                                     MovingImageType >    RegistrationType;
>   MetricType::Pointer         metric        = MetricType::New();
>   OptimizerType::Pointer      optimizer     = OptimizerType::New();
>   InterpolatorType::Pointer   interpolator  = InterpolatorType::New();
>   RegistrationType::Pointer   registration  = RegistrationType::New();
>   registration->SetMetric(        metric        );
>   registration->SetOptimizer(     optimizer     );
>   registration->SetInterpolator(  interpolator  );
>   metric->SetNumberOfHistogramBins( 50 );
>   metric->SetNumberOfSpatialSamples( 10000 );
>   TransformType::Pointer  transform = TransformType::New();
>   registration->SetTransform( transform );
>   typedef itk::ImageFileReader< FixedImageType  > FixedImageReaderType;
>   typedef itk::ImageFileReader< MovingImageType > MovingImageReaderType;
>   FixedImageReaderType::Pointer  fixedImageReader  = 
> FixedImageReaderType::New();
>   MovingImageReaderType::Pointer movingImageReader = 
> MovingImageReaderType::New();
>   fixedImageReader->SetFileName(  argv[1] );
>   movingImageReader->SetFileName( argv[2] );
> 
>   registration->SetFixedImage(    fixedImageReader->GetOutput()    );
>   registration->SetMovingImage(   movingImageReader->GetOutput()   );
>   fixedImageReader->Update();
>   registration->SetFixedImageRegion(
>      fixedImageReader->GetOutput()->GetBufferedRegion() );
>   typedef itk::CenteredTransformInitializer<
>                                     TransformType,
>                                     FixedImageType,
>                                     MovingImageType >  
> TransformInitializerType;
>   TransformInitializerType::Pointer initializer = 
> TransformInitializerType::New();
>   initializer->SetTransform(   transform );
>   initializer->SetFixedImage(  fixedImageReader->GetOutput() );
>   initializer->SetMovingImage( movingImageReader->GetOutput() );
>   initializer->MomentsOn();
>   initializer->InitializeTransform();
>   std::cout << "Initial Transform Parameters " << std::endl;
>   std::cout << transform->GetParameters() << std::endl;
>  
> // -----------------------
>   registration->SetInitialTransformParameters(
>                                  transform->GetParameters() );
> 
>   double translationScale = 1.0 / 1000.0;
>   if( argc > 8 )
>     {
>     translationScale = atof( argv[8] );
>     }
>  typedef OptimizerType::ScalesType       OptimizerScalesType;
>   OptimizerScalesType optimizerScales( transform->GetNumberOfParameters() );
>   optimizerScales[0] =  0.1;
>   optimizerScales[1] =  0.1;
>   optimizerScales[2] =  0.1;
>   optimizerScales[3] =  0.1;
>   optimizerScales[4] =  translationScale;
>   optimizerScales[5] =  translationScale;
>   optimizerScales[6] =  translationScale;
>   optimizerScales[7] =  translationScale;
>   optimizer->SetScales( optimizerScales );
>   double steplength = 0.1;
>   if( argc > 6 )
>     {
>     steplength = atof( argv[6] );
>     }
> 
>   unsigned int maxNumberOfIterations = 300;
>   if( argc > 7 )
>     {
>     maxNumberOfIterations = atoi( argv[7] );
>     }
>    optimizer->SetMaximumStepLength( steplength ); 
>   optimizer->SetMinimumStepLength( 0.001 );
>   optimizer->SetNumberOfIterations( maxNumberOfIterations );
>   optimizer->MinimizeOn();
>   CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New();
>   optimizer->AddObserver( itk::IterationEvent(), observer );
> try
>     {
>     registration->StartRegistration();
>     }
>   catch( itk::ExceptionObject & err )
>     {
>     std::cerr << "ExceptionObject caught !" << std::endl;
>     std::cerr << err << std::endl;
>     return -1;
>     }
>   OptimizerType::ParametersType finalParameters =
>                     registration->GetLastTransformParameters();
>   const double finalRotationCenterX = finalParameters[4];
>   const double finalRotationCenterY = finalParameters[5];
>   const double finalTranslationX    = finalParameters[6];
>   const double finalTranslationY    = finalParameters[7];
>   const unsigned int numberOfIterations = optimizer->GetCurrentIteration();
>   const double bestValue = optimizer->GetValue();
>   // Software Guide : EndCodeSnippet
> 
>   // Print out results
>   //
>   std::cout << "Result = " << std::endl;
>   std::cout << " Center X      = " << finalRotationCenterX  << std::endl;
>   std::cout << " Center Y      = " << finalRotationCenterY  << std::endl;
>   std::cout << " Translation X = " << finalTranslationX  << std::endl;
>   std::cout << " Translation Y = " << finalTranslationY  << std::endl;
>   std::cout << " Iterations    = " << numberOfIterations << std::endl;
>   std::cout << " Metric value  = " << bestValue          << std::endl;
>   typedef itk::ResampleImageFilter<
>                             MovingImageType,
>                             FixedImageType >    ResampleFilterType;
>   TransformType::Pointer finalTransform = TransformType::New();
>   finalTransform->SetParameters( finalParameters );
>   ResampleFilterType::Pointer resample = ResampleFilterType::New();
>   resample->SetTransform( finalTransform );
>   resample->SetInput( movingImageReader->GetOutput() );
>   FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput();
>   resample->SetSize(    fixedImage->GetLargestPossibleRegion().GetSize() );
>   resample->SetOutputOrigin(  fixedImage->GetOrigin() );
>   resample->SetOutputSpacing( fixedImage->GetSpacing() );
>   resample->SetDefaultPixelValue( 100 );
>  
>   typedef  unsigned char  OutputPixelType;
>   typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
>  
>   typedef itk::CastImageFilter<
>                         FixedImageType,
>                         OutputImageType > CastFilterType;
>                    
>   typedef itk::ImageFileWriter< OutputImageType >  WriterType;
> 
>   WriterType::Pointer      writer =  WriterType::New();
>   CastFilterType::Pointer  caster =  CastFilterType::New();
> 
>   writer->SetFileName( argv[3] );
> 
>   caster->SetInput( resample->GetOutput() );
>   writer->SetInput( caster->GetOutput()   );
>   writer->Update();
> 
>   typedef itk::SquaredDifferenceImageFilter<
>                                   FixedImageType,
>                                   FixedImageType,
>                                   OutputImageType > DifferenceFilterType;
>   DifferenceFilterType::Pointer difference = DifferenceFilterType::New();
>   WriterType::Pointer writer2 = WriterType::New();
>   writer2->SetInput( difference->GetOutput() ); 
>  
>   if( argc > 4 )
>     {
>     difference->SetInput1( fixedImageReader->GetOutput() );
>     difference->SetInput2( resample->GetOutput() );
>     writer2->SetFileName( argv[4] );
>     writer2->Update();
>     }
> 
>   if( argc > 5 )
>     {
>     writer2->SetFileName( argv[5] );
>     difference->SetInput1( fixedImageReader->GetOutput() );
>     difference->SetInput2( movingImageReader->GetOutput() );
>     writer2->Update();
>     }
> 
>   return 0;
> }
>  
> 
> ------------------------------------------------------------------------
> Créez gratuitement votre Yahoo! Mail avec *100 Mo de stockage !*
> Créez votre Yahoo! Mail 
> <http://fr.rd.yahoo.com/mail/taglines/*http://fr.rd.yahoo.com/evt=25917/*http://fr.rd.yahoo.com/mail/mail_taglines_100/default/*http://fr.benefits.yahoo.com/>
> 
> *Le nouveau Yahoo! Messenger est arrivé !* Découvrez toutes les 
> nouveautés pour dialoguer instantanément avec vos amis. Téléchargez 
> GRATUITEMENT ici ! 
> <http://fr.rd.yahoo.com/mail/taglines/*http://fr.rd.yahoo.com/evt=26111/*http://fr.rd.yahoo.com/messenger/mail_taglines/default/*http://fr.messenger.yahoo.com> 
> 
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> 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