ANTsX / ANTsPy

A fast medical imaging analysis library in Python with algorithms for registration, segmentation, and more.
https://antspyx.readthedocs.io
Apache License 2.0
608 stars 161 forks source link

What is the correct way to conduct PET-MR coregistration? #528

Closed tctco closed 6 months ago

tctco commented 6 months ago

I don't know where to post this question :( sorry to drop it here

I am attempting to reproduce the Centiloid value calculation for Amyloid-beta deposition as described in this paper: PMC4300247. The paper outlines the following steps for the process:

  1. Manually reorient the subject data to match the Montreal Neurological Institute (MNI) template.
  2. Coregister subject MRI to the MNI template.
  3. Coregister subject PET to the subject MRI.
  4. Apply unified segmentation to the subject MRI.
  5. Apply normalization parameters to transform the subject PET and MRI into MNI space.

The authors used SPM8 for this task, and I have been trying to implement this process using ANTsPy, and my code is as follows:

transform_type = 'Affine'
mr_to_template = ants.registration(fixed=mni152, moving=mr_image, type_of_transform=transform_type)
ants.image_write(mr_to_template['warpedmovout'], './registered_MR.nii')

pet_to_mr = ants.registration(fixed=mr_to_template['warpedmovout'], moving=pet_image, type_of_transform=transform_type)
pet_to_template = ants.apply_transforms(fixed=mni152, moving=pet_image, transformlist=pet_to_mr['fwdtransforms'] + mr_to_template['fwdtransforms'])
ants.image_write(pet_to_template, './registered_PET.nii')

However, I am encountering issues with the PET image registration results, as they do not seem to be correct. Could you provide guidance or suggestions on how to resolve this issue? Specifically, I'm unsure if I'm correctly applying the transformation parameters for the PET images.

Any help or insights would be greatly appreciated.

Here is a detailed version provided with the paper explaining how the Centiloid value is calculated link.

tctco commented 6 months ago

In comparison, the following code produces results that are closer to those of the original author, but there are still non-negligible differences (2~25% difference, should be <5%):

transform_type = 'Affine'
mr_to_template = ants.registration(fixed=mni152, moving=mr_image, type_of_transform=transform_type)
ants.image_write(mr_to_template['warpedmovout'], './registered_MR.nii')

pet_to_template = ants.registration(fixed=mni152, moving=pet_image, type_of_transform=transform_type)
ants.image_write(pet_to_template['warpedmovout'], './registered_PET.nii')
ntustison commented 6 months ago

Try

pet_to_template = ants.apply_transforms(fixed=mni152, moving=pet_image, transformlist=mr_to_template['fwdtransforms'] + pet_to_mr['fwdtransforms'])
tctco commented 6 months ago

@ntustison hi, thanks for your reply!

I've already tried this (I think it's similar to concatenateRegistrations) and it achieved better results. But the differences are still quite large (worse than direct registration to the mni template).

I wonder if it's because I didn't conduct manual reorientation for antspy. I tried to reproduce the paper's results with SPM12 and the results look okay.

cookpa commented 6 months ago

Sounds like the PET to subject MRI is the issue.

If you load the PET and MRI into ITK-SNAP, are they already closely aligned? If so, the initial center-of-mass alignment in registration can make the solution much worse.

In the ANTs CLI, you can disable the center-of-mass alignment between the modalities by omitting the -r argument. @ntustison is there a way to do this in ANTsPy?

tctco commented 6 months ago

@cookpa thanks for your reply!

I just checked the pet and MRI image, and they are not closely aligned :( I think that's the reason why antspy does not perform well.

BTW, is there a handy way to do manual reorientation elegantly?

image

cookpa commented 6 months ago

ITK-SNAP can do it interactively, and you can save an itk transform that you can use to initialize ants registration

ntustison commented 6 months ago

@cookpa I think all the transform types use an initial center of mass alignment.

Perhaps the easiest thing would be to upload the data and let us see for ourselves.

tctco commented 6 months ago

I've noticed that there are substantial differences in the registration results between ANTsPy and SPM12, even after manually initializing. Below are two reproducible examples derived from the paper I mentioned earlier.

exp.zip

protocol for spm12 co-registration: display (manual re-orientation) => Coregister (Estimate) => Segment => Normalise (Write)

ntustison commented 6 months ago

A couple things:

transform_type = 'Affine'
mr_to_template = ants.registration(fixed=mni152, moving=mr_image, type_of_transform=transform_type)
ants.image_write(mr_to_template['warpedmovout'], './registered_MR.nii')

# This line is wrong.
# pet_to_mr = ants.registration(fixed=mr_to_template['warpedmovout'], moving=pet_image, type_of_transform=transform_type)
# It should be the following:
pet_to_mr = ants.registration(fixed=mr, moving=pet_image, type_of_transform=transform_type)

pet_to_template = ants.apply_transforms(fixed=mni152, moving=pet_image, transformlist=pet_to_mr['fwdtransforms'] + mr_to_template['fwdtransforms'])
ants.image_write(pet_to_template, './registered_PET.nii')