--- a +++ b/lung_segmentation.ipynb @@ -0,0 +1,379 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Lung Lobes Segmentation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Imports" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "import SimpleITK as sitk\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import scipy as sp \n", + "import gui\n", + "import cv2\n", + "import matplotlib.image as mpimg\n", + "\n", + "# from mayavi import mlab\n", + "from scipy import signal\n", + "from myshow import myshow, myshow3d\n", + "from read_data import LoadData\n", + "from lung_segment import LungSegment\n", + "from vessel_segment import VesselSegment\n", + "from mpl_toolkits.mplot3d import Axes3D" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Read data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# loading data\n", + "data_path = \"resource/\"\n", + "img_name = \"lola11-01.mhd\"\n", + "data = LoadData(data_path, img_name)\n", + "data.loaddata()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "print \"the shape of image is \", data.image.GetSize()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Lung Segmentation\n", + "Rescale the intensities and map them to [0,255]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "% matplotlib notebook\n", + "\n", + "WINDOW_LEVEL = (1050,500)\n", + "ls = LungSegment(data.image)\n", + "\n", + "# Convert image to uint8 for showing \n", + "ls.conv_2_uint8(WINDOW_LEVEL)\n", + "\n", + "# Set the seed point manually...\n", + "seed_pts = [(125,237,200), (369,237,200)]\n", + "\n", + "# Compute region growing\n", + "ls.regiongrowing(seed_pts)\n", + "\n", + "# showimg image\n", + "ls.image_showing(\"Region Growing Result\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Write the region growing image" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "sitk.WriteImage(ls.temp_img, \"seg_implicit_thresholds.mhd\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Morphological Operatinon (Closing)\n", + "ls.image_closing(7)\n", + "\n", + "# write image\n", + "sitk.WriteImage(ls.temp_img, \"img_closing.mhd\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "img_closing = sitk.ReadImage(\"img_closing.mhd\") # reading the existed closing image \n", + "\n", + "# get the numpy array of the 3D closing image for future using\n", + "img_closing_ndarray = sitk.GetArrayFromImage(img_closing)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Vasculature Segmentation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# get the result of previous lung segmentation.\n", + "img_closing_ndarray = sitk.GetImageFromArray(img_closing_ndarray)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "vs = VesselSegment(original=data.image, closing=img_closing_ndarray)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print \" Pricessing Generate lung mask...\"\n", + "vs.generate_lung_mask(lunglabel=[1,-5000], offset = 0)\n", + "\n", + "# Write image...\n", + "Lung_mask = sitk.GetImageFromArray(vs.img)\n", + "sitk.WriteImage(Lung_mask, \"Lung_mask.mhd\")\n", + "\n", + "print \" Processing Downsampling...\"\n", + "vs.downsampling()\n", + "\n", + "print \" Processing Thresholding...\"\n", + "vs.thresholding(thval=180)\n", + "down = sitk.GetImageFromArray(vs.temp_img)\n", + "sitk.WriteImage(down, \"downsample.mhd\")\n", + "\n", + "print \" Processing Region Growing...\"\n", + "vs.max_filter(filter_size=5)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# save the vasculature-segmented image\n", + "filtered = sitk.GetImageFromArray(vs.temp_img)\n", + "sitk.WriteImage(filtered, \"filtered.mhd\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# convert to binary image\n", + "filtered = sitk.ReadImage(\"filtered.mhd\")\n", + "filtered = sitk.GetArrayFromImage(filtered)\n", + "filtered[filtered > 0] = 1\n", + "binary_filtered = sitk.GetImageFromArray(filtered)\n", + "sitk.WriteImage(binary_filtered, \"binary_filtered.mhd\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "## Postprocessing for fissure enhancement\n", + "**Note:** the following steps need the result of fissure segmentation obtained by the C++ codes I provide. Since the SimpleITK package didn't provide enough functions for fissure segmentation (like computing 3D Hessian matrix), I used ITK C++ for this part, instead." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import SimpleITK as sitk\n", + "from read_data import LoadData\n", + "import numpy as np\n", + "import collections\n", + "\n", + "# Load the fissure image\n", + "data = LoadData(path=\"fissure_enhancement_cxx/\", name=\"vessel_rg.mhd\")\n", + "data.loaddata()\n", + "image = sitk.GetArrayFromImage(data.image)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# count the volume for each label and remove the ones less than 5000.\n", + "nonzeros = image[image > 0]\n", + "d = collections.Counter( nonzeros )\n", + "val_key = []\n", + "keys = set([])\n", + "for key, val in d.items():\n", + " if val > 5000:\n", + " keys.add(key)\n", + "\n", + "image[image == 0] = 1\n", + "for key in keys:\n", + " image[image == key] = 0\n", + "\n", + "image[image > 0] = 2\n", + "image[image == 0] = 1 # the regions left are set to 1\n", + "image[image == 2] = 0 # rest is 0\n", + "img = sitk.GetImageFromArray(image.astype(np.uint8))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Using closing to fill holes\n", + "size = 7\n", + "closing = sitk.BinaryMorphologicalClosingImageFilter()\n", + "closing.SetForegroundValue(255)\n", + "closing.SetKernelRadius(size)\n", + "img = closing.Execute(img)\n", + "# save results\n", + "sitk.WriteImage(img, \"fissure_enhancement_cxx/voxel_val_region_growing_closing.mhd\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Generate Label map for lung, vasculature and fissure regions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "lung_mask = LoadData(path=\"\", name=\"Lung_mask.mhd\")\n", + "lung_mask.loaddata()\n", + "fissure = LoadData(path=\"fissure_enhancement_cxx/\", name=\"voxel_val_region_growing_closing.mhd\")\n", + "fissure.loaddata()\n", + "vessel = LoadData(path=\"\", name=\"binary_filtered.mhd\")\n", + "vessel.loaddata()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "lung_mask = sitk.GetArrayFromImage(lung_mask.image)\n", + "fissure = sitk.GetArrayFromImage(fissure.image)\n", + "vessel = sitk.GetArrayFromImage(vessel.image)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "lung_mask[lung_mask != 0] = 3\n", + "lung_mask[vessel > 0] = 1\n", + "lung_mask[fissure > 0] = 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "lung_mask = sitk.GetImageFromArray(lung_mask)\n", + "sitk.WriteImage(lung_mask, \"label_map.mhd\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +}