loli / medpy

Medical image processing in Python
http://loli.github.io/medpy/
GNU General Public License v3.0
559 stars 136 forks source link

resample does not modify nifti header #86

Closed AndrewDDavis closed 5 years ago

AndrewDDavis commented 5 years ago

Using the medpy.filter.resample function zooms image data as expected, but does not appear to modify the affine in the header. When writing out the nifti using nibabel's to_filename and using the new header, the nifti retains the old pixel spacing.

Edit I can see that the header is modified (along with the header that was fed in to resample!), in that the zooms property has the new resolution, and the qform is modified. However, the sform does not get changed, nor does its code, so the old sform gets priority when writing the nifti out if the code was 1 on input.

loli commented 5 years ago

Thank you for pointing this out.

It is a know issue from long, long ago. Actually the first I ever wrote (https://github.com/loli/medpy/issues/1). I never got around to fully implement the setting and reading of voxel spacing for NIfTI. It's just complicated (see under 'Orientation information' in https://brainder.org/2012/09/23/the-nifti-file-format/) and I found that many NIfTI readers and writers anyway wrongly interpret the sform and qform codes anyway, which leads to additional confusion.

If you can see a easy way to incorporate the new voxel spacing in the _srow* values, I would be happy for the contribution (https://github.com/loli/medpy/blob/master/medpy/io/header.py).

For mid term, I plan to switch all image loading and reading to the simpleitk package, and hence outsourcing the problem ;)

Regarding the double modification: Yes, the header is the original image object returned by the reader (here: nibabel). But it lives independently of the image data. Hence any modification is reflected throughout all copies of the header (except deep copies).

loli commented 5 years ago

Possibly resolve with the switch to SimpleITK (commit e435271).