{"cells":[{"metadata":{},"cell_type":"markdown","source":"# <p style=\"text-align:center;\">Hello KAGGLERS</p>\n![](https://cri.utsw.edu/wp-content/uploads/2020/01/Screen-Shot-2020-03-24-at-10.55.38-AM-1024x535.png)\n\n## Contents\n* Loading Image Data\n* Thresholding Images\n* Finding Contours + hierarchical operations\n* Lung segmentation and Masking\n* **3D** Visualizations Techniques\n\n### <<< This is my 1st NOTEBOOK in \"Active competition\" section. >>>\n\n### <span style=\"color:red;\">UPVOTE</span>, if you find this notebook thought-provoking. It will motivate me to write more similar kernels :-)\n\n## <span style=\"color:green;\">Final OUTCOMES</span> (2D+3D Visualizations)....","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Don't worry about this variables, it is just for final output presentation.\nplt.figure(figsize=(40,10))\nplt.imshow(np.hstack([img, img_thr, ed_img, seg_img]), 'gray')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Importing requisite libraries ","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nimport cv2\nimport matplotlib.pyplot as plt\nimport pydicom as dicom\n\nimport os\nfrom tqdm import tqdm","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Loading Image Data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def load_image(path):\n    ds=dicom.dcmread(path)\n    img = ds.pixel_array                                  # Now, img is pixel_array. it is input of our demo code\n                                                          # Convert pixel_array (img) to -> gray image (img_2d_scaled)\n    img_2d = img.astype(float)                            # Step 1. Convert to float to avoid overflow or underflow losses.\n    img = (np.maximum(img_2d,0) / img_2d.max()) * 255.0   # Step 2. Rescaling grey scale between 0-255\n    return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def show_images():\n    f, ax= plt.subplots(2,3, figsize=(32, 15))\n    for i in tqdm(range(6)):\n        path='../input/osic-pulmonary-fibrosis-progression/train/ID00007637202177411956430'\n        img_path=os.path.join(path, str(i+3))\n        img_path=img_path+'.dcm'\n        \n        img= load_image(img_path)\n        ax[i//3][i%3].imshow(img, aspect='auto', cmap='gray')\n        ax[i//3][i%3].set_xticks([]); ax[i//3][i%3].set_yticks([])\n    plt.show()\n\nshow_images()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Thresholding Images","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def show_THR_img():\n    f, ax= plt.subplots(2,3, figsize=(32, 15))\n    for i in tqdm(range(6)):\n        path='../input/osic-pulmonary-fibrosis-progression/train/ID00007637202177411956430'\n        img_path=os.path.join(path, str(i+5))\n        img_path=img_path+'.dcm'\n        \n        img= load_image(img_path)\n        img_thr= cv2.threshold(img.astype('uint8'), 0, 255, cv2.THRESH_OTSU)[1]\n        ax[i//3][i%3].imshow(img_thr, aspect='auto', cmap='gray')\n        ax[i//3][i%3].set_xticks([]); ax[i//3][i%3].set_yticks([])\n    plt.show()\n\nshow_THR_img()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Finding Contours + hierarchical operations","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def find_contour(img_thr, find_max_con=False):\n    contours,hierarchy,=cv2.findContours(img_thr,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)\n    \n    # Max area contour\n    if find_max_con:\n        contours,hierarchy,=cv2.findContours(img_thr,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)\n        max_con= max(contours,key=cv2.contourArea)\n        \n        mask=np.zeros(img_thr.shape)\n        mask= cv2.fillConvexPoly(mask, max_con, 1.0)\n        \n        return img_thr * mask\n    \n    \n    # EXTERNAL CONTOUR\n    ext_contours=np.zeros(img_thr.shape)\n    for i in range(len(contours)):\n        if hierarchy[0][i][3]==-1:  # checking for ext. contour (-1)  else 'specific no' for diff. internal contours \n            cv2.drawContours(ext_contours,contours,i,255,-1)\n    \n    # INTERNAL CONTOUR\n    int_contours=np.zeros(img_thr.shape)\n    for i in range(len(contours)):\n        if hierarchy[0][i][3]!= -1:  # checking for ext. contour (-1)  else internal contour\n            cv2.drawContours(int_contours,contours,i,255,-1)\n    return ext_contours, int_contours","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def show_contour_img():\n    f, ax= plt.subplots(2,3, figsize=(35, 15))\n    for i in tqdm(range(6)):\n        path='../input/osic-pulmonary-fibrosis-progression/train/ID00007637202177411956430'\n        img_path=os.path.join(path, str(i+3))\n        img_path=img_path+'.dcm'\n        \n        img= load_image(img_path)\n        img_thr= cv2.threshold(img.astype('uint8'), 0, 255, cv2.THRESH_OTSU)[1]\n        ex_con, in_con= find_contour(img_thr)\n        ax[i//3][i%3].imshow(np.hstack([ex_con, in_con]), aspect='auto', cmap='gray')\n        ax[i//3][i%3].set_xticks([]); ax[i//3][i%3].set_yticks([])\n    plt.show()\n\nshow_contour_img()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Lung segmentation and Masking","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def seg_lung(org_img, in_contours_img):\n    kernel= cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))\n    \n    clr_noise_img=cv2.morphologyEx(in_contours_img, cv2.MORPH_OPEN, kernel)\n    forg_img= cv2.dilate(clr_noise_img, kernel,iterations = 2)\n    \n    forg_img= cv2.bitwise_not(forg_img.astype('uint8'))\n    return cv2.bitwise_or(org_img.astype('uint8'), forg_img)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### 1st Approach \n#### --->Recommended","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"\ndef show_forgrd_img():\n    f, ax= plt.subplots(2,3, figsize=(35, 15))\n    for i in tqdm(range(6)):\n        path='../input/osic-pulmonary-fibrosis-progression/train/ID00007637202177411956430'\n        img_path=os.path.join(path, str(i+3))\n        img_path=img_path+'.dcm'\n        \n        img= load_image(img_path)\n        img_thr= cv2.threshold(img.astype('uint8'), 0, 255, cv2.THRESH_OTSU)[1]\n        ex_con, in_con= find_contour(img_thr)\n        \n        seg_img= seg_lung(img, in_con)\n        ax[i//3][i%3].imshow(np.hstack([img, seg_img]), aspect='auto', cmap='gray')\n        ax[i//3][i%3].set_xticks([]); ax[i//3][i%3].set_yticks([])\n    plt.show()\n\nshow_forgrd_img()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"path='../input/osic-pulmonary-fibrosis-progression/train/ID00007637202177411956430/13.dcm'\nimg= load_image(path)\nimg_thr= cv2.threshold(img.astype('uint8'), 0, 255, cv2.THRESH_OTSU)[1]\ned_img= cv2.Canny(img_thr, 100, 200)\nex_con, in_con= find_contour(img_thr)\nseg_img= seg_lung(img, in_con)\n\nplt.figure(figsize=(16,7))\nplt.imshow(np.hstack([img, seg_img]), 'gray')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### 2st Approach ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"\ndef show_forgrd_img_extra():\n    f, ax= plt.subplots(2,3, figsize=(35, 15))\n    for i in tqdm(range(6)):\n        path='../input/osic-pulmonary-fibrosis-progression/train/ID00007637202177411956430'\n        img_path=os.path.join(path, str(i+4))\n        img_path=img_path+'.dcm'\n        \n        img= load_image(img_path)\n        img_thr= cv2.threshold(img.astype('uint8'), 0, 255, cv2.THRESH_OTSU)[1]\n        \n        max_con_img= find_contour(img_thr, find_max_con=True)\n        img_thr= cv2.threshold(max_con_img.astype('uint8'), 0, 255, cv2.THRESH_OTSU)[1]\n        \n        ex_con, in_con= find_contour(img_thr)\n        \n        seg_img= seg_lung(img, in_con)\n        ax[i//3][i%3].imshow(np.hstack([img, seg_img]), aspect='auto', cmap='gray')\n        ax[i//3][i%3].set_xticks([]); ax[i//3][i%3].set_yticks([])\n    plt.show()\n\nshow_forgrd_img_extra()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 3D Visualizations Techniques\nThanks to <br>\nhttps://stackoverflow.com/questions/56035562/3d-dicom-visualisation-in-python\n* Bones 3D model\n* Lungs 3D model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from skimage import measure\nfrom mpl_toolkits.mplot3d.art3d import Poly3DCollection","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Stacking images \nimg=[]\npath='../input/osic-pulmonary-fibrosis-progression/train/ID00007637202177411956430/'\nfor i in range(1, 31):\n    path1= path+str(i)+'.dcm'\n    image= cv2.resize(load_image(path1), (250,250))\n    img.append(image)\n    \nprint(len(img))\nbones=np.array(img)\nbones.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_3d(image, title):\n    \n    # Position the scan upright, \n    # so the head of the patient would be at the top facing the   \n    # camera\n    p = image.transpose(2,1,0)\n    \n    verts, faces, _, _ = measure.marching_cubes_lewiner(p)\n    fig = plt.figure(figsize=(10, 10))\n    ax = fig.add_subplot(111, projection='3d')\n    # Fancy indexing: `verts[faces]` to generate a collection of    \n    # triangles\n    mesh = Poly3DCollection(verts[faces], alpha=0.5)\n    face_color = [0.45, 0.45, 0.75]\n    mesh.set_facecolor(face_color)\n    ax.add_collection3d(mesh)\n    ax.set_xlim(0, p.shape[0])\n    ax.set_ylim(0, p.shape[1])\n    ax.set_zlim(0, p.shape[2])\n    ax.set_title(title)\n    plt.show()\n        \n        \n# run visualization \nplot_3d(bones, 'Bones')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def seg(path):\n    img= load_image(path)\n    img_thr= cv2.threshold(img.astype('uint8'), 0, 255, cv2.THRESH_OTSU)[1]\n    ex_con, in_con= find_contour(img_thr)\n    seg_img= seg_lung(img, in_con)\n    return find_contour(seg_img)[1]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Stacking images \nimg=[]\npath='../input/osic-pulmonary-fibrosis-progression/train/ID00007637202177411956430/'\nfor i in tqdm(range(1, 31)):\n    path1= path+str(i)+'.dcm'\n    image= cv2.resize(seg(path1), (250,250))\n    img.append(image)\n    \n\nlung=np.array(img)\nlung.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_3d(lung, 'Lung 3D')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"![](https://i.gifer.com/7ImI.gif)","execution_count":null}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}