{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"! conda install -c conda-forge gdcm -y","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-23T03:21:51.936283Z","iopub.execute_input":"2021-06-23T03:21:51.936689Z","iopub.status.idle":"2021-06-23T03:23:01.039516Z","shell.execute_reply.started":"2021-06-23T03:21:51.936608Z","shell.execute_reply":"2021-06-23T03:23:01.038398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport pydicom\nimport glob\nimport cv2\nimport plotly\nimport ast\n\nimport numpy as np \nimport pandas as pd \nimport matplotlib.patches as patches\nimport plotly.graph_objects as go\nimport plotly.express as px\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\nfrom tqdm.notebook import tqdm\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nfrom skimage import exposure\nfrom matplotlib.colors import ListedColormap\nfrom collections import Counter\nfrom pathlib import Path\nfrom fastai.vision.all import *\nfrom fastai.medical.imaging import *","metadata":{"execution":{"iopub.status.busy":"2021-06-23T03:23:01.041629Z","iopub.execute_input":"2021-06-23T03:23:01.041930Z","iopub.status.idle":"2021-06-23T03:23:06.321696Z","shell.execute_reply.started":"2021-06-23T03:23:01.041897Z","shell.execute_reply":"2021-06-23T03:23:06.320280Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_path = Path('../input/siim-covid19-detection')\ntrain_study_df = pd.read_csv(dataset_path/'train_study_level.csv')\ntrain_study_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-23T03:23:06.324129Z","iopub.execute_input":"2021-06-23T03:23:06.324647Z","iopub.status.idle":"2021-06-23T03:23:06.376290Z","shell.execute_reply.started":"2021-06-23T03:23:06.324592Z","shell.execute_reply":"2021-06-23T03:23:06.375227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"FIG_FONT = dict(family=\"Helvetica, Arial\", size=14, color=\"#7f7f7f\")\nLABEL_LIST = ['negative', 'typical', 'indeterminate', 'atypical']\nLABEL_COLORS = [px.colors.label_rgb(px.colors.convert_to_RGB_255(x)) for x in sns.color_palette(\"Spectral\", 4)]\nstudy_classes = ['Negative for Pneumonia', 'Typical Appearance', 'Indeterminate Appearance', 'Atypical Appearance']","metadata":{"execution":{"iopub.status.busy":"2021-06-23T03:23:06.378010Z","iopub.execute_input":"2021-06-23T03:23:06.378339Z","iopub.status.idle":"2021-06-23T03:23:06.386126Z","shell.execute_reply.started":"2021-06-23T03:23:06.378306Z","shell.execute_reply":"2021-06-23T03:23:06.385052Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = px.bar(x=LABEL_LIST,\n             y=train_study_df[study_classes].values.sum(axis=0),\n             color=LABEL_LIST, \n             opacity=0.7,\n             color_discrete_sequence=LABEL_COLORS,\n             labels={\"y\":\"Counts\", \"x\": \"\"})\nfig.update_layout(legend_title=None, font=FIG_FONT, xaxis_title=\"\",\n                  yaxis_title=\"<b>Counts</b>\")\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-23T03:23:06.387466Z","iopub.execute_input":"2021-06-23T03:23:06.387763Z","iopub.status.idle":"2021-06-23T03:23:07.266761Z","shell.execute_reply.started":"2021-06-23T03:23:06.387736Z","shell.execute_reply":"2021-06-23T03:23:07.265696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_image_df = pd.read_csv(dataset_path/'train_image_level.csv')\ntrain_image_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-23T03:23:07.268103Z","iopub.execute_input":"2021-06-23T03:23:07.268406Z","iopub.status.idle":"2021-06-23T03:23:07.329693Z","shell.execute_reply.started":"2021-06-23T03:23:07.268377Z","shell.execute_reply":"2021-06-23T03:23:07.328731Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bbox = train_image_df['boxes'].apply(lambda x: len(ast.literal_eval(x)) if x == x else 0)\nc = Counter(bbox.values)\nnum_box = [str(i) for i in range(5)]\ncounts = [c[i] for i in range(5)]\nfig = px.bar(x=num_box, y=counts, color=num_box, opacity=0.7,\n             color_discrete_sequence=LABEL_COLORS)\n             # labels={\"y\":\"Counts\", \"x\": \"Number of boxes\"})\nfig.update_layout(legend_title=None, font=FIG_FONT, xaxis_title=\"<b>Number of boxes</b>\",\n                  yaxis_title=\"<b>Counts</b>\")\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-23T03:23:07.331018Z","iopub.execute_input":"2021-06-23T03:23:07.331332Z","iopub.status.idle":"2021-06-23T03:23:07.581879Z","shell.execute_reply.started":"2021-06-23T03:23:07.331302Z","shell.execute_reply":"2021-06-23T03:23:07.580978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def dicom2array(path, voi_lut=True, fix_monochrome=True):\n    dicom = pydicom.read_file(path)\n    # VOI LUT (if available by DICOM device) is used to\n    # transform raw DICOM data to \"human-friendly\" view\n    if voi_lut:\n        data = apply_voi_lut(dicom.pixel_array, dicom)\n    else:\n        data = dicom.pixel_array\n    # depending on this value, X-ray may look inverted - fix that:\n    if fix_monochrome and dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        data = np.amax(data) - data\n    data = data - np.min(data)\n    data = data / np.max(data)\n    data = (data * 255).astype(np.uint8)\n    return data\n        \n    \ndef plot_img(img, size=(7, 7), is_rgb=True, title=\"\", cmap='gray'):\n    plt.figure(figsize=size)\n    plt.imshow(img, cmap=cmap)\n    plt.suptitle(title)\n    plt.show()\n\n\ndef plot_imgs(imgs, cols=4, size=7, is_rgb=True, title=\"\", cmap='gray', img_size=(500,500)):\n    rows = len(imgs)//cols + 1\n    fig = plt.figure(figsize=(cols*size, rows*size))\n    for i, img in enumerate(imgs):\n        if img_size is not None:\n            img = cv2.resize(img, img_size)\n        fig.add_subplot(rows, cols, i+1)\n        plt.imshow(img, cmap=cmap)\n    plt.suptitle(title)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-23T03:23:07.584037Z","iopub.execute_input":"2021-06-23T03:23:07.584354Z","iopub.status.idle":"2021-06-23T03:23:07.595641Z","shell.execute_reply.started":"2021-06-23T03:23:07.584323Z","shell.execute_reply":"2021-06-23T03:23:07.594598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dicom_paths = get_dicom_files(dataset_path/'train')","metadata":{"execution":{"iopub.status.busy":"2021-06-23T03:23:07.596982Z","iopub.execute_input":"2021-06-23T03:23:07.597333Z","iopub.status.idle":"2021-06-23T03:23:34.630586Z","shell.execute_reply.started":"2021-06-23T03:23:07.597301Z","shell.execute_reply":"2021-06-23T03:23:34.629593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"imgs = [dicom2array(path) for path in dicom_paths[:4]]\nplot_imgs(imgs)","metadata":{"execution":{"iopub.status.busy":"2021-06-23T03:23:34.631814Z","iopub.execute_input":"2021-06-23T03:23:34.632111Z","iopub.status.idle":"2021-06-23T03:23:37.923021Z","shell.execute_reply.started":"2021-06-23T03:23:34.632081Z","shell.execute_reply":"2021-06-23T03:23:37.922263Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def image_path(row):\n    study_path = dataset_path/'train'/row.StudyInstanceUID\n    for i in get_dicom_files(study_path):\n        if row.id.split('_')[0] == i.stem: return i \n        \ntrain_image_df['image_path'] = train_image_df.apply(image_path, axis=1)","metadata":{"execution":{"iopub.status.busy":"2021-06-23T03:23:37.924170Z","iopub.execute_input":"2021-06-23T03:23:37.924630Z","iopub.status.idle":"2021-06-23T03:23:45.381461Z","shell.execute_reply.started":"2021-06-23T03:23:37.924586Z","shell.execute_reply":"2021-06-23T03:23:45.380583Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"imgs = []\nimage_paths = train_image_df['image_path'].values\ntrain_image_df['split_label'] = train_image_df.label.apply(lambda x: [x.split()[offs:offs+6] \n                                                                      for offs in range(0, len(x.split()), 6)])\n\n# map label_id to specify color\nthickness = 5\nscale = 5\nrandom.seed(42)\n\nfor i in range(8):\n    image_path = random.choice(image_paths)\n    # print(image_path)\n    img = dicom2array(path=image_path)\n    img = cv2.resize(img, None, fx=1/scale, fy=1/scale)\n    img = np.stack([img, img, img], axis=-1)\n    for i in train_image_df.loc[train_image_df['image_path'] == image_path].split_label.values[0]:\n        if i[0] == 'opacity':\n            img = cv2.rectangle(img,\n                                (int(float(i[2])/scale), int(float(i[3])/scale)),\n                                (int(float(i[4])/scale), int(float(i[5])/scale)),\n                                [255,0,0], thickness)\n    \n    img = cv2.resize(img, (500,500))\n    imgs.append(img)\n    \nplot_imgs(imgs, cmap=None)","metadata":{"execution":{"iopub.status.busy":"2021-06-23T03:30:20.793581Z","iopub.execute_input":"2021-06-23T03:30:20.793978Z","iopub.status.idle":"2021-06-23T03:30:25.682720Z","shell.execute_reply.started":"2021-06-23T03:30:20.793944Z","shell.execute_reply":"2021-06-23T03:30:25.681548Z"},"trusted":true},"execution_count":null,"outputs":[]}]}