Medical image processing

by Thomas Kerwin

Getting VTK and ITK working under linux

Since I was using debian, I was able to install prebuilt packages for VTK and install the python bindings for VTK as well. Unfortunately, I was not as lucky with ITK, and for that I needed to download the source and compile it. This took some time, and getting the python bindings to compile and work properly took even more time.

My first impression of VTK was that it was slow. I wrote a short python script to load a volume from image slices, then construct an isosurface using vtkContourFilter. I experimented some more with the python scripts and getting even a slice viewer working using vtk with this setup was extremely slow.

Using some other tools

Volume rendering with no transfer function.

Volume rendering, showing voxels with value greater than 35 and using a clipping plane.

Isosurface for isovalue = 35.

I'm used to using VolSuite for viewing data and I continued to use it to quickly view 3d data in this project and apply transfer functions to the data. However, it doesn't have a wide range of image processing tools integrated into the program. Another piece of software I used in this project was MeVisLab. It offers a graphical, network-based image processing framework with plugin dlls for VTK and ITK classes.

Sheep heart dataset

The first dataset I processed was the MRI dataset of a sheep's heart. I loaded it up in VolSuite and noticed a couple of facts about the data. One is that the data is not very noisy, especially inside the heart. This should make processing easier. The second is that the material seems to be divided into three main parts: the light material that makes up the bulk of the heart, the hollow space inside and outside the heart where there is very low or no signal, and the the dark matter that seems to clump around the top half of the heart. I did some elementary processing in VolSuite to get a better look at the data.

The outside noise gives some serious interference to viewing the volume, so I changed the parameters to only display voxels with a value greater than 35. This gets rid of most of the visible low-level noise outside the object, but this is only visually. I also used a isosurface to highlight the noise: this isosurface is set at 35 as well.

After looking at the data, I used MeVisLab to run the data through some more involved processing. I used the anisotropic diffusion filter based on Tukey's biweight. I thresheld that data to get a binary mask of the dark regions. This gave me results with a ring around the edge of the data, probably from the linear blending of the light matter to the black of the background. To rectify this, I used opening operation. This is the combination of a erosion followed by a dilation. This got rid of the small lines surrounding the heart and left only the dark matter I was interested in.

Tukey diffusion

I think the anisotropic diffusion function is very effective for smoothing out noise in images with some high contrast regions. You can see some strange artifacts with the white blotches in the interface between the regions, but in general, this had a very nice effect of smoothing out the regions while keeping the regions distinct. It got rid of a great deal of noise in the outside region too, without having to use thresholding.

I output the dataset resulting from only keeping original voxel data where my mask was. I viewed that in VolSuite and it looked pretty good, except for some artifacts in the middle of the volume where there shouldn't be any of that material.

PET image of a torso

This data was much different from anything I had worked with before. The data values were heavily biased toward a few localized spots like the skull, bladder and kidneys. As with the sheep, I got a good idea of the dataset by looking at it in VolSuite. Since the datasize was fairly large, I decided to crop it and focus on the region of the torso with the liver and kidneys.

Still, the signal was not very strong on the internal organs, the division between them was very faint. I used the itkOtsuThresholdImageFilter to set a good threshold point to begin. You can see the results here. I attempted to use fuzzy connectedness but the program seemed to hang whenever I tried it with a large number of different regions and with only 3 regions, it got pretty much the same areas as Otsu's filter. Region growing didn't help too much either, since most of the internal organs have shared pixels. This is probably due to the low resolution of the data: with only 643 voxels, bleedover is high.

Otsu's filter results

I felt stuck here, because short of hand segmenting contours, I couldn't see how to automaticly extract the liver. I checked the CT data as well, and the voxel values for the kidneys and the liver were nearly identical in thatdataset as well.

Tone shading of watershed segmentation

So I tried a watershed approach, hoping to take advantage of any small differences along the boundaries of the objects, even if they are very close. I ran the sobel3d filter on the data to get the gradient magnitudes: in my experience it performs better than central differences. I then applied the itkWatershedImageFilter with parameters of 0.008 for threshold and level. I got these values by trial and error, and I'm sure there are better ones. This partitioned the volume into segments, and one of them took most of the space of the liver, although it was far from perfect. See a comparison image here.

After doing the watershed, I used a scale and threshold to isolate the segment that I thought was the most accurate for the liver. I used this binary image as a mask and output the original values that were in that segment. You can see my network here.

Tone shading of watershed segmentation

I tried one more thing, anisotropic diffusion with region growing. I was suprised at how easy this was to get working. I used the Weickert diffusion function and then put a seed point in the liver region. The region growing performed pretty well after I tweaked the cutoff value. I visualized this data in MeVis as well, using tone shading. The results are comparable to the watershed output, but they do not match exactly.

-

regular rose vs. anisotropicly diffuse rose