In [1]:
    
import dicom
import numpy as np
import cv2
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
%matplotlib inline
from skimage.filters import threshold_otsu
from skimage.measure import label, regionprops
from skimage.color import label2rgb
from os import listdir
from os.path import join
from mpl_toolkits.mplot3d import Axes3D
    
In [2]:
    
# This is the functionalized segmentation procedure post-thresholding
# Please add to your path
from Segmenter import vol_segment
    
In [3]:
    
# List all patients
patients = listdir('./kaggle_sample_data/')
    
In [11]:
    
segmented_lung = {}
vols = {}
# Cycle over all patients
# Takes a while...
for patient in patients:
    
    if patient[0] != '0' or patient == '0b20184e0cd497028bdd155d9fb42dc9':
        continue
    # Read in filenames
    path_dcms = './kaggle_sample_data/' + patient + '/'
    list_dcms = listdir(path_dcms)
    # Create variables to hold a 3D volume
    width = 512; height = 512; depth = len(list_dcms)
    lung_vol_houns = np.zeros([width,height,depth])
    # Create a dictionary to link slice location with image
    dcm_slices_houns = {}
    # Stack up all the slices in order
    for d in range(depth):
        dcm_file = dicom.read_file(path_dcms + list_dcms[d])
        # This is to club bone and other organs into a single broad non-lung class
        dcm_file.pixel_array_houns = (dcm_file.RescaleSlope * dcm_file.pixel_array) + dcm_file.RescaleIntercept
        dcm_file.pixel_array_houns[dcm_file.pixel_array_houns > -450] = -450
        dcm_slices_houns[dcm_file.SliceLocation] = dcm_file.pixel_array_houns
    sorted_slices = np.sort(dcm_slices_houns.keys())
    # Now let's make a single volume
    for idx,s in enumerate(sorted_slices):
        lung_vol_houns[:,:,idx] = dcm_slices_houns[s]
    # Let's max min normalize these images
    lung_vol_norm = (lung_vol_houns - np.min(lung_vol_houns))/(np.max(lung_vol_houns) - np.min(lung_vol_houns))
    # Otsu thresholding
    flat_volume = lung_vol_norm.flatten()
    noise_thresh = 0.05
    flat_volume_clean = flat_volume[flat_volume > noise_thresh]
    otsu_thresh = threshold_otsu(flat_volume_clean)
    # Do the actual segmentation
    segmented_lung[patient], vols[patient]  = vol_segment(lung_vol_norm, otsu_thresh)
    
In [21]:
    
# Keeping track of the region volumes
bads = []; goods = []
for vol in vols.itervalues():
    bads.append(vol[2])
    goods.append(vol[1])
    
In [29]:
    
plt.plot(range(len(bads)),bads)
plt.plot(range(len(goods)),goods)
plt.plot([0, len(goods)], [1e6, 1e6], 'k-', lw=2)
ax.lines
    
    Out[29]:
    
In [12]:
    
# Create a 3D visualization
    
for patient in segmented_lung.iterkeys():
    segmented = segmented_lung[patient]
    fig = plt.figure(figsize = (15,15))
    ax = fig.gca(projection='3d')
    ax.set_zlim([0,segmented.shape[2]+4])
    X = np.tile(np.arange(512),[512,1])
    Y = np.transpose(np.tile(np.arange(512),[512,1]))
    for i in range(segmented.shape[2]):
        ax.contour(X, Y, segmented[:,:,i]*(i+1), levels = [ i])
    fig.savefig('./3D1_' + patient + '.png')