Marker registration does not follow image registration

Hello,

I registered an MRI scan to a CT scan as follows:

tx = sitk.AffineTransform(fixed_image.GetDimension())
init_pos = sitk.CenteredTransformInitializerFilter.MOMENTS
initial_transform = sitk.CenteredTransformInitializer(
        fixed_image, moving_image, tx, init_pos
    )
 registration_method = sitk.ImageRegistrationMethod()
...
hyperparameters setting
...
registration_method.SetInitialTransform(initial_transform, inPlace=True)
transform = registration_method.Execute(
        sitk.Cast(fixed_image, sitk.sitkFloat32),
        sitk.Cast(moving_image, sitk.sitkFloat32),
    )

Then I use the TransformPoint method to transform some markers that I had put on the original (non registered) MRI scan with 3D Slicer.
On the below screenshot you can see the tip of the nose is marked on the original image while the marker seems to have moved higher to another place after the transform, as if the transform transformed the MRI scan and the marker differently.

Would you have any idea what could cause this small discrepancy in position?

I looked into RAS and LPS coordinate system and for some reason, the solution that gives me the registered marker the closest to the target position (from the CT scan) involves multiplying the control points coordinate by [-1, -1, -1].

PS: Registration works well to register the MRI on the CT scan.

Thank you for your help.

Hello @sebquet,

The transformation obtained from registration maps points from the fixed image coordinate system to the moving one. This transformation is then often used to resample the moving image. If the points were marked on the moving image and we want to transform them to the fixed image coordinate system we need to use the inverse transformation (tx.GetInverse()) to map them.

I suspect this is the issue you are encountering (guessing here because I don’t know if you used the MRI as the fixed_image or moving_image).

2 Likes

Hello @zivy,

Thank you so much for your prompt reply. That was indeed the problem. I was not able to use GetInverse() function because my transform is a composite transform involving a BSpline transform but transforming the CT markers to MRI coor sys did the job.

Thank you!

1 Like

Hello @sebquet,

You’re welcome. Just in case it is of interest, see this Jupyter notebook for information on how to invert bounded and composite transforms.

1 Like

Thank you for the link, I was able to get I was able to make invert_composite_transform function work. However I am unsure what parameter to use for the grid_spacing (because I am using BSpline transform). Should it be the BSpline transform grid spacing, the TransformDomainMeshSize or should it be an hyper parameter of the newly created DisplacementFieldTransform? I tried a couple of thing and errors between transformed CT markers and mri and errors between inversed transformed MRI markers and CT markers is not exactly the same, even when I don’t use the second transform of my composite and only use the affine transformation. I guess it is because of the approximations introduced when reversing the transform.

Thank you!