InsightSoftwareConsortium / ITKElastix

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

Transfer PointSet from Moving Image to Fixed Image #135

Open devraj89 opened 3 years ago

devraj89 commented 3 years ago

Hi @thewtex @blezek @bradking @cpatrick @arnaudgelas @dzenanz @N-Dekker

In the example, ITK_Example09_PointSetAndMaskTransformation.ipynb, it is mentioned ...

When transforming a point set, this happens the other way around: from the fixed image domain to the moving image domain. This is useful for example when you want to know where a point maps to. Point sets therefor need not be transformed with the backwards mapping protocol, but can instead be transformed with regular forward transformation (fixed -> moving). Transforming point sets can be used to get the regions of interest (ROI) in the moving image, based on ROI of the fixed image.

Can we transfer points in moving image to the fixed image domain ? How to do the backwards mapping in this case ? What change should be made here ?

# Procedural interface of transformix filter
result_point_set = itk.transformix_pointset(
    moving_image, result_transform_parameters,
    fixed_point_set_file_name='data/CT_3D_lung_fixed_point_set_corrected.txt',
    output_directory = './exampleoutput')

Thanks

dzenanz commented 2 years ago

Can we transfer points in moving image to the fixed image domain ?

Of course, direct application of the transform should give you that.

How to do the backwards mapping in this case ?

Inverting the transform before applying it should be sufficient.

What change should be made here ?

Someone more familiar with elastix and transformix should answer this.

stephahn0916 commented 2 years ago

hi @devraj89

To inverse the transformation, looks at elastix manual 6.1.6. My pseudo code workflow is the following:

# define some variables
fixed = ....
moving = ...
parameter_object = ...         # your parameter object for forward registration
inverse_parameter_object = ... # your parameter object for backward registration. 
                               # Metric must be set to DisplacementMagnitudePenalty. 
                               # HowToCombineTransforms must be set to Compose.
output_directory = ....        # output directory for you forward registration
inverse_output_directory = ... # output directory of your backward registration
point_set_file_path = ...      # path to your moving point set file

# Start a normal elastix transformation
result_image, result_transform_parameters = itk.elastix_registration_method(
                fixed, moving, parameter_object=parameter_object, output_directory=output_directory)

# Use the last transform parameters files as initial transformation
last_transform_parameters_file = sorted(glob(os.path.join(output_directory,"TransformParameters.*.txt")))[-1]

result_inverse_image, result_inverse_transform_parameters = itk.elastix_registration_method(
                fixed, fixed, #  use fixed image for fixed and moving
                parameter_object=inverse_parameter_object, 
                output_directory=inverse_output_directory,
               initial_transform_parameter_file_name=last_transform_parameters_file
            )
# The result_inverse_transform_parameters should be your inverse transformation but it has always as
#  initial transform the result_transform_parameters. It should be set to NoInitialTransform. 

# Set the first transform parameters InitialTransformParametersFileName to NoInitialTransform
result_inverse_transform_parameters.SetParameter(0,"InitialTransformParametersFileName", "NoInitialTransform")

# Use the transformation in transformix
result_point_set = itk.transformix_pointset( moving_image, result_inverse_transform_parameters,
    fixed_point_set_file_name=point_set_file_path,
    output_directory = inverse_output_directory)

If the registration is composed only of Rigid and Affine transformations, I think it should be possible to invert it using itk.EulerTransform and itk.AffineTransform. Did not tested yet but look at this example for inspiration.