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.
Related
i using SLIVER07 dataset for liver segmentation task but i am stuck in reading that images.
import SimpleITK as sitk
import numpy as np
import matplotlib.pyplot as plt
# reading .mhd file from slive07 dataset
itkimage = sitk.ReadImage('liver-orig001.mhd')
ct_scan = sitk.GetArrayFromImage(itkimage)
plt.imshow(ct_scan[1])
You are trying to pass the entire 3D image volume to imshow. You could instead try:
plt.imshow(ct_scan[40,:,:])
Which will show the 40th slice.
Of interest might be the platipy library, available here, or just $ pip install platipy. The built-in image visualiser (based on matplotlib) is perfect for 3D image visualisation in python, and has lots of cool features.
A little demo:
from platipy.imaging import ImageVisualiser
img = sitk.ReadImage("image_filename.mhd")
vis = ImageVisualiser(img)
fig = vis.show()
I have a satellite image of 7-channels (Basically I have seven .tif files, one for each band). And I have a .csv file with coordinates of points-of-interest that are in the region shot by the satellite. I want to cut small portions of the image in the surroundings of each coordinate point. How could I do that?
As I don't have a full working code right now, it really doesn't matter the size of those small portions of image. For the explanation of this question let's say that I want them to be 15x15 pixels. So for the moment, my final objective is to obtain a lot of 15x15x7 vectors, one for every coordinate point that I have in the .csv file. And that is what I am stucked with. (the "7" in the "15x15x7" is because the image has 7 channels)
Just to give some background in case it's relevant: I will use those vectors later to train a CNN model in keras.
This is what I did so far: (I am using jupyter notebook, anaconda environment)
imported gdal, numpy, matplotlib, geopandas, among other libraries.
Opened the .gif files using gdal, converted them into arrays
Opened the .csv file using pandas.
Created a numpy array called "imagen" of shape (7931, 7901, 3) that will host the 7 bands of the satellite image (in form of numbers). At this point I just need to know which rows and colums of the array "imagen" correspond to each coordinate point. In other words I need to convert every coordinate point into a pair of numbers (row,colum). And that is what I am stucked with.
After that, I think that the "cutting part" will be easy.
#I import libraries
from osgeo import gdal_array
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import geopandas
from geopandas import GeoDataFrame
from shapely.geometry import Point
#I access the satellite images (I just show one here to make it short)
b1 = r"E:\Imágenes Satelitales\2017\226_86\1\LC08_L1TP_226086_20170116_20170311_01_T1_sr_band1.tif"
band1 = gdal.Open(b1, gdal.GA_ReadOnly)
#I open the .csv file
file_svc = "C:\\Users\\Administrador\Desktop\DeepLearningInternship\Crop Yield Prediction\Crop Type Classification model - CNN\First\T28_Pringles4.csv"
df = pd.read_csv(file_svc)
print(df.head())
That prints something like this:
Lat1 Long1 CropingState
-37.75737 -61.14537 Barbecho
-37.78152 -61.15872 Verdeo invierno
-37.78248 -61.17755 Barbecho
-37.78018 -61.17357 Campo natural
-37.78850 -61.18501 Campo natural
#I create the array "imagen" (I only show one channel here to make it short)
imagen = (np.zeros(7931*7901*7, dtype = np.float32)).reshape(7931,7901,7)
imagen[:,:,0] = band1.ReadAsArray().astype(np.float32)
#And then I can plot it:
plt.imshow(imagen[:,:,0], cmap = 'hot')
plt.plot()
Which plots something like this:
(https://github.com/jamesluc007/DeepLearningInternship/blob/master/Crop%20Yield%20Prediction/Crop%20Type%20Classification%20model%20-%20CNN/First/red_band.png)
I want to transform those (-37,-61) into something like (2230,1750). But I haven't figured it how yet. Any clues?
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.
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()
I have converted set of images to ndarray and stored it, now i have to convert them back to images without saving it to disk. I tried with " toimage() " function, but it is displaying only 1 image.
toimage(resizedlist.values()[0]).show()
resizedlist.values contains the ndarray of 49 images. Is there any way to display images randomly??
Thanks in advance!
To plot an ndarray as an image you can use matplotlib:
import numpy as np
import matplotlib.pyplot as plt
random = np.random.normal(0,1,size=[100,100])
plt.imshow(random,aspect="auto")
plt.show()
If your image data is stored RGBA, imshow will plot the image with the correct colours etc.
For reference, all this information can be found here:
http://matplotlib.org/1.3.1/users/image_tutorial.html