ap08082000
ap08082000

Reputation: 1

XYZ format of nifti MRI images

I am working with 3d MRI images in X,Y,Z format where Z is number of slices in brain. I have JPEGS and niftis and I wanna save both files as xyz format numpy array. In the nifti file format, the files are read in as xyz but when I print the first slice I get it as x axis length of z and on Y is length of. How can I read it as xyz and still be able to print the third dimension as a square.

img = nib.load(os.path.join(data_path, str(list_dir[i]) + ".nii.gz"))

# Get the data from the NIFTI image
data = img.get_fdata()

# Get the shape of the data
slices = []
print(data.shape)
data = np.transpose(data, (0, 1, 2))
shape = data.shape
print(shape)

# Loop through each slice in the data
for i in range(shape[2]):
    # Get the current slice
    slice = data[:,:,i]
    slice = np.rot90(slice, axes = (1,0))

    # Save the slice as a 3D Numpy array
    slices.append(np.array(slice))
# Convert the list of slices to a Numpy array
print(len(slices))
slices = np.array(slices)
print(slices.shape)

Upvotes: 0

Views: 604

Answers (1)

alle_meije
alle_meije

Reputation: 2480

The fastest way I know to make a NIftI file out of some (say, 3) JPEG files is this:

First download a file to use:
wget -P /tmp https://upload.wikimedia.org/wikipedia/commons/3/3b/MRI_brain.jpg

Then, use all the libraries you can get

import matplotlib.pyplot as plt;   # for reading JPG files
import nibabel as nib;             # for writing nifti files
import numpy as np;                # for concatenating 2D -> 3D

sli = plt.imread ( '/tmp/MRI_brain.jpg' );     # load the JPG 'slice'
img = np.dstack ( ( sli, sli, sli ) )          # stack copies as 3D
nii = nib.Nifti1Image ( img, np.eye ( 4 ) );   # make a NIfTI image
nii.to_filename ( 'test.nii' );                # save as a NIfTI file

That should give you a 3D image of 3 slices.

What (I think) you mean with the XYZ story is that in MRI image viewers, the 'fastest' direction X is left-to-right, Y is anterior-to-posterior and Z is bottom-to-top. But these dimensions may not correspond to how the images are stored. The dimensions may be stored as ZXY instead of XYZ, and the values may be stored right-to-left not left-to right.

If you open the file test.nii in a viewer, you will see that each of the slices shows a sagittal image (which would be the XZ dimensions), but they are shown as axial slices, and (if the viewer interprets them) R-L , A-P and I-S are not in the right places. This is because the co-ordinate matrix I4 does not correspond to the storage order in the files.

In this case, the quickest solution is to use a co-ordinate matrix that corresponds to the storage order:

nii = nib.Nifti1Image ( img, np.asarray ( [ [  0,  0, 1, 0 ],
                                            [  0, -1, 0, 0 ],
                                            [ -1,  0, 0, 0 ],
                                            [  0,  0, 0, 1 ] ] ) );
nii.to_filename ( 'test.nii' );

then the letters for A-P and I-S are correctly displayed.
(the slices are the same so there is no sensible choice between L-R and R-L)

The page about co-ordinate matrices tells you that with this matrix, moving in each voxel dimension

  • moves in exactly one 'body' direction (1 number per row/column)
  • moves exactly 1 mm/voxel in each of those directions (the length of each row/column vector)

Note that the matrix was made up and may not be correct.

So in a viewer, when zoomed in, a voxel would be a square in each direction.

Upvotes: 0

Related Questions