1

Trying to segment out the lung region, I am having a lot of trouble. Incoming image is like this: (This is essentially a jpg conversion, and each pixel is 8 bits.) enter image description here

I = dicomread('000019.dcm');
I8 = uint8(I / 256);
B = im2bw(I8, 0.007);
segmented = imclearborder(B);

Above script generates: enter image description here

Q-1

I am interested in entire inner black part with white matter as well. I have started matlab couple of days ago, so not quite getting how can I do it. If it is not clear to you what kind of output I want, let me know-I will upload an image. But I think there is no need.

Q-2

in B = im2bw(I8, 0.007); why I need to give a threshold so low? with higher thresholds everything is white or black. I have read the documentation and as I understand it, the pixels with value less than 0.007 are marked black and everything above is white. Is it because of my 16-to-8 bit conversion?

Adorn
  • 1,403
  • 1
  • 23
  • 46

2 Answers2

2

Here's a working solution in python using OpenCV:

import cv2 #openCV
import numpy as np

filename = 'zFrkx.jpg' #name of file in quotations here... assumes file is in same dir as .py file
img_gray = cv2.imread(filename, 0) #converts jpg image to grayscale representation
min_val = 100 #try shifting these around to expand or collapse area of interest
max_val = 150
ret, lung_mask = cv2.threshold(img_gray, min_val, max_val, cv2.THRESH_BINARY_INV) #fixed threshold uses values you'll def above
lung_layer = cv2.bitwise_and(img_gray, img_gray, mask = lung_mask)
cv2.imwrite('cake.tif', lung_layer) #outputs desired layer to current working dir

I tried running the script with threshold values set arbitrarily to 100,150 and got the following result, from which you could select the largest continuous element using dilation and segmentation techniques (http://docs.opencv.org/master/d3/db4/tutorial_py_watershed.html#gsc.tab=0).

LUNG saved as jpg due to upload issues

Also, I suggest you crop the bottom and top X pixels to cut out text since no lung will fill the top or bottom of the picture.

Use tif instead of jpg format to avoid compression related artifact.

I know you noted that you'd like the medullar(?) white matter, too. Would be glad to help with that, but could you first explain in plain english how your shared matlab code works? Seems to work pretty well for the WM.

Hope this helps!

David Shaked
  • 3,171
  • 3
  • 20
  • 31
  • I have a C++ code which does the required task, need to do it in matlab. Converting from C++ to matlab line by line does not seem all right, since it may not be proper use of matlab, I referred to http://stackoverflow.com/questions/20285200/segmenting-lungs-and-nodules-in-ct-images?rq=1 for writing the code. Also about explaining matlab code, there is not much done, simple thresholding. I myself do not understand why value near 0.05 works – Adorn Sep 11 '15 at 04:26
  • I think part of the problem might be the assumption that a black and white ct jpg is properly gray scale represented. Try applying a function to convert from RGB color space to grayscale before applying the threshold function. It seems the calculation of I-8 assumes each pixel in I is represented on a single scale from 0 to 256. However, such a value for each of r, g, and b exists for I. Try the conversion to grayscale before the threshold and let me know what works. – David Shaked Sep 11 '15 at 17:37
2

An other automatic solution that I did quickly using ImageJ (there are the same algorithms in MatLab):

  1. Automatic thresholding using Huang or Li in the color space of your choice (all of them work)
  2. Opening with a structuring element of type disk (delete the small components)
  3. Connected components labeling.
  4. Delete the components that touches the border of the images.
  5. Fill holes.

And you have a clean result.

FiReTiTi
  • 5,597
  • 12
  • 30
  • 58