Automating Radiology – detecting lung nodules using morphological image processing in F#
The human lung has a variety of techniques to keep the lung sterile, if small grains of sand, dust or small organisms enter the lungs then the body’s immune response is to destroy it with enzymes or clear it from the lung with coughing, however in some cases neither of these techniques work, so the body has to ‘wall’ the foreign material off, resulting in nodular densities that can calcify (calcium is a by product of this ‘walling off’), these nodules are seen on chest X-rays. Organisms also cause calcified nodules, these include the tuberculosis bacterium, Rubella (the virus that causes German Measles), and a variety of fungi.
In the case of the tuberculosis when our body tries to ‘wall’ the foreign bacterium off, calcified nodular densities can appear within the lungs. These nodules could indicate ‘inactive TB’ is present in the patient. These densities are seen on chest X-rays. Medically it is important to know whether a person has inactive TB because this can indicate that the patient is now more susceptible to contract TB again. The aim of this article is to see how we can use morphological image processing techniques as a method to create an automated detection system for these nodules within a chest X-ray:
Image processing background
Morphological Image processing techniques are useful tools for extracting image components such as boundaries and skeletons, ‘Erosion’ and ‘Dilation’ are fundamental techniques used. Dilation is an operation that “grows” or “thickens” an image by a specific structuring element.
First let us look at dilation. Dilation is defined as:
The morphological transformation dilation combines two sets using vector addition, here is a graphical example of a dilation of an image a by a 3×3 structuring element of 1’s:
Erosion combines two sets using vector subtraction of set elements, and is the dual operator of dilation. It should be noted that erosion and dilation are not inverse transformations. If an image is eroded and then dilated the original image is not obtained.
Here is a graphical example of erosion by the structuring element:
This has the opposite effect.
Opening and Closing
From the two operators, erosion and dilation, we can define two more operations called opening and closing using the following equations:
Simply put a morphological opening operation is simply an erosion followed by a dilation by a structuring element, whereas morphological closing is a dilation followed by and erosion. Opening and closing an image with an isotropic structuring element (isotropic in this context means that the structuring element behaves in the same way in all directions, like a square or circle of 1’s with an origin in the center) can be used to eliminate specific image details smaller than the structuring element. Closing connects objects that are close to each other, fills small holes and smoothes the object outline.
Nodule detection algorithm – Modified Grayscale Top Hat Morphological Transform (MGTH)
Now that we have discussed morphological image processing we can discuss the MGTH (Modified Grayscale Top Hat Morphological Transform). The MGTH uses the opening and closing operation to removing large vessels and boney structures in the X-ray revealing nodular like densities. The MGTH is described as the following:
The results of this operation are very similar to another morphological image processing technique called the Top-Hat transformation which is a good tool for extracting light objects on a dark but slowly changing background.
Prototyping in Matlab
Before building out an application to analyze the X-rays, let’s build a little prototype using MATLAB’s image processing libraries. This way we can see if the algorithm works:
%image is the intensity matrix which represents % the xray %SEsize is the size of the structuring element function h = MGTH(image, SEsize); %create a square structuring element. se1 = strel('square',SEsize); %perform 'open' morphological operation on image erodedXRay = imerode(image, se1); xRayOpen = imdilate(erodedXRay,se1); %perfom 'close' on the image dilatedXRay = imdilate(image, se1); xRayClose = imerode(dilatedXray,se1); outlines =imsubtract(imsubtract(image, xRayOpen),imsubtract(xRayClose, image)); h = outlines;
Once happy we can move onto building the solution in F#.
The first thing to do is to implement the basic morphological operations. Lets start with ‘erosion’ and ‘dilation’. Lets start by writing the tests:
and then the implementation:
then based the equations for erosion and dilation we can define opening and closing:
Once we’ve done that we need a few simple functions for addition and subtraction of image matrices, so lets define some tests for that:
(note that I’ve skipped out some tests in the interest of space)
And then the implementation:
Then finally the actually MGTH algorithm:
When we run the MGTH function with an intensity array representing an Xray, we get an output which highlights the nodules. I’ve dilated the results and applied them to the following XRay below which can be seen in red:
We can use F# to implement morphological image processing methodologies, and use them to produce medical expert systems.