Creating a nifti file from a numpy array
Asked Answered
P

2

15

I have a numpy array that I would like to covert into a nifti file. Through the documentation it seems PyNIfTI used to do this with:

image=NiftiImage(Array)               

However, PyNIfTI isn't supported anymore. NiBabel, the successor to PyNIfTI, doesn't seem to support this function. I must be missing something. Does anyone know how to do this?

Pneumatophore answered 4/2, 2015 at 20:26 Comment(0)
H
26

The replacement function in the newer NiBabel package would be called Nifty1Image. However, you are required to pass in the affine transformation defining the position of that image with respect to some frame of reference.

In its simplest form, it would look like this:

import nibabel as nib
import numpy as np

data = np.arange(4*4*3).reshape(4,4,3)

new_image = nib.Nifti1Image(data, affine=np.eye(4))

You could also write to a NIfTI-2 file format by using Nifti2Image, which also requires the affine transformation.

Hefty answered 4/2, 2015 at 20:44 Comment(8)
Thank you so much! I totally missed that in the documentation. This was a huge help! (I can't Vote up since this was my first time on Stack Overflow.)Pneumatophore
@Pneumatophore Glad to help and welcome to StackOverflow. Don't worry about not being able to upvote, it takes some time to get reputation. You can accept the answer though, which will also give you some reputation. And it will signify to the larger community that you have found an answer that works.Hefty
Sorry - I'm still having problems. I'm looking to create the nifti file with vector data. I initialize the array via: vectorArray = np.zeros((3,3,3), dtype = ('float,float,float')) The nib.Nifti1Image gives the error: data dtype "[('f0', '<f8'), ('f1', '<f8'), ('f2', '<f8')]" not supportedPneumatophore
@Michelle, that's because you have created (needlessly) a structured array. Simply put: you have created an array of records, where each element of those records is a float. To solve, simply define your array like this: vectorArray = np.zeros((3,3,3), dtype=np.float).Hefty
Thanks again :-) But how can I get my vector data ( (i,j,k)/voxel), i.e. (0.23, 0.48, 0.84) for array location [1,1,1] into that type?Pneumatophore
@Michelle, I'm not entirely sure what you're asking. I think you want to define the numpy array upfront, e.g. like this: arr = np.zeros((2,4,3,3)); arr[1,1,1] = [.23, .48, .84] and then convert to a NIfTI image. If not, I suggest asking a new question on SO and best to add a good example of what you're after ;-)Hefty
@Pneumatophore Hmmmm, I should use np.eye(4) all the time right? I feel confused even with the document :(Lewiss
@LossesDon please check my answerNucleolus
N
5

Accepted answer is sufficient. I am adding few lines of detailed explanation for the same.

import nibabel as nib
import numpy as np

data = np.arange(4*4*3).reshape(4,4,3)

new_image = nib.Nifti1Image(data, affine=np.eye(4))

The function np.eye(n) returns a n by n identity matrix.
Here this np.eye(4) is used to generate 4 by 4 matrix as Nifti processes 4 by 4 file format. So you 3 by 3 matrix is converted to 4 by 4 by multiplication with 4 by 4 identity matrix.

So, always affine = np.eye(4) will work.

Same is applicable to both Nifti1Image and Nifti2Image

Nucleolus answered 22/11, 2018 at 9:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.