Reproducibility of image registration


(Stanislau Trukhan) #1


I’ve done the registration of microscopical images with affine transform using conjugate gradient line search. I observe small to a large variation in the results after several complete the same runs. Metric is Mattes Mutual Information (bins=50), sampling strategy - regular. Initialization is based on manual landmarks. Images are in the float16 format.

Questions are:

  1. Where the randomness take place at the optimization procedure?
  2. How to make registration procedure reproducible?

Best regards,

(Bradley Lowekamp) #2

It sounds like you are using the ITKv4 registration frame work. Look for methods in the classes that allow for setting for “Seeds”. For example the itk::ImageRegistrationMethodv4::MetricSamplingReinitializeSeed method. By default the sampling seed is initialized from from wall clock to produce random results.

If you are seeing significant difference in your registration results based on the sampling, your registration in not robust. You many be optimizing to different local minima or not properly converging. Steps to improving robustness include, more samples, using a multi-scale approach, and ensuring you optimizer is using the appropriate scales and parameters.

(Stanislau Trukhan) #3

Thank you! But I’m using “REGULAR” and not “RANDOM” sampling strategy which should not use any random variables. What could be an issue then?

btw My setup also includes sitk, multi-scale approach, scales and learning rate estimator.

Best regards,

(Bradley Lowekamp) #4

(Stanislau Trukhan) #5


Thank you for the link to a code!

Since I’m using sitk I fixed the seed with the following:
registration_method SetMetricSamplingPercentage(1, 42)

But still I got tiny (hundredth of a pixel size) difference in TRE’s.

How can I fix the seed in sitk?

Best regards,

(Bradley Lowekamp) #6

That sounds like a fairly small amount. I would look for additional sources of randomness or light numeric differences. The next things to consider:

  • What metric are you using? Does that introduce any additional randomness/numeric issues?
  • How many threads/workers are you using? Perhaps try 1 via ProcessObject::SetNumberOfThreads() and ProcessObject::SetGlobalDefaultNumberOfThreads.

(Stanislau Trukhan) #7


  • Metric is MattesMutualInformation (bins=50), also I switched image format to float64.
  • I’m using 20 cores. I’ll try also computing on 1 core. Can you please give me a hint of why it could be an issue?

Thanks for your advice!

Best regards,