@effigies - is there a nibabel guide on changing datatype of a NiftiImage
object and saving to a NifTI file with that datatype?
In terms of the on-disk dtype
or the intent code?
both on_disk and intent. in the example below, something was likely not set appropriately, such that even though the header dtype
says uint8
, the data array (or the values) does not reflect that. should nibabel have raised an exception when doing the original save (i.e. a mismatch between intent and data dype)?
In [2]: import nibabel as nb
In [3]: img = nb.load('output_means.nii.gz')
In [7]: img.header.get_data_dtype()
Out[7]: dtype('uint8')
In [4]: import numpy as np
In [5]: np.unique(img.get_fdata())
Out[5]:
array([ 0. , 0.96078433, 1.92156866, 3.07450986, 4.03529419,
...
44.96470669, 45.92549102, 47.07843222, 48.03921655, 49.00000088])
In [6]: np.unique(img.get_data())
Out[6]:
array([ 0. , 0.96078433, 1.92156866, 3.07450986, 4.03529419,
...
44.96470669, 45.92549102, 47.07843222, 48.03921655, 49.00000088])
In [8]: np.unique(img.dataobj)
Out[8]:
array([ 0. , 0.96078433, 1.92156866, 3.07450986, 4.03529419,
...
44.96470669, 45.92549102, 47.07843222, 48.03921655, 49.00000088])
possible rewrite solution:
data = np.round(means.get_fdata()).astype(np.uint8)
means = nb.Nifti1Image(data, header=means.header, affine=means.affine)
nib.save(means, outfile_means)
In that example, what is happening is that your data is floats, so nibabel is doing its best to set scl_slope
and scl_inter
to capture your data with 8 bits of precision.
So if you want to coerce the interpreted dtype as well as the on-disk dtype, then you need to do something like what you suggest. I would play with it, but you might need to set_data_dtype
, as well, since you’re copying the header from an image that presumably had a different on-disk dtype:
data = np.round(means.get_fdata()).astype(np.uint8)
means = nb.Nifti1Image(data, header=means.header, affine=means.affine)
means.header.set_data_dtype(np.uint8)
nib.save(means, outfile_means)
Annoyingly, intent
here doesn’t mean “intended type interpretation”, but more general notions of intent such as “label” or “z score”.