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
625 stars 161 forks source link

FA to MNI registration via T1w composite transform is off by a few mms #448

Closed ajschadler12 closed 1 year ago

ajschadler12 commented 1 year ago

Describe the bug I am trying to perform a DWI (FA) -> MNI registration via a DWI -> T1w -> MNI composite transform. After the composite transform is applied, the registration between the FA and MNI images is off by a few mm.

I was wondering if perhaps some of my parameters were off?

To Reproduce

I can send images if need be.

# Read in T1w, T1w brain mask, FA, MNI, and MNI brainmask
t1w_ants = ants.image_read("T1w_defaced.nii.gz", dimension=3)
t1w_brainmask_ants = ants.image_read("T1w_brainmask.nii.gz", dimension=3)
FA_ants = ants.image_read("FA.nii.gz", dimension=3)
mni_ants = ants.image_read("Images/Registration/DWI_2_T1w/mni/mni_icbm152_t1_tal_nlin_asym_55_ext.nii")
mni_brainmask_ants = ants.image_read("Images/Registration/DWI_2_T1w/mni/mni_icbm152_t1_tal_nlin_asym_55_ext_mask.nii")

# N4 bias field correction on T1w image
t1w_n4_ants = ants.n4_bias_field_correction(t1w_ants, mask=t1w_brainmask_ants)

# Apply brainmask to T1w image and MNI
t1w_brain_n4_ants = t1w_n4_ants * t1w_brainmask_ants
mni_brain_ants = mni_ants * mni_brainmask_ants

# compute transforms
dwi_2_t1w = ants.registration(fixed=t1w_brain_n4_ants, moving=FA_ants, type="Affine")
t1w_2_mni = ants.registration(fixed=mni_brain_ants, moving=t1w_brain_n4_ants, type_of_transform="SyN")

dwi_2_mni_xfms = dwi_2_t1w["fwdtransforms"] + t1w_2_mni["fwdtransforms"]

FA_mni_ants = ants.apply_transforms(fixed=mni_brain_ants, moving=FA_ants, transformlist=dwi_2_mni_xfms)

# Plot results
## FA -> T1w
t1w_n4_ants.plot(overlay=FA_ants, title="Pre reg", slices=range(80, 181, 20), overlay_alpha=0.5)
t1w_n4_ants.plot(overlay=dwi_2_t1w["warpedmovout"], title="Post reg", slices=range(80, 181, 20), overlay_alpha=0.5)

## T1w -> MNI
mni_ants.plot(overlay=t1w_brain_n4_ants, overlay_cmap="hot", title="Pre reg", slices=range(40, 141, 20), overlay_alpha=0.5)
mni_ants.plot(overlay=t1w_2_mni["warpedmovout"], overlay_cmap="hot", title="Post reg", slices=range(40, 141, 20), overlay_alpha=0.5)

## FA -> MNI
mni_brain_ants.plot(overlay=FA_ants, title="Pre reg", slices=range(40, 141, 20), overlay_alpha=0.5)
mni_brain_ants.plot(overlay=FA_mni_ants, title="Post reg", slices=range(40, 141, 20), overlay_alpha=0.5)

Screenshots

FA to T1w using Affine transform FA to T1w

T1w to MNI using SyN transform T1w to MNI

FA to MNI using composite transform FA to MNI

cookpa commented 1 year ago

I think you might need to switch these

dwi_2_mni_xfms = dwi_2_t1w["fwdtransforms"] + t1w_2_mni["fwdtransforms"]

to

dwi_2_mni_xfms = t1w_2_mni["fwdtransforms"] + dwi_2_t1w["fwdtransforms"] 

Some more background on this convention here

https://github.com/ANTsX/ANTs/wiki/Forward-and-inverse-warps-for-warping-images,-pointsets-and-Jacobians#combining-warps