nipy / nibabel

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

Loss of Data Precision Issue When Saving Nifti1Image #1268

Closed buer19970329 closed 10 months ago

buer19970329 commented 11 months ago

I have noticed that when using the nibabel library to save a 4D matrix data using Nifti1Image, there is a loss of data precision. Specifically, I execute the following code:

nii = nib.Nifti1Image(res4d, header=img.header, affine=img.affine) nii.to_filename('test.nii.gz')

Where res4d is a 4D matrix containing floating-point numbers. After saving it as 'test.nii.gz', I expect the data to remain unchanged. For example: res4d[10, 10, 10, 0] = 0.443210 nii.get_fdata()[10, 10, 10, 0] = 0.443210

Expected Behavior: I expect the saved data 'test.nii.gz' to maintain the original precision, matching the values in res4d.

Actual Behavior: However, upon loading 'test.nii.gz' and retrieving the data with nib.load('test.nii.gz').get_fdata(), there is a loss of precision, i.e., nib.load('test.nii.gz').get_fdata() = 0.440395 When I checked the image in fsleyes, the volex location of 10, 10, 10, 0 is 0.440395 too.

I have confirmed that this issue replicates consistently in my environment and is not sporadic. I am willing to provide more information or test code if needed. If anyone can provide assistance, I would greatly appreciate it. Thanks in advance.

Python Version: 3.9.12 nibabel Version: 5.1.0 Operating System: macOS

buer19970329 commented 11 months ago

@matthew-brett @effigies

effigies commented 10 months ago

You will need to set the precision you want on the file that you intend to save.

In recent versions, you can add a dtype to the .to_filename() method:

nii.to_filename('test.nii.gz', dtype='float32')

The approach that will work across more versions would be:

nii.set_data_dtype('float32')
nii.to_filename('test.nii.gz')