Has anyone tried converting the ITK DeformableRegistration15.cxx example for use with SimpleITK? There are several calls in the DeformableRegistration15.cxx that I can’t seem to map into SimpleITK.
For us to help you, you need to be more specific. What functionality are you missing?
From a brief glance at the DeformableRegistration15.cxx all of the components are available in SimpleITK. This is a standard three step registration (rigid-affine-BSpline). I recommend that you take a look at the registration examples in the SimpleITK Jupyter notebooks repository, the 6* notebooks. These likely cover what you need.
Thanks so much for your response. Here are more details.
I decided to take a step backward and first try to duplicate just the ITK Rigid Registration program. I have attached both the ITK version and my SimpleITK conversion.
Unfortunately, I am not getting the same results from the 2 programs; I am hoping I’m just missing something here.
A few notes:
I’m using C# SimpleITK v2.0.1 for the SimpleITK example
I’m using ITK v5.0.1 for the ITK example
There are some methods that are called in the ITK_RigidRegistrationExample.cxx that I cannot find in SimpleITK (they are marked in the code). For the example output, I ran the code with these lines commented out. Here are the sections:
Looks like ITK is using a fixed region for the registration?
I can’t find any kind of region setting method in SimpleITK.
ITK initializes the metric seed (metric->ReinitializeSeed(76926294)) I can’t find anyway to do this in SimpleITK (maybe it’s not necessary?)
ITK sets the number of SpatialSamples for the metric (metric->SetNumberOfSpatialSamples(10000L)) I can’t find a way to do this in SimpleITK.
I also found one parameter in SimpleITK that I cannot find in ITK, that is the “learning rate” for the RegularStepGradientDescentOptimizer(). For now, I have set the learning rate to be the same as the max step, but maybe that is not correct.
Finally, I have attached the output from running the 2 programs on my data, along with the final transforms. As you can see, they are somewhat close, but certainly not the same.
Since SimpleITK 2.0.1 is based on ITK 5.0.1, I would expect the differences to be much smaller (if any differences at all).
I’m happy to supply the example data as well …
Any help you can give me would be really appreciated.
These look very close, based on eyeballing the final parameter values. Admittedly this is not the correct way to compare two transformations, better to use Target Registration Error. In this case take a random set of points inside your region of interest and compute ||T_0(p_i) - T_1(p_i)||, see this function.
You should be aware that the registration involves a probabilistic component, the random choice of point set, so running the same code without setting the seed will lead to slightly different results. As you did not explicitly set the sampling strategy and percentage if using a random sample you end up using the default values (I don’t remember what they are). I believe being explicit about choices is always better, even when using the default values (I never remember what they are).
Finally, the ITK code seems to be using old strategies (user selected scales for parameters). Since ITK 4.0 the recommended approach is to use the automated scaling methods. Also, your code did not explicitly specify a sampling strategy or percentage if it was random sampling. Plesae see attached modifiedSimpleITK_RigidRegistrationExample.cs (4.9 KB) code (comments starting with “zivy” are where code was modified).
I really recommend that you go through the SimpleITK notebooks and write your code from scratch and not try to translate from the ITK code (which appears to have only been minimally updated in the transition from 3.x to 4.0 - we are now in ITK 5.x).