{"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":"markdown","source":"`I Tried to Solve this on Google Colab but the dataset size was beyond available disk space`\n\n# My biggest mistake was that I did not figure out the model I will be using for Object detection as my dataset and inputs will be prepared accordingly.\n\nHere I've decided to go ahead with SSD ","metadata":{}},{"cell_type":"markdown","source":"## 1. Problem Statement:\nIdentify and localize COVID-19 abnormalities on chest radiographs.\n\n\n* Brief:\nFive times more deadly than the flu, COVID-19 causes significant morbidity and mortality. Like other pneumonias, pulmonary infection with COVID-19 results in inflammation and fluid in the lungs. COVID-19 looks very similar to other viral and bacterial pneumonias on chest radiographs, which makes it difficult to diagnose. Your computer vision model to detect and localize COVID-19 would help doctors provide a quick and confident diagnosis. As a result, patients could get the right treatment before the most severe effects of the virus take hold.\n\n## 2. Evaluation:\nThe challenge uses the standard PASCAL VOC 2010 mean Average Precision (mAP) at IoU > 0.5. Note that the linked document describes VOC 2012, which differs in some minor ways (e.g. there is no concept of \"difficult\" classes in VOC 2010). The P/R curve and AP calculations remain the same.\n\nIn this competition, we are making predictions at both a study (multi-image) and image level.\n\n## 3. Data Description\n\nDataset information\nThe train dataset comprises 6,334 chest scans in DICOM format, which were de-identified to protect patient privacy. All images were labeled by a panel of experienced radiologists for the presence of opacities as well as overall appearance.\n\nNote that all images are stored in paths with the form study/series/image. The study ID here relates directly to the study-level predictions, and the image ID is the ID used for image-level predictions.\n\nThe hidden test dataset is of roughly the same scale as the training dataset.\n\nColumns\ntrain_study_level.csv\n\n* id - unique study identifier\n* Negative for Pneumonia - 1 if the study is negative for pneumonia, 0 otherwise\n* Typical Appearance - 1 if the study has this appearance, 0 otherwise\n* Indeterminate Appearance  - 1 if the study has this appearance, 0 otherwise\n* Atypical Appearance  - 1 if the study has this appearance, 0 otherwise\n\n\ntrain_image_level.csv\n\n* id - unique image identifier\n* boxes - bounding boxes in easily-readable dictionary format\n* label - the correct prediction label for the provided bounding boxes\n","metadata":{}},{"cell_type":"markdown","source":"## Lets Start by importing basic libraries & the dataset\n\n","metadata":{}},{"cell_type":"code","source":"# Installing dcm library to read Dicom Images\n!pip install python-gdcm\nprint(\"Installation Complete\")\n!pip install tensorflow-io\nprint(\" TF - io Installed Successfully\")","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:47:52.054874Z","iopub.execute_input":"2021-08-09T14:47:52.055309Z","iopub.status.idle":"2021-08-09T14:48:05.662886Z","shell.execute_reply.started":"2021-08-09T14:47:52.055210Z","shell.execute_reply":"2021-08-09T14:48:05.661953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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)\nimport ast #helps to process trees of the Python abstract syntax grammar.\nimport pydicom # for working with DICOM files such as medical images, reports, and radiotherapy objects.\nimport matplotlib.pyplot as plt\n%matplotlib inline\nimport PIL # Python Imaging Library\nfrom PIL import Image, ImageDraw, ImageFont #Python Imaging Library\nimport tensorflow as tf\n\nimport tensorflow_hub as hub\nimport wandb # experiment tracking, dataset versioning, and model management\nimport seaborn as sns\nimport tqdm # visualise progress\nimport cv2 #convert dicom to png\n\n\n","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:05.664620Z","iopub.execute_input":"2021-08-09T14:48:05.664973Z","iopub.status.idle":"2021-08-09T14:48:08.201374Z","shell.execute_reply.started":"2021-08-09T14:48:05.664932Z","shell.execute_reply":"2021-08-09T14:48:08.200245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Importing the training files names\nt_image_fnames = []\npath = \"/kaggle/input/siim-covid19-detection/train/\"\nimport os\nlen(os.listdir(path))\nfor root, dirs, filenames in os.walk(path):\n    for fname in filenames:\n        t_image_fnames.append(os.path.join(root,fname))\n\ntrain_image_level = pd.read_csv(\"/kaggle/input/siim-covid19-detection/train_image_level.csv\")\ntrain_study_level = pd.read_csv(\"/kaggle/input/siim-covid19-detection/train_study_level.csv\")    \nlen(t_image_fnames)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:09.373738Z","iopub.execute_input":"2021-08-09T14:48:09.374063Z","iopub.status.idle":"2021-08-09T14:48:18.190476Z","shell.execute_reply.started":"2021-08-09T14:48:09.374030Z","shell.execute_reply":"2021-08-09T14:48:18.189691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Importing the training files names\ntest_image_fnames = []\npath1 = \"/kaggle/input/siim-covid19-detection/test/\"\nimport os\nprint(len(os.listdir(path1)))\nfor root, b, filenames in os.walk(path1):\n    for fname in filenames:\n        test_image_fnames.append(os.path.join(root,fname))\nlen(test_image_fnames)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:18.191904Z","iopub.execute_input":"2021-08-09T14:48:18.192239Z","iopub.status.idle":"2021-08-09T14:48:19.993822Z","shell.execute_reply.started":"2021-08-09T14:48:18.192203Z","shell.execute_reply":"2021-08-09T14:48:19.993030Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Crosschecking that the number of image file paths is same as the number of image IDs\nif len(train_image_level.id) == len(t_image_fnames):\n    print(\"length is almost the same\")\n    \nelse:\n    print(\"holy moly\")\n    \ntrain_image_level.head()","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:19.995558Z","iopub.execute_input":"2021-08-09T14:48:19.995923Z","iopub.status.idle":"2021-08-09T14:48:20.013015Z","shell.execute_reply.started":"2021-08-09T14:48:19.995886Z","shell.execute_reply":"2021-08-09T14:48:20.011821Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Check for any missing data","metadata":{}},{"cell_type":"code","source":"train_image_level.isnull().sum()\n","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:20.014662Z","iopub.execute_input":"2021-08-09T14:48:20.015025Z","iopub.status.idle":"2021-08-09T14:48:20.025445Z","shell.execute_reply.started":"2021-08-09T14:48:20.014988Z","shell.execute_reply":"2021-08-09T14:48:20.024454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_study_level.isnull().sum()","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:20.026874Z","iopub.execute_input":"2021-08-09T14:48:20.027420Z","iopub.status.idle":"2021-08-09T14:48:20.038450Z","shell.execute_reply.started":"2021-08-09T14:48:20.027381Z","shell.execute_reply":"2021-08-09T14:48:20.037458Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Since boundary box is missing in some of the images... that means there is no abnormality in those cases","metadata":{}},{"cell_type":"code","source":"print(\"There are \",train_image_level.StudyInstanceUID.duplicated().sum(),\" Images that refer to duplicated study IDs\")","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:20.039852Z","iopub.execute_input":"2021-08-09T14:48:20.040187Z","iopub.status.idle":"2021-08-09T14:48:20.046948Z","shell.execute_reply.started":"2021-08-09T14:48:20.040153Z","shell.execute_reply":"2021-08-09T14:48:20.046081Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X = t_image_fnames\ny = train_image_level[\"label\"]\n","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:20.048385Z","iopub.execute_input":"2021-08-09T14:48:20.049033Z","iopub.status.idle":"2021-08-09T14:48:20.054639Z","shell.execute_reply.started":"2021-08-09T14:48:20.048997Z","shell.execute_reply":"2021-08-09T14:48:20.053743Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nimport pydicom\n%matplotlib inline\nplt.figure(figsize = (10,8))\nimage = pydicom.dcmread(X[21])\nplt.imshow(image.pixel_array,cmap=plt.cm.bone)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:20.057141Z","iopub.execute_input":"2021-08-09T14:48:20.057735Z","iopub.status.idle":"2021-08-09T14:48:21.476044Z","shell.execute_reply.started":"2021-08-09T14:48:20.057698Z","shell.execute_reply":"2021-08-09T14:48:21.475186Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Function to Display 25 Images\ndef show_25_images(images):\n    \"\"\"\n    Displays a plot of 25 images and their labes for training images\n    \"\"\"\n    \n    # setup the figure\n    plt.figure(figsize = (10,10))\n    \n    # loop through 25 files to display 25 images\n    for i in range(25):\n        # Create subplots ( 5 rows , 5 columns)\n        ax = plt.subplot(5,5,i+1)\n        # display an image\n        image = pydicom.dcmread(images[i])\n        plt.imshow(image.pixel_array,cmap = plt.cm.bone)\n        plt.axis(\"off\")","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:21.477243Z","iopub.execute_input":"2021-08-09T14:48:21.477629Z","iopub.status.idle":"2021-08-09T14:48:21.484583Z","shell.execute_reply.started":"2021-08-09T14:48:21.477593Z","shell.execute_reply":"2021-08-09T14:48:21.483787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_25_images(X[20:])","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:21.486008Z","iopub.execute_input":"2021-08-09T14:48:21.486620Z","iopub.status.idle":"2021-08-09T14:48:35.960465Z","shell.execute_reply.started":"2021-08-09T14:48:21.486582Z","shell.execute_reply":"2021-08-09T14:48:35.958814Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import ast\nboxes = ast.literal_eval(train_image_level.loc[3,'boxes'])\nboxes","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:35.962021Z","iopub.execute_input":"2021-08-09T14:48:35.962497Z","iopub.status.idle":"2021-08-09T14:48:35.980411Z","shell.execute_reply.started":"2021-08-09T14:48:35.962458Z","shell.execute_reply":"2021-08-09T14:48:35.975513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Function to display 9 images with boundary boxes if present\n","metadata":{}},{"cell_type":"code","source":"def display_image_and_box(image):\n    \"\"\"\n    Takes image number as input\n    \"\"\"\n    import matplotlib\n    fig, axs = plt.subplots(3,3,figsize = (20,16))\n    fig.subplots_adjust(hspace = .1 , wspace = .1)\n    axs = axs.ravel()\n    row = image\n    i=0\n    for row in range(row,row+9):\n        study = train_image_level.loc[row, 'StudyInstanceUID']\n        dt_file =pydicom.dcmread( X[row])\n        img = dt_file.pixel_array\n        if(train_image_level.loc[row,'boxes']!= train_image_level.loc[row,'boxes']) == False:\n            boxes = ast.literal_eval(train_image_level.loc[row,'boxes'])\n        \n            for box in boxes:\n                p = matplotlib.patches.Rectangle((box['x'],box['y']), box['width'], box['height'],\n                                           ec = 'r',fc = 'none', lw = 2.)\n                axs[i].add_patch(p)\n        axs[i].imshow(img,cmap = plt.cm.bone)\n        axs[i].set_title(train_image_level.loc[row,'label'].split(' ')[0])\n        axs[i].set_xticklabels([])\n        axs[i].set_yticklabels([])\n        i+=1","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:35.982373Z","iopub.execute_input":"2021-08-09T14:48:35.982720Z","iopub.status.idle":"2021-08-09T14:48:35.999755Z","shell.execute_reply.started":"2021-08-09T14:48:35.982686Z","shell.execute_reply":"2021-08-09T14:48:35.998841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"display_image_and_box(19)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:36.004555Z","iopub.execute_input":"2021-08-09T14:48:36.004909Z","iopub.status.idle":"2021-08-09T14:48:48.373145Z","shell.execute_reply.started":"2021-08-09T14:48:36.004875Z","shell.execute_reply":"2021-08-09T14:48:48.372375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Extract Metadata for all the images into a seprate DataFrame**","metadata":{}},{"cell_type":"code","source":"from pydicom import dcmread, read_file\nfrom pydicom.tag import Tag\nfrom tqdm import tqdm\npvt_creator1 = Tag(0x2001, 0x10) #Private Creator 1\npvt_creator2 = Tag(0x0903, 0x10) #Private Creator 1\n\ncolumns = [ 'StudyID',\n 'StudyInstanceUID',\n 'PatientSex', \n 'BitsAllocated',\n 'BitsStored',\n 'Columns',\n 'Rows',\n 'BodyPartExamined', \n 'HighBit', \n 'ImageType',\n 'ImagerPixelSpacing',\n 'InstanceNumber',\n 'Modality',\n 'PatientID',\n 'PatientName',\n 'AccessionNumber',\n 'DeidentificationMethod',\n #'DeidentificationMethodCodeSequence',\n 'PhotometricInterpretation',\n 'PixelRepresentation',\n 'SOPClassUID',\n 'SOPInstanceUID',\n 'SamplesPerPixel',\n 'SeriesInstanceUID',\n 'SeriesNumber',\n 'SpecificCharacterSet',\n 'StudyDate',\n 'StudyTime',\n 'PrivateCreator1',\n 'PrivateCreator2']\n\ndef extract_metadata(columns, files):\n    df = pd.DataFrame(columns=columns)\n    for num, file in tqdm(enumerate(files)):\n        row = {}\n        dicom_img = read_file(file, stop_before_pixels=True)\n        for col in columns:\n            if col not in ['PrivateCreator1', 'PrivateCreator2']:\n                row[col] = dicom_img[col].value\n        try:        \n            row['PrivateCreator1'] = dicom_img.get_item(pvt_creator1).value\n            row['PrivateCreator2'] = dicom_img.get_item(pvt_creator2).value    \n        except AttributeError:\n            pass\n        df = df.append(row,ignore_index=True)\n    return df","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:48.374404Z","iopub.execute_input":"2021-08-09T14:48:48.374855Z","iopub.status.idle":"2021-08-09T14:48:48.386623Z","shell.execute_reply.started":"2021-08-09T14:48:48.374817Z","shell.execute_reply":"2021-08-09T14:48:48.385787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#train_df = extract_metadata(columns,X)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:48.387726Z","iopub.execute_input":"2021-08-09T14:48:48.388162Z","iopub.status.idle":"2021-08-09T14:48:48.399949Z","shell.execute_reply.started":"2021-08-09T14:48:48.388126Z","shell.execute_reply":"2021-08-09T14:48:48.398399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#train_df.head().T","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:48.401123Z","iopub.execute_input":"2021-08-09T14:48:48.401424Z","iopub.status.idle":"2021-08-09T14:48:48.408323Z","shell.execute_reply.started":"2021-08-09T14:48:48.401392Z","shell.execute_reply":"2021-08-09T14:48:48.407284Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#test_df = extract_metadata(columns,test_image_fnames)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:48.409924Z","iopub.execute_input":"2021-08-09T14:48:48.410533Z","iopub.status.idle":"2021-08-09T14:48:48.416786Z","shell.execute_reply.started":"2021-08-09T14:48:48.410496Z","shell.execute_reply":"2021-08-09T14:48:48.415659Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"\ntrain_df['Rows'] = train_df['Rows'].astype(int)\ntrain_df['Columns'] = train_df['Columns'].astype(int)\ntest_df['Rows'] = test_df['Rows'].astype(int)\ntest_df['Columns'] = test_df['Columns'].astype(int)\ntrain_df.to_csv('train_imgs_meta.csv', index=None)\ntest_df.to_csv('test_imgs_meta.csv', index=None)\n\n\"\"\"","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:48.419497Z","iopub.execute_input":"2021-08-09T14:48:48.419864Z","iopub.status.idle":"2021-08-09T14:48:48.427406Z","shell.execute_reply.started":"2021-08-09T14:48:48.419815Z","shell.execute_reply":"2021-08-09T14:48:48.426411Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Convert the Dicom files to png of custom size for model input\n\n","metadata":{"execution":{"iopub.status.busy":"2021-08-09T12:42:23.71988Z","iopub.execute_input":"2021-08-09T12:42:23.720333Z","iopub.status.idle":"2021-08-09T12:42:23.725331Z","shell.execute_reply.started":"2021-08-09T12:42:23.720239Z","shell.execute_reply":"2021-08-09T12:42:23.72421Z"}}},{"cell_type":"code","source":"\n# Importing the training files names\ns = []\ndcm = \".dcm\"\npath = \"/kaggle/input/siim-covid19-detection/train/\"\nimport os\n#print(len(os.listdir(path)))\nfor root, dirs, filenames in os.walk(path):\n    for fname in filenames:\n        s.append(os.path.join(root,fname))\n\n\n\nss = [x.replace('/kaggle/input/siim-covid19-detection/train/','') for x in s]\nss[:10]","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:48.429106Z","iopub.execute_input":"2021-08-09T14:48:48.429482Z","iopub.status.idle":"2021-08-09T14:48:53.045219Z","shell.execute_reply.started":"2021-08-09T14:48:48.429446Z","shell.execute_reply":"2021-08-09T14:48:53.044446Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\"\"\"outdir = \"./custompng/train\"\n#os.mkdir(outdir)\n\n\n\nfor f in X[:10]:   # remove \"[:10]\" to convert all images \n    \n    ds = pydicom.read_file(f) # read dicom image\n    img = ds.pixel_array # get image array\n    print(f)\n    cv2.imwrite(outdir + f.replace('.dcm','.png'),img) # write png image\n    \n    \n    \"\"\"\n\n","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:53.047897Z","iopub.execute_input":"2021-08-09T14:48:53.048144Z","iopub.status.idle":"2021-08-09T14:48:53.056230Z","shell.execute_reply.started":"2021-08-09T14:48:53.048118Z","shell.execute_reply":"2021-08-09T14:48:53.055460Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\nimport os\nimport pydicom\n\ninputdir = '../input/siim-covid19-detection/train/'\noutdir = './custompng/train'\n#os.mkdir(outdir)\n\ntest_list = [ f for f in  os.listdir(inputdir)]\ni=0\nfor f in tqdm(X):   # remove \"[:10]\" to convert all images \n    \n    ds = pydicom.read_file(inputdir + ss[i]) # read dicom image\n    img = ds.pixel_array # get image array\n    cv2.imwrite(outdir + ss[i].replace('.dcm','.png'),img)\n    i+=1\n    \n    \nprint(i)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:48:53.057711Z","iopub.execute_input":"2021-08-09T14:48:53.058114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}