InsightSoftwareConsortium / ITKElastix

An ITK Python interface to elastix, a toolbox for rigid and nonrigid registration of images
Apache License 2.0
190 stars 23 forks source link

Inverse transform #285

Open omaghsoudi opened 2 months ago

omaghsoudi commented 2 months ago

Hi Is there any function to inverse the registration? For example, getting the original moving coordinates associated with the points in the fixed image, after affine and deform transforms used (the transform parameter file is available as the registration was complete) .

Thank you!

dzenanz commented 2 months ago

Deformable transforms are not necessarily invertible. I am unaware of a convenient function to invert them. @N-Dekker or @mstaring might know of a way which is not too inconvenient?

mstaring commented 2 months ago

This notebook should be helpful: https://github.com/InsightSoftwareConsortium/ITKElastix/blob/main/examples/ITK_Example11_Transformix_DeformationField.ipynb

omaghsoudi commented 2 months ago

Thank you. I think that resolved my problem.

omaghsoudi commented 2 months ago

You suggestion worked for the bspline (deform registration), but it does not work for rigid transform alone.

    inverse_image, inverse_transform_parameters = itk.elastix_registration_method(
  File "/opt/conda/envs/elastix3/lib/python3.10/site-packages/itk/support/helpers.py", line 176, in image_filter_wrapper
    return image_filter(*args, **kwargs)
  File "/opt/conda/envs/elastix3/lib/python3.10/site-packages/itk/itkElastixRegistrationMethodPython.py", line 1810, in elastix_registration_method
    return instance.__internal_call__()
  File "/opt/conda/envs/elastix3/lib/python3.10/site-packages/itk/ITKCommonBasePython.py", line 1437, in __internal_call__
    self.UpdateLargestPossibleRegion()
RuntimeError: /work/_skbuild/linux-x86_64-3.10/cmake-build/_deps/elx-src/Core/Main/itkElastixRegistrationMethod.hxx:380:
ITK ERROR: ElastixRegistrationMethod(0x558281b94700): Internal elastix error: See elastix log (use LogToConsoleOn() or LogToFileOn()).

Everything works for the deform registration with the same code. This is my initial_transform_parameter_file_name file:

(CenterOfRotationPoint -1.0005186796188354 -147.00051867961884 -82.44999694824219)
(ComputeZYX "false")
(Direction 1 0 0 0 1 0 0 0 1)
(FixedImageDimension 3)
(FixedInternalImagePixelType "float")
(HowToCombineTransforms "Compose")
(Index 0 0 0)
(InitialTransformParameterFileName "NoInitialTransform")
(MovingImageDimension 3)
(MovingInternalImagePixelType "float")
(NumberOfParameters 6)
(Origin -225.56100463867188 -371.5610046386719 -174.6999969482422)
(Size 512 512 124)
(Spacing 0.8789060115814209 0.8789060115814209 1.5)
(Transform "EulerTransform")
(TransformParameters 0.1394409716849276 -0.1449852943495937 0.022096482481481324 -17.114835288096504 -33.66983366205986 44.09175161002788)
(UseDirectionCosines "true")

// ResampleInterpolator specific
(ResampleInterpolator "FinalLinearInterpolator")

// Resampler specific
(CompressResultImage "false")
(DefaultPixelValue -1024)
(Resampler "DefaultResampler")
(ResultImageFormat "nii.gz")
(ResultImagePixelType "float")
omaghsoudi commented 2 months ago

And this is detailed log:


ELASTIX version: 5.1.0
Command line options from ElastixBase:
-out      ***
-threads  7
Command line options from TransformBase:
-t0       ***rigid_registration/TransformParameters.0.txt

Reading images...
Reading images took 0 ms.

Reading the elastix parameters from file ...

Transform parameters are initialized as: [0, 0, 0, 0, 0, 0]
Scales are estimated automatically.
Scales for transform parameters are: [20875.069329302674, 20870.280463565956, 32229.701232521853, 1, 1, 1]
Initialization of all components (before registration) took: 42 ms.
Preparation of the image pyramids took: 1214 ms.

Resolution: 0
WARNING: The parameter "UseMultiThreadingForMetrics", requested at entry number 0, does not exist at all.
  The default value "true" is used instead.
Setting the fixed masks took: 0 ms.
Setting the moving masks took: 0 ms.
WARNING: The parameter "FixedImageBSplineInterpolationOrder", requested at entry number 0, does not exist at all.
  The default value "1" is used instead.
WARNING: The parameter "NumberOfFixedHistogramBins", requested at entry number 0, does not exist at all.
  The default value "32" is used instead.
WARNING: The parameter "NumberOfMovingHistogramBins", requested at entry number 0, does not exist at all.
  The default value "32" is used instead.
WARNING: The parameter "FixedLimitRangeRatio", requested at entry number 0, does not exist at all.
  The default value "0.01" is used instead.
WARNING: The parameter "MovingLimitRangeRatio", requested at entry number 0, does not exist at all.
  The default value "0.01" is used instead.
WARNING: The parameter "SP_A", requested at entry number 0, does not exist at all.
  The default value "20" is used instead.
WARNING: The parameter "SigmoidInitialTime", requested at entry number 0, does not exist at all.
  The default value "0" is used instead.
WARNING: The parameter "MaxBandCovSize", requested at entry number 0, does not exist at all.
  The default value "192" is used instead.
WARNING: The parameter "NumberOfBandStructureSamples", requested at entry number 0, does not exist at all.
  The default value "10" is used instead.
WARNING: The parameter "UseConstantStep", requested at entry number 0, does not exist at all.
  The default value "false" is used instead.
WARNING: The parameter "MaximumStepLengthRatio", requested at entry number 0, does not exist at all.
  The default value "1" is used instead.
WARNING: The parameter "MaximumStepLength", requested at entry number 0, does not exist at all.
  The default value "0.859375" is used instead.
WARNING: The parameter "NumberOfGradientMeasurements", requested at entry number 0, does not exist at all.
  The default value "0" is used instead.
WARNING: The parameter "NumberOfJacobianMeasurements", requested at entry number 0, does not exist at all.
  The default value "1000" is used instead.
WARNING: The parameter "NumberOfSamplesForExactGradient", requested at entry number 0, does not exist at all.
  The default value "100000" is used instead.
WARNING: The parameter "SigmoidScaleFactor", requested at entry number 0, does not exist at all.
  The default value "0.1" is used instead.
Elastix initialization of all components (for this resolution) took: 0 ms.
Initialization of NormalizedMutualInformation metric took: 2 ms.
Starting automatic parameter estimation for AdaptiveStochasticGradientDescent ...
WARNING: The parameter "ASGDParameterEstimationMethod", requested at entry number 0, does not exist at all.
  The default value "Original" is used instead.
  Computing JacobianTerms ...
  Computing the Jacobian terms took 0.001010s
  NumberOfGradientMeasurements to estimate sigma_i: 6
  Sampling gradients ...
Time spent in resolution 0 (ITK initialization and iterating): 0.0101
Stopping condition: Error in metric.
Settings of AdaptiveStochasticGradientDescent in resolution 0:
( SP_a 1.000000 )
( SP_A 20.000000 )
( SP_alpha 0.602000 )
( SigmoidMax 1.000000 )
( SigmoidMin -0.800000 )
( SigmoidScale 0.000000 )

itk::ExceptionObject (0x55a6571e72e0)
Location: "ElastixTemplate - Run()" 
File: /work/_skbuild/linux-x86_64-3.10/cmake-build/_deps/elx-src/Common/CostFunctions/itkAdvancedImageToImageMetric.hxx
Line: 901
Description: ITK ERROR: NormalizedMutualInformationMetric(0x55a6571e1b20): Too many samples map outside moving image buffer: 0 / 73728

Error occurred during actual registration.
omaghsoudi commented 2 months ago

Any updates on this?

wangtongy commented 2 months ago

This notebook should be helpful: https://github.com/InsightSoftwareConsortium/ITKElastix/blob/main/examples/ITK_Example11_Transformix_DeformationField.ipynb

According to the manual, I think we also need to set the metric to [DisplacementMagnitudePenalty ] right? This step did not show in the notebook.

omaghsoudi commented 2 months ago

I do not see either of metric or DisplacementMagnitudePenalty in my configs or parameters files generated by the registration transforms.

wangtongy commented 2 months ago

I do not see either of metric or DisplacementMagnitudePenalty in my configs or parameters files generated by the registration transforms.

What I meant is to change the Metric in the parameter files that are used to do registration. Based on my understanding, if you used "AdvancedMattesMutualInformation" as Metric to run elastix registration, you can inverse the transform by 1) change AdcancedMattesMutualInformation to DisplacementMagnitudePenalty, 2) Use the transformation file that generated by "real" registration as initial transform 3) use the original fixed image set both as fixed and moving, 4) redo registration. The output transform files should be the inverse transform.

"The DisplacementMagnitudePenalty is a cost function that penalises ||Tµ(x) − x||2. You can use this to invert transforms, by setting the transform to be inverted as an initial transform (using -t0), setting (HowToCombineTransforms "Compose"), and running elastix with this metric, using the original fixed image set both as fixed (-f) and moving (-m) image."

Can anyone correct me if I make it wrong?

thewtex commented 1 month ago

You suggestion worked for the bspline (deform registration), but it does not work for rigid transform alone.

For the rigid transform, calling GetInverseTransform() on the ITK Transform will return the inverse. This could be a good addition to this notebook: https://github.com/InsightSoftwareConsortium/ITKElastix/blob/main/examples/ITK_Example22_ConvertToITKTransform.ipynb

change the Metric in the parameter files that are used to do registration

Obtaining the inverse of the transformation is generally independent of the similarity metric used in registration.

omaghsoudi commented 3 weeks ago

Can you please add an example of this suggestion in a notebook?