How can I obtain 2D slices from a 3D NIfti volume? - python

I'm currently using the following code to convert DCM slices into NIfti images:
import dicom2nifti
import os
dicom2nifti.convert_directory("input_path", "output_path", compression=True, reorient=True)
This code will generate a 3D NIfti volume.
How can I obtain all the slices from this 3D NIfti volume?

Use the package nibabel. A simple working example opens your NIfTI file as a numpy 3D matrix, which can use for your processing needs:
import nibabel as nib
import numpy as np
import matplotlib.plot as plt
my_nifti = nib.load('YOURNIFTIFILE.nii').get_fdata()
# get the shape of your NIfTI
my_nifti.shape
# access it as 3D numpy array
nifti_slice = my_nifti[:,:,59]
# display the slice
plt.imshow(nifti_slice)
plt.show()

Related

Saving a multidimensional array as tiff image in python

I am working on a Hyperspectral Image(HSI) of Indian Pines. Initially the data was stored in .mat file and then using loadmat function I have read the data in an array. The array dimension is (145,145,200). Now When I am trying to save this array as a Tiff(.tif) image somehow things are not working well. I am using tifffile package and it's imwrite function to save the image. But when I am opening the image in QGIS software there it's showing only one band instead of 200 bands.
I am attaching the code here below:
import tifffile
import numpy as np
from scipy.io import loadmat
def read_HSI():
X = loadmat('Indian_pines_corrected.mat')['indian_pines_corrected']#dataset
y = loadmat('Indian_pines_gt.mat')['indian_pines_gt']#ground truth
print(f"X shape: {X.shape}\ny shape: {y.shape}")
return X, y
X, y = read_HSI()
tifffile.imwrite('IndianPines(inputX).tif', X)
If there is any other way to save a .mat file into .tif format then please let me know.
Thank you in advance.
I was able to save it using scikit-image:
import numpy as np
import skimage
data = np.dstack([skimage.data.astronaut(),skimage.data.astronaut()])
data = data.swapaxes(0,2)
data = data.swapaxes(1,2)
import matplotlib.pyplot as plt
plt.imshow(data[4])
Under the hood it uses tiffile plugin:
skimage.io.imsave('test2.tiff', data,photometric='minisblack')

How to create mesh surface from segmentation MRI file using Python and VTK

I have a binary mask of 3D medical images in nifti format, "mask.nii.gz" which I would like to extract surface mesh from.
I can load binary mask data into a numpy.ndarray as following
import numpy as np
import nibabel as nib
filePath = "mask.nii.gz"
image = nib.load(filePath)
image_data = image.get_data()
but not sure how to render the surface with vtkDiscreteMarchingCubes() using the image_data above and output the vertices from rendered surface.
Could someone shed a light on this issue? Sorry I am very new to VTK library here. Many Thanks in advance.
You can create mesh with skimage.measure, using marching_cubes
In your case, try transform nib.image to numpy ndarray
image_ndarray = np.array(imgage.dataobj).astype(np.float64)
verts, faces, norm, val = measure.marching_cubes_lewiner(image, threshold, step_size=step_size, allow_degenerate=True)

Plot 3d volumetric data represented by a 3D numpy array

I've seen that vtkplotter supports a wide range of volumetric image formats, but does it support plotting numpy arrays? I have an image in a .mhd format that I converted to .npz file and would like to plot it using the mentioned library. Is there a way to do so?
import numpy as np
data = np.zeros((3,3,3))
# how to plot this?
If you know any other tools for visualizing volumetric data, suited for medical analysis, please tell so. I've tried mayavi but it consumes so much memory that it crashes my computer.
You can use numpy_support to convert numpy arrays to vtkImageData (i.e. a VTK 3D image).
An example follows, there's a numpy warning about type conversion: I don't think it's relevant but I'm not a python guru...
from vtk.util import numpy_support
import vtk
import numpy as np
data = np.zeros((3,3,3))
# vtkImageData is the vtk image volume type
imdata = vtk.vtkImageData()
# this is where the conversion happens
depthArray = numpy_support.numpy_to_vtk(data.ravel(), deep=True, array_type=vtk.VTK_DOUBLE)
# fill the vtk image data object
imdata.SetDimensions(data.shape)
imdata.SetSpacing([1,1,1])
imdata.SetOrigin([0,0,0])
imdata.GetPointData().SetScalars(depthArray)
# f.ex. save it as mhd file
writer = vtk.vtkMetaImageWriter()
writer.SetFileName("test.mhd")
writer.SetInputData(imdata)
writer.Write()
... and to visualize vtk volume data you can use Paraview.

Obtaining z-buffer(depth) informaiton from dicom file in python

I have a set of dicom images(contains 160 .dcm files). I can visualize a single file by the following python code:
import pydicom as dicom
import os
import numpy
import matplotlib.pyplot as plt
filename = "./myfiles/MR000130.dcm";
dataset = dicom.dcmread(filename)
plt.imshow(dataset.pixel_array, cmap=plt.cm.bone)
plt.show()
My question is:
How do I visualize these whole bunch of volumetric data as a single picture?
Is there any way to obtain the z-buffer information?
It's in the file. There is stuff in the DICOM apart from pixel data. See it with
print(dataset._pretty_str).
It might be dataset.SliceLocation.
We can't tell you how to change 3D to 2D. You could read all the slices, and then reslice in other planes. You could do some fancy segmentation and render surfaces in 3D. You need to decide what is most appropriate for your case.

Viewing .npy images

How can I view images stored with a .npy extension and save my own files in that format?
.npy is the file extension for numpy arrays - you can read them using numpy.load:
import numpy as np
img_array = np.load('filename.npy')
One of the easiest ways to view them is using matplotlib's imshow function:
from matplotlib import pyplot as plt
plt.imshow(img_array, cmap='gray')
plt.show()
You could also use PIL or pillow:
from PIL import Image
im = Image.fromarray(img_array)
# this might fail if `img_array` contains a data type that is not supported by PIL,
# in which case you could try casting it to a different dtype e.g.:
# im = Image.fromarray(img_array.astype(np.uint8))
im.show()
These functions aren't part of the Python standard library, so you may need to install matplotlib and/or PIL/pillow if you haven't already. I'm also assuming that the files are either 2D [rows, cols] (black and white) or 3D [rows, cols, rgb(a)] (color) arrays of pixel values.
Thanks Ali_m. In my case I inspect the npy file to check how many images was in the file with:
from PIL import Image
import numpy as np
data = np.load('imgs.npy')
data.shape
then I plotted the images in a loop:
from matplotlib import pyplot as plt
for i in range(len(data)):
plt.imshow(data[i], cmap='gray')
plt.show()

Categories

Resources