3D visualization of .dicom files with ipyvolume - python

i'm trying to visualize a set of .dicom files using pydicom and ipyvolume.
I used pydicom to read files and then sorted them by their location and turned the slices into a 3D array. I could draw a 3D model of the data using ipyvolume.pylab.plot_isosurface() although I'm not sure if this is the right way of visualizing medical images (it's all solid pixels with the same opacity and color). I've also tried ipyvolume.pylab.volshow() but that did not work.
Is there a right way to visualize medical images with ipyvolume? or this is just not the right library for that?

DICOM file does not have 'voxel' data so you can't simply plot a dicom in 3D view. You should estimate voxel data using slices of a dicom series. after that, using a 3D modeling algorithm such as Marching Cubes you can extract final 3D model. Take a look at CTU.

I haven't used ipyvolume, but looking at the documentation it ought to be able to visualize DICOM image sets.
If you want to try another package, I use SimpleITK to load DICOM images and itkwidgets do volume visualization in a Jupyter notebook.
Here's a simple notebook that load a DICOM series and displays it:
import SimpleITK as sitk
import itkwidgets
# Get the DICOM file names in the current directory
names = sitk.ImageSeriesReader.GetGDCMSeriesFileNames('.')
# Read the DICOM series
reader = sitk.ImageSeriesReader()
reader.SetFileNames(names)
img = reader.Execute()
itkwidgets.view(img)
If the directory has more than one DICOM series in it, GetGDCMSeriesFileNames has a seriesID parameter you can give it to specify which series to load.

Related

How to render an stl and save it as a png?

I am trying to render an stl and save it as a png so it is a preview of the stl.
I have a project that needs to take layer images(png) and save it as 3d(stl). I converted every layer image(approximately 300-400 image) to a numpy array. Then from those numpy arrays I made vertices and faces. My stl files are faces(triangles) aligned on top of each other. So there is no actual body in the final image just faces aligned together.(Layers have no z value)
Here is a single layer from one of my models:
And here is the final model:
And now I am trying to generate an image like the 2nd picture above. So there will be a preview of the stl model. And I am trying to figure a way out to save the preview as a png file. But I couldn't figure out the plot libraries' camera movements.
I tried matplotlib but i suppose there is no camera adjustment setting so it generates a png on a side that I do not want. That's why I want a way to control the camera. There is blender's Python API but it seems pretty confusing.
Any ideas on how to do that in Python?

How to save matplotlib plot to a hdf5 file?

im processing measured data and in a following process i create plots of them. (To be more specific its about to display orbits of a spinning shaft.) Thus i will create many plots and i want to safe them to a hdf5 file. The "workaround" i know is:
saving the file to a .jgp
reading it with opencv
writing that array to the hdf5
This works well, but will create a mess in my working dictionary.
Here is a Code example if someone wants to just safe one ore two plots:
fig.savefig(some_plot.jpg) # saves the plot to working discretionary as 'some_plot.jpg'
image = cv2.imread(some_plot.jpg) # reads the created .jpg as array
g = f.create_dataset(some_path, data=image) # creates dataset in the hdf5 and safes the
image array to it
# add !!important!! image attributes , i got these from another forum but if you convert a
# image in hdf5 and read the attributes you can create them by yourself
# futher information is in the hdf5 documentation (hdfgroup.org --> HDF5 Image and Palette
Specification)
g.attrs.create('CLASS', 'IMAGE', dtype='S6')
g.attrs.create('IMAGE_MINMAXRANGE', [0, 255], dtype=np.uint8)
g.attrs.create('IMAGE_SUBCLASS', 'IMAGE_TRUECOLOR', dtype='S16')
g.attrs.create('IMAGE_VERSION', '1.2', dtype='S4')
g.attrs.create('INTERLACE_MODE', 'INTERLACE_PIXEL', dtype='S16')
So now my problem is that this code creates a .jpg image for every plot, which will make a mess. Is there a way of converting the picture to a numpy arrray without the need of saving it as a image. (I could delete the picture.jpg after it got saved to the hdf5, but i want to avoid that.) matplotlib.pyplot has a inbuild imread()-function that i will try in the future to safe the use of opencv. I hope someone knows a solution to save plot images directly to hdf5.
Best regards
Marius

Create mosaic from overlaping images in python

I have imageset which is provided from drone imaging system. Separate images do overlap for about 70%. Each image is tif file from which I can read GPS location (one location for each image). What I want to do with images is to merge them in the same tif file. In other words I would like to create mosaic from all the images available.
Furthermore, I actually have 5 imagesets. Each represents separate spectral band. So at the and I would like to create mosaic, which would consist of 5 bands.
Mosaicing for separate imageset is more illustratively shown on the picture:
https://i.stack.imgur.com/41gZm.png
I imagine workflow for marging like this:
1.) Create mosaic A_i from overlaping images from i-th imageset, where i=1..5 for each spectral band
2.) Create final mosaic B from all A_i mosaics where i=1..5 for each spectral band
I am wondering what would be the best approach to create such mosaic. I heard about dgal, rasterio, pygis etc. but I do not know which library is the most suitable, powerful and intuitive. At the end I would like to have everything implemented in python. Preferably within library, but command line calls within python will also do the job.
I hope I explaind my problem clearly enough. Any help and suggestions are welcome. Examples will be very much appreciated.
you can try to use PIL to concatenate images. An example is:
from PIL import Image
im1 = Image.open(image_file1)
im2 = Image.open(image_file2)
newIm = Image.new('RGB', (im1.width + im2.width, im1.height))
dst.paste(im1, (0, 0))
dst.paste(im2, (im1.width, 0))
if images overlap you will have to adjust the values where to paste them.
I hope this help with your issue.

How to turn CT segmentation into 3d model in python

I have this numpy array of slices of segments of the liver CT(ground truths). I want to export them into a viewable format in tools like blender. The slices are white and black, 0-255. Anything other than liver is black, I want the liver to be viewed in 3d.
The slices are in top view. I used this code in kaggle to view them but just in jupyter https://www.kaggle.com/akh64bit/full-preprocessing-tutorial/data. It can be any way to visualize them.
You may try transform your arrays to DICOM format as mentioned before in stackoverflow: Create pydicom file from numpy array
Than you can easily visualize DICOM images in various platforms!
For new folks stumbling upon this question that are looking to convert pixels / voxels to an STL file or files, this Python workflow has worked for me:
Load stack of images as a 3D NumPy array using imageio.imread().
Segment the foreground from the background using one of the many segmentation algorithms from the scikit-image submodule skimage.segmentation, creating a 3D binary image.
Use the marching cubes algorithm from the scikit-image submodule skimage.measure to convert the voxels of interest to a list of faces defined by vertices on the surface of the volume.
Use numpy-stl to create an stl.Mesh object from the list of faces and vertices (as done in this example) then save the mesh with stl.Mesh.save().
As a bonus, you can use the Python package for the Open3D library to open & view multiple STL files!

convert itk (nifti file) to polydata image (.vtk)

I am working with MRI database with niftiformat (.nii) but I want to convert them to polydata images .vtk.
I used many different methods: like miconv, itksnap, I download vtk, itk, and itkvtkglue...
But no one give me a good results.
So please help me.
If I understand correctly nii files are volumetric data so you cannot just "convert" it to polygonal data unless you create an isosurface out of it, try:
from vtkplotter import load
vol = load('myfile.nii') #vtkVolume
vol.isosurface().show()
# or convert to vtk format:
vol.write('newfile.vti')

Categories

Resources