SuperElastix / SimpleElastix

Multi-lingual medical image registration library
http://simpleelastix.github.io
Apache License 2.0
514 stars 148 forks source link

invert b-spline transformation #330

Open clemsgrs opened 5 years ago

clemsgrs commented 5 years ago

Hi, I have registered some images with the following parameter map vector :

elsx = sitk.ElastixImageFilter()
pmap = sitk.GetDefaultParameterMap('bspline')
elsx.SetParameterMap(pmap)

I managed to invert an affine transformation manually (by reading the transform parameter file and inverting the matrix given by elsx.GetTransformParameterMap()[0]["Transform Parameters"]).

Yet, I can't manage to invert a b-spline transform. Any idea how I could do it ? thx

clemsgrs commented 5 years ago

I have tried out two methods to get the inverse but neither of them lead to decent results :

reminder : Image A is fixed. I want to register image B on image A with a b-spline transform and inverse this b-spline to apply it to image A's segmentation mask.

1) set image A as fixed image 2) set image B as moving image 3) register image B on image A with a b-spline : this gives image C 4) save the parameters of this transform with sitk.WriteParameterFile(elsx.GetTransformParameterMap()[0], bspline_save_path)

So as to inverse this b-spline I do the following :

5) set image B as the fixed image 6) set image C as the moving image 7) register image C on image B with another b-spline transform : this gives image D 8) save the parameters of this transform with sitk.WriteParameterFile(elsx.GetTransformParameterMap()[0], inverse_save_path)

when comparing image D and image B, they do not look similar enough to consider that the last b-spline transform is the inverse of the first one...

I tried to do it manually as it is (very quickly) explained in the elastix manual (section 6.1.6) :

1) set image B as fixed image and as moving image 2) create a new b-spline parameter map p = sitk.GetDefaultParameterMap('bspline') which will later contain the inverse of the b-spline function used to register image B on image A 3) set the original b-spline that we aim to inverse as the initial transform with p['InitialTransformParametersFileName'] = [bspline_save_path] 4) set p['Metric'] = ['DisplacementMagnitudePenalty'] and p['HowToCombineTransforms'] = ['Compose'] 5) selx.Execute() 6) get the result parameter map with inverse_bspline = selx.GetTransformParameterMap()[0] 7) set the initial transform in this last parameter file to "NoInitialTransform" : inverse_bspline["InitialTransformParametersFileName"] = ["NoInitialTransform"] 8) apply this transform to image C : it gives image D

here again, images B and D are too different to consider we found the inverse...