[Neuroimaging] Getting scaling and offset from nifti header in nibabel

Matthew Brett matthew.brett at gmail.com
Thu Dec 17 12:57:09 EST 2015


Hi,

On Thu, Dec 17, 2015 at 4:42 PM, Samuel St-Jean <stjeansam at gmail.com> wrote:
> Hello,
>
> I'd like to get the scaling and offset value to compare data from two
> volumes acquired in the same scan. Since the floating points values are
> wildly different, we need ot put them on the same scaling of intensity. This
> can be done from the dicom files directly, but it a painful and error prone
> process and difficult to automate.
>
> Turns out mrconvert from mrtrix does not take into account scaling when your
> data is in floating point (by design, so even the options to correct this
> scaling are disabled), but still stores the correct values. When opening the
> nifti files converted from nibabel the headers just show nan values, while
> mrtrix can parse them correctly. Here is the header from mrinfo as an
> example.
>
> ************************************************
> Image:               "noise.nii.gz"
> ************************************************
>   Format:            NIfTI-1.1
>   Dimensions:        128 x 128 x 78
>   Voxel size:        1.79665 x 1.79665 x 1.8
>   Dimension labels:  0. left->right (mm)
>                      1. posterior->anterior (mm)
>                      2. inferior->superior (mm)
>   Data type:         signed 16 bit integer (little endian)
>   Data layout:       [ -0 -1 +2 ]
>   Data scaling:      offset = 0, multiplier = 166.825
>   Comments:          SAMUEL 9JUIL (SAMU
>                      MRtrix version: 0.3.12-1050-g62ace960
>   Transform:               0.9993    -0.00287    -0.03691 -115.6
>                        -5.649e-11       0.997    -0.07752 -108.4
>                           0.03702     0.07746      0.9963 -60.36
>                                 0           0           0 1
>
> Same header through nibabel
>
> <class 'nibabel.nifti1.Nifti1Header'> object, endian='<'
> sizeof_hdr      : 348
> data_type       :
> db_name         : SAMUEL 9JUIL (SAMU
> extents         : 16384
> session_error   : 0
> regular         : r
> dim_info        : 0
> dim             : [  3 128 128  78   1   1   1   1]
> intent_p1       : 0.0
> intent_p2       : 0.0
> intent_p3       : 0.0
> intent_code     : none
> datatype        : int16
> bitpix          : 16
> slice_start     : 0
> pixdim          : [ 1.          1.79665172  1.79665172  1.79999924 0.
> 0.          0.
>   0.        ]
> vox_offset      : 0.0
> scl_slope       : nan
> scl_inter       : nan
> slice_end       : 0
> slice_code      : unknown
> xyzt_units      : 10
> cal_max         : 0.0
> cal_min         : 0.0
> slice_duration  : 0.0
> toffset         : 0.0
> glmax           : 0
> glmin           : 0
> descrip         : MRtrix version: 0.3.12-1050-g62ace960
> aux_file        :
> qform_code      : scanner
> sform_code      : scanner
> quatern_b       : -0.0185005571693
> quatern_c       : -0.038780156523
> quatern_d       : 0.999076247215
> qoffset_x       : 111.719642639
> qoffset_y       : 119.12978363
> qoffset_z       : -34.2374076843
> srow_x          : [ -1.79541993e+00   5.15606394e-03 -6.64402023e-02
> 1.11719643e+02]
> srow_y          : [  1.01492648e-10  -1.79124594e+00 -1.39527366e-01
> 1.19129784e+02]
> srow_z          : [ -0.06651677  -0.13917242   1.79335308 -34.23740768]
> intent_name     :
> magic           : n+1
>
>
> Those would probably be scl_slope and scl_inter, but the values just got
> lost somewhere apparently. The same behavior is seen from the example in
> nifti header here :
> http://nipy.org/nibabel/nifti_images.html#the-nifti-header
>
> So the questions
>
> 1. Did something went wrong, or do both program just use different field? If
> so, does nibabel show all fields in the header or only known ones?
> 2. Is the field scl_slope/scl_inter even related to the dicom scaling (and
> offset/multiplier from mrtrix, though this one goes in their mailing list if
> nobody knows)? Philips call those SS and SI values, and you simply need to
> fix the offset + scaling with these numbers to get sane intensities out of
> your scanner, but they are a huge pain to get out.

No - nothing wrong.  The nibabel reader resets the scale and slope to
NaN by default when it reads in the image.

If you want to read the original scale and slope, you can get them
from the image array proxy object, as in:

img.dataobj.slope
img.dataobj.inter

Is that what you needed?

Matthew


More information about the Neuroimaging mailing list