to_nibabel() produces wrong transforms
See original GitHub issueWhile using transforms on the MNI152 template I noticed that the output of to_nibabel() was flipped along the vertical plane. While investigating the issue, I noticed, that this is caused by a wrong extraction of the q-form parameters (direction, origin) from ITK.
ants_mni = ants.image_read('./MNI152.nii.gz')
nii_mni = nib.load('./MNI152.nii.gz')
ants_mni = ants_mni.to_nibabel()
print(ants_mni.get_qform())
print(nii_mni.get_qform())
results in:
[[ 2. 0. 0. -90.]
[ 0. -2. 0. 126.]
[ 0. 0. 2. -72.]
[ 0. 0. 0. 1.]]
[[ -2. 0. 0. 90.]
[ 0. 2. 0. -126.]
[ 0. 0. 2. -72.]
[ 0. 0. 0. 1.]]
Using the ITK internal functions for exporting to nifti file format, everything works as expected:
ants_mni = ants.image_read('./MNI152.nii.gz')
ants.image_write(ants_mni, './ANTS_MNI152.nii.gz')
ants_nii = nib.load('./ANTS_MNI152.nii.gz')
nii_mni = nib.load('./MNI152.nii.gz')
print(ants_nii.get_qform())
print(nii_mni.get_qform())
[[ -2. 0. 0. 90.]
[ 0. 2. 0. -126.]
[ 0. 0. 2. -72.]
[ 0. 0. 0. 1.]]
[[ -2. 0. 0. 90.]
[ 0. 2. 0. -126.]
[ 0. 0. 2. -72.]
[ 0. 0. 0. 1.]]
Although this could be used a a quick work around, like in the from_nibabel() implementation, a Nifti/Nibabel class export, should no rely on using hard-drive exports, when all the necessary information could be retrieved while loading the file initially.
Issue Analytics
- State:
- Created 4 years ago
- Comments:26 (15 by maintainers)
Top Results From Across the Web
VTK transform gives wrong orientation value - Stack Overflow
I have a cube to which I am applying transform with centroid coordinates(x,y,z), scale(length, width, height) and the orientation angles in ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
ITK uses LPS coordinates and NIFTI RAS. This is handled in the I/O, when ITK converts qform into a direction cosine matrix or writes a cosine matrix back out as a qform.
https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/IO/NIFTI/src/itkNiftiImageIO.cxx
See methods
SetImageIOOrientationFromNIfTI
andSetNIfTIOrientationFromImageIO
.According to this page
https://nipy.org/nibabel/coordinate_systems.html
NiBabel always wants RAS coordinates so I think it should be safe to apply the same conversion steps in the
to_nibabel
andfrom_nibabel
functions.Some more on this:
https://itk.org/Doxygen/html/classitk_1_1ImageBase.html#a23ebc76de3b60bb1eeabf66cd4dabc48
This is the base ITK class that handles voxel to physical space conversion. It references this page
https://itk.org/Wiki/Proposals:Orientation#Some_notes_on_the_DICOM_convention_and_current_ITK_usage
consider https://github.com/ANTsX/ANTsPy/commit/1e73b82fd23a9c39d80918739991da41f290cd9d