nipy / nibabel

Python package to access a cacophony of neuro-imaging file formats
http://nipy.org/nibabel/
Other
649 stars 258 forks source link

Help applying affine transformation #906

Closed sravan953 closed 4 years ago

sravan953 commented 4 years ago

Hello,

I am unable to figure out how to apply an affine matrix (get_affine() to the numpy array(get_data()). I have tried:

nb.affines.apply_affine(pts=vol.get_data(), aff=vol.get_affine())

... where vol is of shape (256, 256, 287).

effigies commented 4 years ago

What are you trying to do?

sravan953 commented 4 years ago

I want the numpy data to be transformed so that when I view it using matplotlib it is of the right orientation. Loading the same volume using SimpleITK and calling GetArrayFromImage() I get a different volume on display.

effigies commented 4 years ago

First, I would suggest having a look at nilearn's plotting tools, rather than writing your own methods for plotting with matplotlib. You can also use img.orthoview() on the SpatialImage object directly, and the plots will respect the orientation of the image.


For actually manipulating the image:

apply_affine does not operate on a data matrix, but a set of coordinates. In the case of NIfTI images, it translates coordinates in voxel space (indices) to world space (mm right, anterior and superior of some origin). The data array is already "in" the space described by the affine, so to get it in some other space, you need some notion of what your target space is.

If your target is RAS space, such that increasing the index along the first dimension finds locations further right from the origin (and similarly anterior and superior for the second and third dimensions), you can use nib.as_closest_canonical(img). This will not resample the data, so if the head is not plumb and level then the "world" coordinates may not exactly align with the subject's coordinates.

If you need the data resampled so that it has a specific orientation, then you can check out the nib.processing.resample_from_to. Similarly, nilearn has some resampling functions.


Finally, one thing to keep an eye out for when using ITK is that it does not respect the NIfTI standard, and ignores the sform matrix when set. If the qform and sform don't match, then ITK is going to interpret the image differently from pretty much all other neuroimaging tools.

sravan953 commented 4 years ago

Thanks for all this information, it is very helpful!

jond01 commented 4 years ago

Finally, one thing to keep an eye out for when using ITK is that it does not respect the NIfTI standard, and ignores the sform matrix when set. If the qform and sform don't match, then ITK is going to interpret the image differently from pretty much all other neuroimaging tools.

Just updating - looks like it is going to be solved: InsightSoftwareConsortium/ITK#1868

hjmjohnson commented 4 years ago

@jond01 Actually ITK was rigidly adhering to the original NIFTI standard as discussed with the NIFTI developers at the time.

Given that the issues with precision when adhering to the original standards, many tools adopted the use of the sform for it's potentially greater precision. ITK is late to making the change to the general community use over the original developers' intentions.

I hope that this change to ITK makes it more consistent with the community implementations.

jond01 commented 4 years ago

I see @hjmjohnson, thanks for this interesting remark and the effort to keep the ecosystem consistent