[Insight-users] problem with MI regsitration
Luis Ibanez
luis.ibanez at kitware.com
Wed Nov 10 17:02:12 EST 2004
Hi Yannick
Thanks for letting us know that you solved the problem.
Just to double-check:...
What you found is that calling
optimizer->MaximizeOn();
is not equivalent to calling
optimizer->MinimizeOff(); ??
If that's the case, that sounds like a bug in the optimizer...
Please let us know so we can trace this in case is a real bug.
Thanks
Luis
------------------------
Yannick Allard wrote:
> Hi Luis,
>
> Thank you for everything. It did work after the scaling but that was not the
> only problem. Somehow, even if I called the MaximizeOn function, the optimizer
> was still minimizing the MI, so I had to call the MinimizeOff function to solve
> that problem.
>
> Have a nice day
>
> Yannick
>
>
> Selon Luis Ibanez <luis.ibanez at kitware.com>:
>
>
>>Hi Yannick,
>>
>>
>>Thanks for posting your code.
>>
>>
>>You are not setting the scaling parameters for the transform.
>>
>>
>>Those values are fundamental when you use the AffineTransform
>>because the dynamic range of the coefficients in the rotational
>>part of the matrix is *much smaller* than the dynamic range of
>>the coefficients in the translational part.
>>
>>
>>
>>Please read the Chapter on Image Registration from the ITK
>>Software Guide
>>
>> http://www.itk.org/ItkSoftwareGuide.pdf
>>
>>
>>and pay particular attention to sections:
>>
>> 8.5.1 "Rigid Registration in 2D"
>> pdf-page 263, and its code in pdf-page 266.
>>
>>
>> AND
>>
>>
>> 8.6.2 "Parameter Tunning" in pdf-page 291.
>>
>>
>>If you don't to set the parameter scaling, the optimizer treats
>>angular units at the same range of translations, so you can easily
>>end up using rotations of 5 radians !!!
>>
>>
>>Note also that in general you should prefer the use of the
>>CenteredAffineTransform over the standard AffineTransform.
>>
>>
>>
>>and...
>>
>>as a standard issue you should always connect an observer to your
>>optimizer, so you can track its progress on the parametric space.
>>
>>
>>
>>
>> Regards,
>>
>>
>>
>> Luis
>>
>>
>>
>>---------------------------
>>Yannick Allard wrote:
>>
>>
>>>Hi Luis,
>>>
>>>here the code portion that I'm using to regsiter the output of the warper
>>
>>with
>>
>>>the fixed image. With that, all the samples points map outside the moving
>>>image... the output of the warper is perfect and the two image now have the
>>>same dimension and spacing, so I really dont know what is the problem...
>>
>>I'll
>>
>>>add the observer to see what wrong in the iteration :
>>>
>>> //Mutual information maximisation for coregistration refinement
>>>
>>> typedef itk::AffineTransform< double, Dimension > TransformType;
>>> typedef itk::GradientDescentOptimizer OptimizerType;
>>> typedef itk::LinearInterpolateImageFunction< FixedImageType, double >
>>>InterpolatorTypeMI;
>>> typedef itk::ImageRegistrationMethod< FixedImageType, FixedImageType >
>>>RegistrationType;
>>>
>>> TransformType::Pointer transform = TransformType::New();
>>> OptimizerType::Pointer optimizer = OptimizerType::New();
>>> InterpolatorTypeMI::Pointer interpolatorMI = InterpolatorTypeMI::New();
>>> RegistrationType::Pointer registration = RegistrationType::New();
>>> registration->SetOptimizer( optimizer );
>>> registration->SetTransform( transform );
>>> registration->SetInterpolator( interpolatorMI );
>>>
>>> typedef itk::MutualInformationImageToImageMetric< FixedImageType,
>>>FixedImageType > MetricType;
>>> MetricType::Pointer metric = MetricType::New();
>>> registration->SetMetric( metric );
>>>
>>> metric->SetFixedImageStandardDeviation( 0.4 );
>>> metric->SetMovingImageStandardDeviation( 0.4 );
>>> metric->SetNumberOfSpatialSamples( 100 );
>>>
>>> typedef itk::NormalizeImageFilter< FixedImageType, FixedImageType >
>>>FixedNormalizeFilterType;
>>> typedef itk::NormalizeImageFilter< MovingImageType, FixedImageType
>>>
>>>
>>>>MovingNormalizeFilterType;
>>>
>>> FixedNormalizeFilterType::Pointer fixedNormalizer =
>>>FixedNormalizeFilterType::New();
>>> MovingNormalizeFilterType::Pointer movingNormalizer =
>>>MovingNormalizeFilterType::New();
>>>
>>> typedef itk::DiscreteGaussianImageFilter< FixedImageType,
>>
>>FixedImageType >
>>
>>>GaussianFilterType;
>>> GaussianFilterType::Pointer fixedSmoother = GaussianFilterType::New();
>>> GaussianFilterType::Pointer movingSmoother = GaussianFilterType::New();
>>>
>>> fixedSmoother->SetVariance( 2.0 );
>>> movingSmoother->SetVariance( 2.0 );
>>>
>>> //Modify the following twolines of code to get the data from the
>>
>>databuffers
>>
>>> fixedNormalizer->SetInput( l_FixedImage );
>>> movingNormalizer->SetInput( warper->GetOutput() );
>>> movingNormalizer->Update();
>>> fixedNormalizer->Update();
>>>
>>> fixedSmoother->SetInput( fixedNormalizer->GetOutput() );
>>> movingSmoother->SetInput( movingNormalizer->GetOutput() );
>>> fixedSmoother->Update();
>>> movingSmoother->Update();
>>>
>>> registration->SetFixedImage( fixedSmoother->GetOutput() );
>>> registration->SetMovingImage( movingSmoother->GetOutput() );
>>>
>>> registration->SetFixedImageRegion(
>>>fixedNormalizer->GetOutput()->GetBufferedRegion() );
>>> typedef RegistrationType::ParametersType ParametersType;
>>>
>>> transform->SetIdentity();
>>>
>>>
>>> registration->SetInitialTransformParameters( transform->GetParameters()
>>
>>);
>>
>>> optimizer->SetLearningRate( 100.0 );
>>> optimizer->SetNumberOfIterations( 200 );
>>> optimizer->MaximizeOn();
>>>
>>> try
>>> {
>>> registration->StartRegistration();
>>> }
>>> catch( itk::ExceptionObject & err )
>>> {
>>> std::cerr << "ExceptionObject caught !" << std::endl;
>>> std::cerr << err << std::endl;
>>> return;
>>> }
>>>
>>> ParametersType finalParameters =
>>
>>registration->GetLastTransformParameters();
>>
>>> typedef itk::ResampleImageFilter< MovingImageType, FixedImageType >
>>>ResampleFilterType;
>>>
>>> TransformType::Pointer finalTransform = TransformType::New();
>>>
>>> // Print out results
>>> for( int Index = 0; Index < transform->GetNumberOfParameters(); Index++
>>
>>)
>>
>>> {
>>> std::cerr<<"Tranform parameters : "<<finalParameters[ Index
>>
>>]<<std::endl;
>>
>>> }
>>>
>>> finalTransform->SetParameters( finalParameters );
>>>
>>> ResampleFilterType::Pointer resample = ResampleFilterType::New();
>>>
>>> resample->SetTransform( finalTransform );
>>> resample->SetInput( warper->GetOutput() );
>>> resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );
>>> resample->SetOutputOrigin( fixedImage->GetOrigin() );
>>> resample->SetOutputSpacing( fixedImage->GetSpacing() );
>>> resample->SetDefaultPixelValue( 0.0 );
>>> resample->Update();
>>>
>>>
>>
>>
>>
>>
>>
>>
>
>
>
>
>
More information about the Insight-users
mailing list