[Insight-users] Registration - Mutual Information + Affine - Fine tuning of parameters for optimization

Luis Ibanez luis.ibanez at kitware.com
Thu Jul 2 19:28:59 EDT 2009


Hi Sharath,


0) It is great that you have verified the Initialization


1) Translation initialization is "usually" enough...
     but only if the rotation and scaling misalignments
     are small....

     A typical registration will not be able to correct
     for more than a 30 degrees rotation, or a scaling
     beyond a factor of 1.5.

     So, please provide all the initialization that you can.

     You may want to consider the use of the

           LandmarkBasedTransformInitializer


2)  If you results start diverging from the expected answer
     in the very first iterations, then you should suspect:

       a) Incorrect balance of the rotation vs translation
           values in the parameter scaling array

                               or

        b) Your step lenghts are too large in the optimizer

                                or

        c)  You may have set the Optimizer to Maximize, when
             the Metric needs to be Minimized (or the other way
             around).


3) You are correct that if the Registration is walking in the
     right direction, the Joint histograms should be getting
     more concentrated in the diagonal...

     BUT ONLY IF

     you are working with two images of the same modality.

     Otherwise, if the images are of different modality, the
     histogram will never be concentrated in the diagonal.


4) Unfortunately we don't have much material written on
    how to analyze the histograms.

    I will suggest that you save them as images using the
    Histogram to Image filter, and then load them as a
    series of 2D+T images into VV

              http://www.creatis.insa-lyon.fr/rio/vv

    so that you can play them as an animation.


5)  The typical use of the vtkRegistrationMonitor will be:

  #include "vtkRegistrationMonitor.h"
  #include "vtkKWImage.h"
  #include "vtkContourFilter.h"
  #include "vtkImageData.h"

 vtkRegistrationMonitor monitor;

  vtkSmartPointer< vtkKWImage > fixedKWImage  = vtkSmartPointer< vtkKWImage
>::New();
  vtkSmartPointer< vtkKWImage > movingKWImage   = vtkSmartPointer<
vtkKWImage >::New();

  fixedKWImage->SetITKImageBase( const_cast<FixedImageType *>( fixedImage )
);
  movingKWImage->SetITKImageBase( const_cast<MovingImageType *>( movingImage
) );

  vtkSmartPointer< vtkContourFilter > fixedContour  = vtkSmartPointer<
vtkContourFilter >::New();
  vtkSmartPointer< vtkContourFilter > movingContour = vtkSmartPointer<
vtkContourFilter >::New();

  fixedContour->SetInput( fixedKWImage->GetVTKImage() );
  movingContour->SetInput( movingKWImage->GetVTKImage() );

  fixedContour->SetValue(  0, 200.0 ); // level for iso-contour (DEPENDS on
your data)
  movingContour->SetValue( 0, 200.0 ); // level for iso-contour (DEPENDS on
your data)

  monitor.SetFixedSurface( fixedContour->GetOutput() );
  monitor.SetMovingSurface( movingContour->GetOutput() );

  monitor.SetNumberOfIterationPerUpdate( 1 ); (RECONSIDER CHANGING...)

  std::string screenshotDirectory = argv[7];
  itksys::SystemTools::MakeDirectory( screenshotDirectory.c_str() );

  std::cout <<  screenshotDirectory << std::endl;

  monitor.SetScreenshotOutputDirectory( screenshotDirectory.c_str() );
  monitor.SetScreenshotBaseName( "registrationScreenshot" );

  monitor.Observe( optimizer, rigidTransform );


You will find the vtkKWImage classes also in

   InsightApplications/Auxiliary/vtk


---

  Regards,


      Luis


----------------------------------------------------------------------
On Thu, Jul 2, 2009 at 3:01 PM, Sharath Venkatesha
<sharath20284 at yahoo.com>wrote:

>
> Hi,
>
> Thanks for the all the help and information provided in the earlier mails.
>
> I have ensured that I am using correct initialization ( translation only)
> and correct values of optimizer scales.
>
> *** Is it sufficient if I provide initialization parameters for translation
> (approx values) only? It is difficult for me estimate the scale and rotation
> parameters.
>
> I am using MutualInformationHistogramImageToImageMetric +
> MultiResolutionImageRegistrationMethod + AffineTransform +
> RegularStepGradientDescentOptimizer/GradientDescentOptimizer
>
> I am having problem with tuning of parameters (MaxStepSize and MinStepSize
> for RegularStepGradientDescentOptimizer, and LearningRate for
> GradientDescentOptimizer) . My results start diverging off the correct route
> in the first few iterations itself.
>
> I have looked into
> (1) Plotting of joint histograms   (section 8.5.3 of ITK manual)
> (2)  vtkRegistrationMonitor
>
>
> I am having trouble interpreting the results of the joint histograms.I
> understand that with correct parameters for registration, I should get a
> histogram which has highest density only along the diagonal.  I have the
> outputs of the JointHistograms after very iteration for very level , and
> finding hard to follow the changes.
>
> *** Is there is a defined procedure for understanding the results?
>
> Can you please point me to where I can get more information on (1) and (2)
> ?
>
> Thanks,
> Sharath Venkatesha
>
>
> ------------------------------
> Luis wrote:
>
>
> Hi Sharath,
>
> 0) Whenever you get the exception saying that too many points
>    mapped outside of the moving image, it means that the
>    current Transform is such that when mapping the moving image
>    into the Fixed image coordinate system the overlap between
>    the two image is so small that it is unlikely that the
>    registration will recover in further iterations.
>
>    This is typically due to:
>
>
>        A) Poor initilization of the Transform
>
>        B) Poor selection of Scaling parameters
>           (the array that normalizes the dynamic
>            range of the different Transform parameters,
>            e.g. radians versus millimeters)
>
>        C) Optimizers that are set to perform jumps
>           that are too large, and bring the Transform
>           out of the range of the image.
>
> 1) You want to check this potential suspects in order.
>
>    That is.
>
>    First, verify that the initial transform
>    is reasonably placing the Moving image on top of the
>    Fixed image. You can do this by using the Resample
>    image filter, passing the moving image as input,
>    using the initial transform as Transform, and using
>    the Fixed image as reference. Then compare the
>    fixed image to the resampled moving image.
>
>    If the initial image looks ok,
>    then you want to check the values of the ParameterScaling.
>    It should be such that when you look at the Transform
>    parameters at ever iteration (using an Observer), the
>    values should change from iteration to iteration, according
>    to the expected dynamic range.
>
>    For example, transform parameters that correspond to rotations
>    should change by increments smaller than 0.01 (since they are
>    measured in Radians).  While transform parameters that correspond
>    to translations should change at increments of 1 ~ 10
>
>
>    Finally, you should identify the parameter of the optimzer
>    that is responsible for selecting the size of jumps that
>    are performed in the parameteric space.  (e.g. as you have
>    done for the learning rate in the GradientDescent optimizer).
>
>    You want to reduce the size of that jump, until you get the
>    Transform to have small increments at every iteration.
>
>
> 2) These parameters must be set up for every "family" of
>    registration problems.  That is, the parameters that may be
>    good for registering a T1 to T2 MRI brain images, may not be
>    appropriate for registering a confocal microscopy image to
>    another.
>
>    However, once you fine tune the paramters for a pair of
>    T1-T2 images, it is likely that the same set of parameters
>    will work for another pair of the same type.
>
>    There is a need for a "smart layer" above the registration
>    framework, that could take away from the user the burden
>    of finding proper parameter settings....
>
>    any ideas are welcome  :-)
>
>
> 3) Visual monitoring of the registraiton process
>    will help to make the fine-tunning process less
>    frustrating.
>
>    You may want to give it a try at the VTK helper
>    classes:
>
>       InsightApplications/Auxiliary/vtk/
>                      vtkRegistrationMonitor.h
>                      vtkRegistrationMonitor.cxx
>
>     they will display renderings from iso-surfaces
>     at every iteration of the registration process.
>
>     This is usually very informative...
>
>
>
>   Regards,
>
>
>      Luis
>
>
> --------------
> sharath v wrote:
> > Hi,
> >
> > Thanks for the help. Changing the learning parameter worked...
> >
> >
> For Viola MI + Affine and with learning rate of 0.01 and 100
> iterations, I get good results on BrainProtonDensitySliceR10X13Y17
> image. Whereas on the BrainProtonDensitySliceR10X13Y17S12 image, it
> requires atleast 200 iterations to give correct results.
> >
> >
> I want to use an optimizer which has a stopping value (i.e not fixed
> number of iterations) like Amoeba/Evolutionary/GradientDescentStep
> >
> > I tried using the Amoeba optimizer with the following
> >
> >     OptimizerType::ParametersType simplexDelta(
> transform->GetNumberOfParameters() );
> >     simplexDelta.Fill( 5.0 );
> >     optimizer->AutomaticInitialSimplexOff();
> >     optimizer->SetInitialSimplexDelta( simplexDelta );
> >     optimizer->SetParametersConvergenceTolerance( 0.01 ); // quarter
> pixel
> >     optimizer->SetFunctionConvergenceTolerance(0.001); // 0.1%
> >     optimizer->SetMaximumNumberOfIterations( 200 );
> >
> >
> but I get an exception that sampled point mapped  to outside of the
> moving image, after 6-7 iterations. Similar issue happens for
> OnePlusOne optimizer with
> >
> >     typedef itk::Statistics::NormalVariateGenerator  GeneratorType;
> >     GeneratorType::Pointer generator = GeneratorType::New();
> >     generator->Initialize(12345);
> >     optimizer->SetNormalVariateGenerator( generator );
> >     optimizer->Initialize( 10 );
> >     optimizer->SetEpsilon( 1.0 );
> >     optimizer->SetMaximumIteration( 4000 );
> >
> > Can you please let me know what values need to be used?
> >
> > And is there a way to make the registration process partially independent
> of these parameters?
> >
> > Thanks,
> > Sharath
>
>
>
>
>
> _____________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the ITK FAQ at:
> http://www.itk.org/Wiki/ITK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.itk.org/mailman/listinfo/insight-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20090702/06c3da27/attachment-0001.htm>


More information about the Insight-users mailing list