[Neuroimaging] Question about nibabel.processing

Zoltick, Brad (NIH/NIMH) [E] zoltickb at mail.nih.gov
Thu Oct 12 10:33:32 EDT 2017


Hello Chris,


I have used these two functions to convert a 4d nifti dataset to N, 3d volumes.

Perhaps this will help you.  You can easily store the first volume and then resample.

____________________________________________________________

!/usr/bin/env python3

#
# Use nibabel tools to convert a 4D (space+time) single file nifti
# file to a set of single volume pairs of (.img,.hdr) files

import os
import sys
import numpy as np
import nibabel as nib

def nii_4d_to_3d_pair(fname):
    """ convert a nifti1 4D image to N nifti1 3d pair (.img,.hdr) images """
    if not fname.endswith('nii'):
        sys.exit('filename must be a 4D nifti file: {}'.format(fname))

    img4d = nib.load(fname)
    basename = img4d.get_filename()[:-4]
    affine = img4d.affine     # save affine
    header = img4d.header     # save header
    numvols = img4d.shape[3]  # 4th dimension is time (number of volumes)
    data = img4d.get_data()   # 4d numpy array

    for i in range(numvols):
        img3d = nib.Nifti1Pair(data[:,:,:,i], affine, header)
        img3d_name = '{0}_{1:02d}.img'.format(basename, i)
        nib.save(img3d, img3d_name)

def nii_4d_to_3d(fname):
    """ convert a nifti1 4D image to N nifti1 3d single file images """
    if not fname.endswith('nii'):
        sys.exit('filename must be a 4D nifti file: {}'.format(fname))

    img4d = nib.load(fname)
    basename = img4d.get_filename()[:-4]
    affine = img4d.affine     # save affine
    header = img4d.header     # save header
    numvols = img4d.shape[3]  # 4th dimension is time (number of volumes)
    data = img4d.get_data()   # 4d numpy array

    for i in range(numvols):
        img3d = nib.Nifti1Image(data[:,:,:,i], affine, header)
        img3d_name = '{0}_{1:02d}.nii'.format(basename, i)
        nib.save(img3d, img3d_name)

if __name__ == '__main__':
    usage = 'conv_4dto3d.py file.nii'
    if len(sys.argv) < 2:
        sys.exit(usage)
    fname = sys.argv[1]
    nii_4d_to_3d_pair(fname)

__________________________________


Brad J Zoltick
Computer Engineer

NIH/NIMH
Building 10, Room 3C-210
Bethesda, MD 20892-1394

Tel (301)402-3232
Fax (301)480-7795


________________________________
From: Christopher Cox <christopher.cox-2 at manchester.ac.uk>
Sent: Thursday, October 12, 2017 9:15 AM
To: neuroimaging at python.org
Subject: [Neuroimaging] Question about nibabel.processing


Hello,



My first question should really be: how do you review the archive for this mailing list? I imagine this question has been answered, but I do not know where to look.



I am attempting something very simple: I want to resample a volume. The nifti file on disk is 4D, and contains two volumes. Nibabel.processing.resample_to_output() will not work with 4D data. Fortunately for me, I only care about the first volume in this dataset. So I should have no problem.



But... nothing I can think to try works. I apologize it is difficult to read, but I’ve condensed several of my attempts into an interactive python session, and copied all of my work and the errors I am getting as a post script. I tried to color code, but that might not come through.



My first attempt is to try and pass the sliced data object (as in, data = img.get_data()), but that is a memory map as lacks the metadata the function requires. I tried passing the image (as in, img = nib.load(…)), but it cannot be sliced like the data can. I then tried simply loading only a single volume into memory (as in, vol0 = img.datobj[…,0]), but that doesn’t work either (vol0 is a numpy array, and img is still seen as 4D).  I tried updating the shape metadata in img, but that’s read only.



Thank you very much for helping me figure out the intended way to use this function.



Best,

Chris



Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win32

Type "help", "copyright", "credits" or "license" for more information.

>>> import nibabel as nib

>>> nib.__version__

'2.1.0'



>>> import nibabel.processing

>>> img = nib.load('Template_6.nii')

>>> img.shape

(121, 145, 121, 2)



>>> data = img.get_data()

>>> r = nib.processing.resample_to_output(data[...,0], [3,3,3])

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

  File "C:\Users\mbmhscc4\AppData\Roaming\Python\Python36\site-packages\nibabel\processing.py", line 242, in resample_to_output

    out_vox_map = vox2out_vox((in_img.shape, in_img.affine), voxel_sizes)

AttributeError: 'memmap' object has no attribute 'affine'



>>> r = nib.processing.resample_to_output(img, [3,3,3])

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

  File "C:\Users\mbmhscc4\AppData\Roaming\Python\Python36\site-packages\nibabel\processing.py", line 242, in resample_to_output

    out_vox_map = vox2out_vox((in_img.shape, in_img.affine), voxel_sizes)

  File "C:\Users\mbmhscc4\AppData\Roaming\Python\Python36\site-packages\nibabel\spaces.py", line 76, in vox2out_vox

    raise ValueError('This function can only deal with 3D images')

ValueError: This function can only deal with 3D images



>>> r = nib.processing.resample_to_output(img[...,0], [3,3,3])

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

TypeError: __getitem__() takes 1 positional argument but 2 were given



>>> vol0 = img.dataobj[...,0]

>>> r = nib.processing.resample_to_output(vol0, [3,3,3])

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

  File "C:\Users\mbmhscc4\AppData\Roaming\Python\Python36\site-packages\nibabel\processing.py", line 242, in resample_to_output

    out_vox_map = vox2out_vox((in_img.shape, in_img.affine), voxel_sizes)

AttributeError: 'numpy.ndarray' object has no attribute 'affine'



# This is after the previous attempt, loading only the first volume. img remains 4D

>>> r = nib.processing.resample_to_output(img, [3,3,3])

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

  File "C:\Users\mbmhscc4\AppData\Roaming\Python\Python36\site-packages\nibabel\processing.py", line 242, in resample_to_output

    out_vox_map = vox2out_vox((in_img.shape, in_img.affine), voxel_sizes)

  File "C:\Users\mbmhscc4\AppData\Roaming\Python\Python36\site-packages\nibabel\spaces.py", line 76, in vox2out_vox

    raise ValueError('This function can only deal with 3D images')

ValueError: This function can only deal with 3D images





>>> img.shape = img.shape[0:3]

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

AttributeError: can't set attribute





Christopher R. Cox, PhD

Neuroscience and Aphasia Research Unit (NARU)

University of Manchester, UK

christopher.cox-2 at manchester.ac.uk<mailto:christopher.cox-2 at manchester.ac.uk>


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/neuroimaging/attachments/20171012/e566127d/attachment.html>


More information about the Neuroimaging mailing list