Extracting Exact Metric Value in SimpleITK Python

Hi there,

I am using Elastix in command line to register images using Mattes mutual information metric, and at the end of the registration process, I am recording the exact metric value between the fixed and moving image, a functionality introduced in Elastix 4.9.0. I am attempting to compute the same value with simpleITK in python, and I am not able to reproduce the result that I am getting through elastix. I would appreciate any help on the topic.

Here is my python code and attached is the transform parameter file used in Elastix:

import simpleitk as sitk
pixelType = sitk.sitkFloat64
fixedImage = sitk.ReadImage(’/path/fixed_image.nii’, pixelType)
movingImage = sitk.ReadImage(’/path/moving_image.nii’, pixelType)
Reg = sitk.ImageRegistrationMethod()
Reg.SetOptimizerAsGradientDescentLineSearch(learningRate=1.0,numberOfIterations=1,convergenceMinimumValue=1e-5,convergenceWindowSize=5)
Reg.SetMetricSamplingPercentage(100.0)
Reg.SetInitialTransform(sitk.Transform(2,sitk.sitkIdentity))
Reg.SetMetricAsMattesMutualInformation(numberOfHistogramBins = 32)

Reg.MetricEvaluate(fixedImage,movingImage)

Affine_Double.txt (1.8 KB)

Josh

1 Like

NumberOfSpatialSamples 8000 is a far cry from 100% sampling. There are a lot of other parameters in that file, and you are explicitly setting only a subset. And how is the metric value different?

@Niels_Dekker might have more advice.

1 Like

Thank you for the quick response. The exact metric value recorded in the resulting elastix.log is -0.595666 between the fused moving image and fixed image, and the computed value is -0.59268 in python. Those are close, but not quite the same, and I am afraid to move forward without being able to recapitulate the elastix results. 8000 spatial samples is certainly different than 100% sampling, but I was under the impression that computing the exact metric in elastix was performed by sampling all locations, which is why I chose 100% with simpleITK.

Thanks for the help!

1 Like

Hi @jhess,

Some additional things to be aware of:

  1. Setting the random sampling to 100% doesn’t sample all voxels. This is just a way to specify the number of samples (repeated samples will occur).
  2. The random sampling in ITK does not take the actual voxel center, there is a jitter factor inside each voxel, so each time the sample value from the same voxel will be slightly different.
  3. To use the actual voxel values for 100% of the voxels don’t sample
Reg.SetMetricSamplingStrategy(Reg.NONE)
1 Like

Hi @zivy and @dzenanz,

Using the advice given (setting Reg.SetMetricSamplingStrategy(Reg.NONE)), I am still receiving a metric value of -0.59268. Happy to hear any other suggestions on how to reproduce the elastix exact metric.

Thanks again.

Josh

Perhaps there is Gaussian smoothing going on in Elastix?

1 Like

Hi @blowekamp,

I think you may be correct. In elastix the default smoothing schedule for the multi-resolution registration approach was used, and it seems that the default sigma value for the final resolution is 1. It would and need to be 0 for a fair comparison to the simpleITK implementation.

Josh