Sunil Kumar
Sunil Kumar

Reputation: 1391

Segmenting Lungs and nodules in CT images

I am new with Image processing in Matlab, I am trying to segment LUNG and nodules from CT image. I have done initial image enhancement.

I searched lot on the same but I haven't found any relevant materials.

Trying to segment lung part from the given image; and then detecting nodules on Lung part.

enter image description here

Code I tried in Matlab:

d1 = dicomread('000000.dcm'); 
d1ca = imadjust(d1); 

d1nF = wiener2(d1ca);

d1Level  = graythresh(d1nF);
d1sBW = im2bw(d1nF,d1Level); 
sed = strel('diamon',1); 
BWfinal = imerode(d1sBW,sed);
BWfinal = imerode(BWfinal,sed);

BWoutline = bwperim(BWfinal);
Segout = d1nF;
Segout(BWoutline) = 0; 

edgePrewitt = edge(d1nF,'prewitt'); 

Result of above code:

enter image description here

Want results like this:

http://oi41.tinypic.com/35me7pj.jpg

http://oi42.tinypic.com/2jbtk6p.jpg

http://oi44.tinypic.com/w0kthe.jpg

http://oi40.tinypic.com/nmfaio.jpg

http://oi41.tinypic.com/2nvdrie.jpg

http://oi43.tinypic.com/2nvdnhk.jpg

I know its may be easy for experts. Please help me out.

Thank you!

Upvotes: 10

Views: 8252

Answers (2)

lennon310
lennon310

Reputation: 12689

Try this:

% dp6BK.png is your original image, I downloaded directly
I = im2double(imread('dp6BK.png'));  
I=I(:,:,1);
imshow(I)


cropped = I(50:430,8:500); %% Crop region of interest   
thresholded = cropped < 0.35; %% Threshold to isolate lungs
clearThresh = imclearborder(thresholded); %% Remove border artifacts in image   
Liver = bwareaopen(clearThresh,100); %% Remove objects less than 100 pixels
Liver1 = imfill(Liver,'hole'); % fill in the vessels inside the lungs
figure,imshow(Liver1.*cropped)

What you will get:

enter image description here

Upvotes: 7

karlphillip
karlphillip

Reputation: 93468

The following is not a Matlab answer! However, OpenCV and Matlab share many features in common, and I'm sure you will be able to translate this C++ code to Matlab with no problems.

For more information about the methods being called, check the OpenCV documentation.

#include <iostream>
#include <vector>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>    

int main(int argc, char* argv[])
{
// Load input image (colored, i.e. 3-channel)
cv::Mat input = cv::imread(argv[1]);
if (input.empty())
{
    std::cout << "!!! failed imread()" << std::endl;
    return -1;
}   

// Convert input image to grayscale (1-channel)
cv::Mat grayscale = input.clone();
cv::cvtColor(input, grayscale, cv::COLOR_BGR2GRAY);

What grayscale looks like:

// Erode & Dilate to remove noises and improve the result of the next operation (threshold)
int erosion_type = cv::MORPH_RECT; // MORPH_RECT, MORPH_CROSS, MORPH_ELLIPSE
int erosion_size = 3;
cv::Mat element = cv::getStructuringElement(erosion_type, 
                                            cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1), 
                                            cv::Point(erosion_size, erosion_size));

cv::erode(grayscale, grayscale, element);
cv::dilate(grayscale, grayscale, element);

What grayscale looks like after morphological operations:

// Threshold to segment the area of the lungs
cv::Mat thres;
cv::threshold(grayscale, thres, 80, 150, cv::THRESH_BINARY);

What thres looks like:

    // Find the contours of the lungs in the thresholded image
std::vector<std::vector<cv::Point> > contours;
cv::findContours(thres, contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);


// Fill the areas of the lungs with BLUE for better visualization   
cv::Mat lungs = input.clone();      
for (size_t i = 0; i < contours.size(); i++)
{
    std::vector<cv::Point> cnt = contours[i];
    double area = cv::contourArea(cv::Mat(cnt));        

    if (area > 15000 && area < 35000)
    {
        std::cout << "* Area: " << area << std::endl;
        cv::drawContours(lungs, contours, i, cv::Scalar(255, 0, 0), 
                         CV_FILLED, 8, std::vector<cv::Vec4i>(), 0, cv::Point() );
    }           
}

What lungs looks like:

// Using the image with blue lungs as a mask, we create a new image containing only the lungs
cv::Mat blue_mask = cv::Mat::zeros(input.size(), CV_8UC1);
cv::inRange(lungs, cv::Scalar(255, 0, 0), cv::Scalar(255, 0, 0), blue_mask);    
cv::Mat output;
input.copyTo(output, blue_mask);

What output looks like:

At this point you have the lungs isolated in the image and can proceed to execute other filter operations to isolate the nodules.

Good luck.

Upvotes: 14

Related Questions