[Insight-users] DemonsRegistrationFilter (How to fine tune)

Vincent Luboz Vincent.Luboz at imag.fr
Mon Nov 8 15:56:13 EST 2004


Hi Luis

Thanks a lot for your quick answer!
I tried to address my problems with your propositions and I still have few 
questions:

> 1) Don't be affraid of trying multi-resolution.
>     There are multiple advantages in the multi-resolution
>     approach and in practical cases you want all of those
>     advantages, for example: increase performance and
>     stability.

I downsampled the images on one of the axis by 2 and the results have an error 
larger than with the original data. Based on this conclusion, I decided to 
avoid the multi resolution approach


> 2) If the deformation field resulting from the DEMONS
>     algorithm is returning displacement that are too large
>     it means that you should increase the smoothing during
>     iterations.  Use the SetStandardDeviation() method:
> 
http://www.itk.org/Insight/Doxygen/html/classitk_1_1PDEDeformableRegistrationFi
lter.html#z262_0
>     in order to increase the level of smoothing.  The stronger
>     the smoothing, the more you will constraing the deformation
>     field. 

I tried to increase the smoothing level by changing the value of the standard 
deviation (I tried a smoothing value of 1, 2, 5 and 10). Globally, it takes 
more iterations to reach the same displacement field. But there is still this 
problem of convergence
 if I increase the number of iterations the values of 
the displacement field increase
 To give an idea, I tried to go up to 2000 
iterations with a smoothing level of 5 and the maximum value of the 
displacement field was still increasing

Does it mean that I have to increase the number of iterations to reach the 
convergence?

> Note that you should also verify the settings of the
>     Kernel Width and the Maximum Error for the Gaussian smoothing.
>     These parameters are explained in the documentation of the
>     DiscreteGaussianImageFilter

I didn’t find how to link the demonsRegistration filter to this discrete 
Gaussian filter
 How would you do?
I tried to use the methods SetMaximumError and SetMaximumKernelWidth from the 
class itkPDEDeformableRegistrationFilter but they are virtual methods and 
cannot be used in the demonsRegistration filter
 Do we have to complete the 
code of those 2 methods in order to use them, or is there a way to get the 2 
methods described in DiscreteGaussianImageFilter?

> 3) The maximum number of iteration for the DEMONS filter, or any
>     other PDEDeformableRegistration filter, for that matter,
> 
http://www.itk.org/Insight/Doxygen/html/classitk_1_1PDEDeformableRegistrationFi
lter.html
>     is only preventing the filter from running for ever. The real
>     converging criterion is the MaxRMSError(). The way to drive the
>     convergence of this filter is to plot the values returned from
>     its internal metric. 

To overcome the problem of convergence, I changed the value of the RMS Error 
as you proposed. I tried with the following values: 0.0, 0.2, 0.8, 1.0, and 
5.0. For all of them, I tried 60 iterations and then 400 iterations. All of 
them give exactly the same result. Did I do something wrong? (the values are 
out of bound? too small? not enough iterations?)

Here is my piece of code for the registration algorithm:
> > 
> > // The input fixed image is simply the output of the fixed image casting
> > // filter.  The input moving image is the output of the histogram matching
> > filter.
> > registrationFilter->SetFixedImage(fixedImageReader->GetOutput());
> > registrationFilter->SetMovingImage(movingImageReader->GetOutput());
> > 
> > // The demons registration filter has two parameters: the number of
> > // iterations to be performed and the standard deviation of the Gaussian
> > // smoothing kernel to be applied to the deformation field after each 
> > iteration.
> > registrationFilter->SetNumberOfIterations( 400 );
> > registrationFilter->SetStandardDeviations( 5.0 );
> > 
> > // Set the maximum error allowed in the solution
> > registrationFilter->SetMaximumRMSError(0.8); 
> > 
> > // The registration algorithm is triggered by updating the filter. The
> > // filter output is the computed deformation field.
> > registrationFilter->Update();


Thanks again for your help!

Best regards,

Vincent.





Quoting Luis Ibanez <luis.ibanez at kitware.com>:
> 
> 
> Hi Vincent,
> 
> 
> 1) Don't be affraid of trying multi-resolution.
>     There are multiple advantages in the multi-resolution
>     approach and in practical cases you want all of those
>     advantages, for example: increase performance and
>     stability.
> 
>     The *only* way to know if the results are going to be
>     worst is to try the method. It takes time an energy...
>     but it is better than just being supersticious  :-)
> 
> 
> 2) If the deformation field resulting from the DEMONS
>     algorithm is returning displacement that are too large
>     it means that you should increase the smoothing during
>     iterations.  Use the SetStandardDeviation() method:
> 
http://www.itk.org/Insight/Doxygen/html/classitk_1_1PDEDeformableRegistrationFi
lter.html#z262_0
>     in order to increase the level of smoothing.  The stronger
>     the smoothing, the more you will constraing the deformation
>     field.  Note that you should also verify the settings of the
>     Kernel Width and the Maximum Error for the Gaussian smoothing.
>     These parameters are explained in the documentation of the
>     DiscreteGaussianImageFilter
>  
> 
http://www.itk.org/Insight/Doxygen/html/classitk_1_1DiscreteGaussianImageFilter
.html
> 
> 
> 
> 
> 3) The maximum number of iteration for the DEMONS filter, or any
>     other PDEDeformableRegistration filter, for that matter,
> 
http://www.itk.org/Insight/Doxygen/html/classitk_1_1PDEDeformableRegistrationFi
lter.html
>     is only preventing the filter from running for ever. The real
>     converging criterion is the MaxRMSError(). The way to drive the
>     convergence of this filter is to plot the values returned from
>     its internal metric.  You will find examples on how to do this
>     by calling the GetMetric() method in the following files
> 
>         Insight/Examples/Registration/
>                   DeformableRegistration2.cxx
>                   DeformableRegistration3.cxx
>                   DeformableRegistration5.cxx
> 
> 
>      The typical plot of the DEMONS metric (which is nothing else than
>      the sum of square differences) has the appearance of an exponential
>      decay. Meaning that it drops rapidly during the first iterations,
>      and then in continues decreasing at a very slow pace.  It is
>      therefore for you a matter of deciding when you have invested enough
>      computation time for the metric reduction that you are obtaining.
> 
>      Please plot the values of the metric, as illustrated in the examples
>      above, and see how those plots change when you modify the level of
>      smoothing in the DEMONS filter.
> 
> 
> 
> 
>   Please let us know if you have further questions,
> 
> 
> 
>      Thanks
> 
> 
>        Luis
> 
> 
> 
> 
> ----------------------------
> Vincent Luboz wrote:
> 
> > Hi Luis
> > 
> > Thanks a lot for your help, everything is going much faster now!!
> > 
> > 
> >>1) Try compiling for Release (BTW are you in Windows or Unix ?)
> > 
> > 
> > You were right: compiling for Release help a lot!! I'm using Visual .net on
> 
> > Windows XP, and the program run 10 times faster in its release version! 
> > 
> > 
> >>4) Given that your data is CT, I don't think you need to preprocess
> >>    your data with HistogramMatching at all. The natural calibration
> >>    of intensity in CT should be good enough for allowing the two
> >>    images to be registered based on the local Optical Flow computed
> >>    by the Demons algorithm.
> > 
> > 
> > Ok, I tried without histogram and it works as good as with it.
> > Consequently, I deleted it and go straight to the matching.
> >  
> > 
> >>    Just skip the "Matcher" filters. Note that you can also get rid
> >>    of the "Casters" if you instantiate your readers for using
> >>    Images of pixel type float from the beginning.  The Reader will
> >>    cast the image data at reading time. These two changes will remove
> >>    (2X + 2*2X = 6X ) copies of your input images from the memory
> >>    taken by the pipeline. It should help to bring down the
> >>    memory footprint of 1.4Gb that you observed.
> > 
> > 
> > Right, I changed that into my code too, and I gain quite a lot in memory!
> > 
> > 
> >>Please let us know if you have further questions.
> > 
> > 
> > well, I do have one more question:
> > 
> > 
> >>2) Demons doesn't have a multi-resolution option built-in, but
> >>    you can manually set up your program in order to do the
> >>    subsampling, solve the registration in the subsampled images,
> >>    then Super-sample the resulting deformation field in order
> >>    to use it in the next finer grid.  All the necessary components
> >>    to do this are already in the toolkit.
> > 
> > 
> > I would like to try that multi resolution filter but the results given
> without 
> > downsampling my images are not that good and I am afraid they would be
> worst 
> > if I use it.
> > By the way, how can I improve the results of the demon algorithm?
> > Indeed, I tried to increase the number of iterations (50, 500 and 5000) but
> 
> > the displacement field resulting is always increasing and in many place it
> is 
> > going far beyond the real displacement observed during the experiment. I
> was 
> > expecting it converged to something stable after a certain number of 
> > iterations, but it doesn't seem to be the case. Do I have to change
> something 
> > else in my code?
> > I tried to use a gaussian smoothing (the sigma parameter of the demon 
> > algorithm) of 2, 5 and 10, but still, the algorithm does not converge.
> > Have you got any hints, please?
> > 
> > Here is my code if it can help you:
> > // declaration of the types of the images
> > typedef itk::Image< float, Dimension >  FixedAndMovingImageType;
> > 
> > typedef itk::ImageFileReader<FixedAndMovingImageType> 
> > FixedAndMovingImageReaderType;
> > 
> > FixedAndMovingImageReaderType::Pointer fixedImageReader   = 
> > FixedAndMovingImageReaderType::New();
> > FixedAndMovingImageReaderType::Pointer movingImageReader = 
> > FixedAndMovingImageReaderType::New();
> > 	
> > fixedImageReader->SetFileName(fixedImageFileName);
> > movingImageReader->SetFileName(movingImageFileName);
> > 
> > // In the DemonsRegistrationFilter, the deformation field is
> > // represented as an image whose pixels are floating point vectors.
> > typedef itk::Vector< float, Dimension >    VectorPixelType;
> > typedef itk::Image<VectorPixelType, Dimension> DeformationFieldType;
> > typedef itk::DemonsRegistrationFilter<
> >                           FixedAndMovingImageType,
> >                           FixedAndMovingImageType,
> >                           DeformationFieldType>   RegistrationFilterType;
> > RegistrationFilterType::Pointer registrationFilter = 
> > RegistrationFilterType::New();
> > 
> > // The input fixed image is simply the output of the fixed image casting
> > // filter.  The input moving image is the output of the histogram matching
> 
> > filter.
> > registrationFilter->SetFixedImage(fixedImageReader->GetOutput());
> > registrationFilter->SetMovingImage(movingImageReader->GetOutput());
> > 
> > // The demons registration filter has two parameters: the number of
> > // iterations to be performed and the standard deviation of the Gaussian
> > // smoothing kernel to be applied to the deformation field after each 
> > iteration.
> > registrationFilter->SetNumberOfIterations( 150 );
> > registrationFilter->SetStandardDeviations( 10.0 );
> > 
> > // The registration algorithm is triggered by updating the filter. The
> > // filter output is the computed deformation field.
> > registrationFilter->Update();
> > 
> > It compiles and works but is still not converging to a stable displacement
> 
> > field.
> > 
> > Thanks in advance,
> > 
> > Vincent.
> > 
> > 
> > 
> > 
> > 
> > 
> > previous emails:
> > 
> > 
> >>------------------------
> >>
> >>Vincent Luboz wrote:
> >>
> >>
> >>>Hi Luis
> >>>
> >>>Thanks a lot for your answer!
> >>>
> >>>Few answers to your questions and then more questions:   ;-)
> >>>
> >>>
> >>>
> >>>>1) Did you compiled your code for "Release" ?
> >>>>   Just that could give you up to a factor of
> >>>>   10X in execution time.
> >>>
> >>>
> >>>Right, I didn't think about that and I am actually compling in Debug... I
> >>
> >>am 
> >>
> >>>going to change that.
> >>>
> >>>
> >>>
> >>>>2) When you attempt to use Demons in 3D image
> >>>>   you usually want to do this in a multi-resolution
> >>>>   framework, especially if you exect to find large
> >>>>   deformations.
> >>>
> >>>
> >>>So you mean I should use a filter to downsample the 3D images? or is
> there
> >>
> >>an 
> >>
> >>>option in the itkDemonRegistration to take this into account?
> >>>
> >>>
> >>>
> >>>>3) The number of matchnig points that you set up
> >>>>   in the histogram (10,000) seems to be excesive.
> >>>>   Is there a particular reason why you decided to
> >>>>   go that far ?
> >>>>   What is the pixel type of your images  ?
> >>>
> >>>
> >>>The pixel type of my image is unsigne short.
> >>>I used 10000 points in the histogram since I thought that this value was
> >>
> >>the 
> >>
> >>>number of points (placed regularly on a grid) used to compute the elastic
> 
> >>>transformation from one image to another.
> >>>Is it wrong?
> >>>
> >>>You say that I could get rid of the histogram part.
> >>>
> >>>So you mean, instead of having
> >>>registrationFilter->SetMovingImage(matcher->GetOutput());
> >>>in the following code, I would have:
> >>>registrationFilter->SetMovingImage(movingImageCaster->GetOutput());
> >>>where matcher is the histogram filter and movingImageCaster is the moving
> 
> >>>image after being cast.
> >>>
> >>>// In the DemonsRegistrationFilter, the deformation field is
> >>>// represented as an image whose pixels are floating point vectors.
> >>>typedef itk::Vector< float, Dimension >    VectorPixelType;
> >>>typedef itk::Image<VectorPixelType, Dimension> DeformationFieldType;
> >>>typedef itk::DemonsRegistrationFilter<
> >>>              InternalImageType,
> >>>              InternalImageType,
> >>>              DeformationFieldType>   RegistrationFilterType;
> >>>
> >>>RegistrationFilterType::Pointer registrationFilter = 
> >>>RegistrationFilterType::New();
> >>>
> >>>// The input fixed image is simply the output of the fixed image casting
> >>>// filter.  The input moving image is the output of the histogram
> matching
> >>
> >>>filter.
> >>>registrationFilter->SetFixedImage(fixedImageCaster->GetOutput());
> >>>registrationFilter->SetMovingImage(matcher->GetOutput());
> >>>
> >>>is it correct?
> >>>
> >>>Again, thanks a lot for your help
> >>>
> >>>Best regards,
> >>>
> >>>Vincent.
> >>>
> >>>
> >>>Quoting Luis Ibanez <luis.ibanez at kitware.com>:
> >>>
> >>>
> >>>>Hi Vincent,
> >>>>
> >>>>Memory leaks should in principle show up in our daily
> >>>>Purify builds. Nothing seems to be reported for the
> >>>>DemonsRegistration filter, as you can see from the most
> >>>>recent Purify build:
> >>>>
> >>>>http://www.itk.org/Testing/Sites/moxel2.crd/WinNT-VC++60/20040927-0500-
> >>>
> >>>Nightly/DynamicAnalysis.html
> >>>
> >>>
> >>>>You probably can speed up a lot your registration
> >>>>by considering the following issues:
> >>>>
> >>>>1) Did you compiled your code for "Release" ?
> >>>>   Just that could give you up to a factor of
> >>>>   10X in execution time.
> >>>>
> >>>>2) When you attempt to use Demons in 3D image
> >>>>   you usually want to do this in a multi-resolution
> >>>>   framework, especially if you exect to find large
> >>>>   deformations.
> >>>>
> >>>>3) The number of matchnig points that you set up
> >>>>   in the histogram (10,000) seems to be excesive.
> >>>>   Is there a particular reason why you decided to
> >>>>   go that far ?
> >>>>   What is the pixel type of your images  ?
> >>>>
> >>>>4) When you are using CT scans you usually don't
> >>>>   need the HistogramIntensity correction at all.
> >>>>   Intensigy correction is mostly oriented to MRI
> >>>>   images that tend to have arbitrary scalings in
> >>>>   intensity.  CT on the other hand are usually
> >>>>   in Hounsfield units. That should result in
> >>>>   similar tissues having similar intensities in
> >>>>   both images.  I would suggest you to skip the
> >>>>   intensity correction between the two CT images
> >>>>   unless you are using images that are not calibrated
> >>>>   in Hounsfield units.
> >>>>
> >>>>
> >>>>The memory usage of 1.4Gb seems excesive, but in practice
> >>>>it depends of how many things you put together in the pipeline.
> >>>>Note that the deformation field for that image size will have
> >>>>an image of Vectors with double or float component type, that
> >>>>alone will take about 230Mb...
> >>>>
> >>>>
> >>>>  Please let us now more details of what you are doing.
> >>>>
> >>>>
> >>>>    Regards,
> >>>>
> >>>>
> >>>>      Luis
> >>>>
> >>>>
> >>>>---------------------------
> >>>>Vincent.Luboz at imag.fr wrote:
> >>>>
> >>>>
> >>>>
> >>>>>Hi itk users
> >>>>>
> >>>>>I'm using the itkHistogramMatchingImageFilter combined with the 
> >>>>>itkDemonsRegistrationFilter to match 2 sets of 3D CT scans. The first
> one
> >>>>
> >>>>is 
> >>>>
> >>>>
> >>>>>an object and the second one is the same object but slightly deformed
> (it
> >>>>
> >>>>is 
> >>>>
> >>>>
> >>>>>an elastic deformation induced by a load on the object).
> >>>>>I used the example given in the itkDemonsRegistrationFilterTest file to
> >>>>
> >>>>used 
> >>>>
> >>>>
> >>>>>this matching algorithm and my program is a copy of it (except the
> >>
> >>variable
> >>
> >>>>>values).
> >>>>>The transformation resulting from the matching seems fine but it takes a
> 
> >>>>>really long time to compute. For example it took 24 hours for matching
> my
> >>
> >>2
> >>
> >>>>>data sets (both of them have a size of 20Mo and 512x512x36 in pixel
> size)
> >>>>
> >>>>with 
> >>>>
> >>>>
> >>>>>10000 points for the histogram, only 20 iterations for the demon
> >>
> >>algorithm
> >>
> >>>>and 
> >>>>
> >>>>
> >>>>>a sigma of 5 (to smooth the result since I only asked for 20
> iterations).
> >>>>>Is it normal that it takes that long?
> >>>>>I was thinking that it may be due to a memory leak of the demon
> algorithm
> >>
> >>>>>since when I run my program, it starts by reading the 2 data sets, so
> the
> >>
> >>>>>memory increases by 40 Mo but them it keeps increasing until reaching a
> >>>>
> >>>>memory 
> >>>>
> >>>>
> >>>>>usage of 1.4Go!!
> >>>>>Is it normal? What can I do to avoid that or to get the result faster?
> >>>>>
> >>>>>Thanks in advance for your help,
> >>>>>
> >>>>>Vincent.
> >>>>>
> >>>>>
> >>>>>-------------------------------------------------
> >>>>>envoyé via Webmail/IMAG !
> >>>>>
> >>>>>_______________________________________________
> >>>>>Insight-users mailing list
> >>>>>Insight-users at itk.org
> >>>>>http://www.itk.org/mailman/listinfo/insight-users
> >>>>>
> >>>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>_______________________________________________
> >>>>Insight-users mailing list
> >>>>Insight-users at itk.org
> >>>>http://www.itk.org/mailman/listinfo/insight-users
> >>>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>-------------------------------------------------
> >>>envoyé via Webmail/IMAG !
> >>>
> >>>
> >>>
> >>
> >>
> >>
> >>
> >>_______________________________________________
> >>Insight-users mailing list
> >>Insight-users at itk.org
> >>http://www.itk.org/mailman/listinfo/insight-users
> >>
> > 
> > 
> > 
> > 
> > 
> > -------------------------------------------------
> > envoyé via Webmail/IMAG !
> > 
> > _______________________________________________
> > Insight-users mailing list
> > Insight-users at itk.org
> > http://www.itk.org/mailman/listinfo/insight-users
> > 
> > 
> 
> 
> 
> 
> _______________________________________________
> Insight-users mailing list
> Insight-users at itk.org
> http://www.itk.org/mailman/listinfo/insight-users
> 




-------------------------------------------------
envoyé via Webmail/IMAG !



More information about the Insight-users mailing list