{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Importing all modules"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import PIL\nfrom PIL import Image\nfrom PIL import ImageFont\nfrom PIL import ImageColor\nfrom PIL import ImageDraw\nfrom PIL import ImageOps\n\nfrom pathlib import Path\nimport numpy as np \nimport pandas as pd\nimport cv2\nimport seaborn as sns\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\n%matplotlib inline\nplt.style.use('ggplot')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Just to see what file is available is the directory\n# fastai has more detailed implementation of ls\nPath.ls = lambda x: list(x.iterdir())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"path = Path(r'/kaggle/input/vinbigdata-chest-xray-abnormalities-detection')\ntrain_dir = Path(path/'train')\ntest_dir = Path(path/'test')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Investigating `train_df`"},{"metadata":{"trusted":true},"cell_type":"code","source":"len(train_dir.ls()), len(test_dir.ls())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv(path/'train.csv')\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['class_name'].value_counts().plot.barh()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Without No finding column total number of examples in training data set"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.loc[train_df['class_name'] != 'No finding','class_name'].value_counts().plot.barh()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_images_number = 2\nrandom_images = np.random.choice(train_dir.ls(), test_images_number)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Reading pydicom image and converting them three channel PIL image"},{"metadata":{"trusted":true},"cell_type":"code","source":"import pydicom\nfrom pydicom import dcmread","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ds = dcmread(random_images[0])\nds","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ds.PatientSex","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_size = ((ds.Rows),(ds.Columns))\nimage_size","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Code also taken from [this Notebook](https://www.kaggle.com/bjoernholzhauer/eda-dicom-reading-vinbigdata-chest-x-ray) and also combines code from \n[here](https://github.com/vinbigdata-medical/vindr-cxr/blob/main/outlier-detection/transforms.py)"},{"metadata":{"trusted":true},"cell_type":"code","source":"def from_dicom_to_3_channel_numpy(file_name):\n    \"\"\"\n    convert dicoḿ file to 3 channel numpy array \n    and also human readable format\n    \n    file_name = name of the dicom file\n    \n    3 images will be plotted as an output\n    first image = after reading dicom files\n    second image = after converting to human readable format \n    last image = three channel image\n    \n    image : return 3 channel image\n    \"\"\"\n    dcm_file = pydicom.dcmread(file_name)\n  \n    if dcm_file.BitsStored in (10, 12):\n        dcm_file.BitsStored = 14\n    \n    raw_image = dcm_file.pixel_array\n    raw_image = pydicom.pixel_data_handlers.util.apply_voi_lut(raw_image , dcm_file)\n\n    # Normalize pixel to be in [0, 255]\n    rescaled_image = cv2.convertScaleAbs(raw_image,\n                                         alpha=(255.0/raw_image.max()))\n    # Correct image inversion\n    if dcm_file.PhotometricInterpretation == \"MONOCHROME1\":\n        rescaled_image = cv2.bitwise_not(rescaled_image)\n    \n    # Perform histogram equalization if the input is \n    # original dicom file\n\n    if raw_image.max() > 255:\n        adjusted_image = cv2.equalizeHist(rescaled_image)\n    else:\n        adjusted_image = rescaled_image\n\n    image = Image.fromarray(adjusted_image)\n    image = image.convert('RGB')\n    \n    \n    # plotting all 3 main converions done in this function\n    plt.figure(figsize=(18, 5))\n    \n    plt.subplot(1,3,1)\n    plt.imshow(raw_image, cmap='gray', label='dicom file')\n    plt.axis('off')\n    plt.subplot(1,3,2)\n    plt.imshow(rescaled_image, cmap='gray', label = 'human readable')\n    plt.axis('off')\n    plt.subplot(1,3,3)\n    plt.imshow(image, cmap='gray', label = 'Three channel')\n   \n    plt.axis('off')\n    plt.subplots_adjust()\n    plt.legend()\n    return image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image = from_dicom_to_3_channel_numpy(file_name = random_images[1])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# let me try bounding box plotting\n"},{"metadata":{},"cell_type":"markdown","source":"As No finding have no bounding box therefore removing no founding "},{"metadata":{"trusted":true},"cell_type":"code","source":"classified_df = train_df.loc[train_df['class_name'] != 'No finding',:]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"classified_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"total_images_available = list(set(classified_df['image_id']))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## How much bounding box availble per image"},{"metadata":{"trusted":true},"cell_type":"code","source":"# only see how much unique image and total image availble\nlen(total_images_available),classified_df.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bbox_per_image = {grp:data.shape[0] for  grp, data in classified_df.groupby('image_id')}\n \n    \nprint(f'Maximum box number per image  = {np.max(list(bbox_per_image.values()))},\\nMinimum box number= {np.min(list(bbox_per_image.values()))}, \\nAverage box number  {np.round(np.average(list(bbox_per_image.values())))}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(list(bbox_per_image.values()))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Now plotting a sample which has relative smaller bounding box"},{"metadata":{},"cell_type":"markdown","source":"our previous function plot 3 images. that was only for observation. We \nactually need a  function which just return the pil image. `dicom_to_pil` is the same fuction as previous.\nJust without the plotting the image"},{"metadata":{"trusted":true},"cell_type":"code","source":"def dicom_to_pil(file_name):\n    \"\"\"\n    convert dicoḿ file to 3 channel numpy array \n    and also human readable format\n    \n    file_name = name of the dicom file \n    image : return 3 channel image\n    \"\"\"\n    dcm_file = pydicom.dcmread(file_name)\n  \n    if dcm_file.BitsStored in (10, 12):\n        dcm_file.BitsStored = 16\n    \n    raw_image = dcm_file.pixel_array\n    raw_image = pydicom.pixel_data_handlers.util.apply_voi_lut(raw_image , dcm_file)\n\n    # Normalize pixel to be in [0, 255]\n    rescaled_image = cv2.convertScaleAbs(raw_image,\n                                         alpha=(255.0/raw_image.max()))\n    # Correct image inversion\n    if dcm_file.PhotometricInterpretation == \"MONOCHROME1\":\n        rescaled_image = cv2.bitwise_not(rescaled_image)\n    \n    # Perform histogram equalization if the input is \n    # original dicom file\n\n    if raw_image.max() > 255:\n        adjusted_image = cv2.equalizeHist(rescaled_image)\n    else:\n        adjusted_image = rescaled_image\n\n    image = Image.fromarray(adjusted_image)\n    image = image.convert('RGB')\n    return image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample = '9a5094b2563a1ef3ff50dc5c7ff71345'\nsample_box = classified_df.loc[classified_df['image_id'] == sample, :]\nsample_box","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"base_file = train_dir\nfile_name = f'{base_file}/{sample}.dicom'\nimage = dicom_to_pil(file_name)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# let me see the image first\nplt.figure(figsize=(18, 5))\nplt.imshow(image)\nplt.axis('off');","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Now bounding box "},{"metadata":{},"cell_type":"markdown","source":"I recently completer one coursera online course [Advanced Computer vision with tensorflow](https://www.coursera.org/learn/advanced-computer-vision-with-tensorflow/home/welcome), where a nice utility function was available, where if you give bounding box and image it will create \nbounding box. There are different other nice function was availble. One can easily look at the course"},{"metadata":{"trusted":true},"cell_type":"code","source":"def draw_bounding_box_on_image(image,\n                               ymin,\n                               xmin,\n                               ymax,\n                               xmax,\n                               color='red',\n                               thickness=1,\n                               display_str=[],\n                               use_normalized_coordinates=True):\n    \"\"\"\n    Adds a bounding box to an image.\n    Bounding box coordinates can be specified in either absolute (pixel) or\n    normalized coordinates by setting the use_normalized_coordinates argument.\n    Args:\n        image: a PIL.Image object.\n        ymin: ymin of bounding box.\n        xmin: xmin of bounding box.\n        ymax: ymax of bounding box.\n        xmax: xmax of bounding box.\n        color: color to draw bounding box. Default is red.\n        thickness: line thickness. Default value is 4.\n        display_str_list: string to display in box\n        use_normalized_coordinates: If True (default), treat coordinates\n          ymin, xmin, ymax, xmax as relative to the image.  Otherwise treat\n    coordinates as absolute.\n    \"\"\"\n    draw = PIL.ImageDraw.Draw(image)\n    im_width, im_height = image.size\n    if use_normalized_coordinates:\n        (left, right, top, bottom) = (xmin*im_width, xmax*im_width, ymin*im_height, ymax*im_height)\n    else:\n        (left, right, top, bottom) = (xmin, xmax, ymin, ymax)\n    draw.line([(left, top), (left, bottom), (right, bottom),\n             (right, top), (left, top)], width=thickness, fill=color)\n    \n    \n    if len(display_str) >= 1:\n        try:\n            font = ImageFont.truetype(\"/usr/share/fonts/truetype/liberation/LiberationSansNarrow-Regular.ttf\",\n                                  50)\n        except IOError:\n            print(\"Font not found, using default font.\")\n            font = ImageFont.load_default()\n\n\n        # If the total height of the display strings added to the top of the bounding\n        # box exceeds the top of the image, stack the strings below the bounding box\n        # instead of above.\n        display_str_heights = [font.getsize(ds)[1] for ds in display_str]\n        # Each display_str has a top and bottom margin of 0.05x.\n        total_display_str_height = (1 + 2 * 0.05) * sum(display_str_heights)\n\n        if top > total_display_str_height:\n            text_bottom = top\n        else:\n            text_bottom = top + total_display_str_height\n\n        text_width, text_height = font.getsize(display_str[0])\n        margin = np.ceil(0.05 * text_height)\n        draw.rectangle([(left, text_bottom - text_height - 2 * margin),\n                        (left + text_width, text_bottom)],\n                       fill=color)\n        draw.text((left + margin, text_bottom - text_height - margin),\n                  display_str[0],\n                  fill=\"black\",\n                  font=font)\n        text_bottom -= text_height - 2 * margin\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def bounding_boxes_in_pil_image(sample):\n    \"\"\"\n    \n    \"\"\"\n    \n    sample_box = classified_df.loc[classified_df['image_id'] == sample, :]\n    base_file = train_dir\n    file_name = f'{base_file}/{sample}.dicom'\n    image = dicom_to_pil(file_name)\n    image_pil = (image)\n    rgbimg = PIL.Image.new(\"RGBA\", image_pil.size)\n    rgbimg.paste(image_pil)\n    for i in sample_box.index:\n    # creating bounding box for each row\n        x_min, y_min, x_max, y_max = sample_box.loc[i, ['x_min','y_min','x_max', 'y_max']]\n        draw_bounding_box_on_image(image=rgbimg,\n                          ymin=y_min,\n                          xmin=x_min,\n                          ymax=y_max,\n                          xmax=x_max,\n                          color='red',\n                          thickness=10,\n                          use_normalized_coordinates=False)\n    image_bbox = np.array(rgbimg)\n    plt.figure(figsize=(18, 12))\n    plt.imshow(image_bbox)\n    plt.axis('off')\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bounding_boxes_in_pil_image(sample)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## let's plot extreme boxes. At first we need to search for the sample has 57 boxes"},{"metadata":{"trusted":true},"cell_type":"code","source":"{key for key, value in bbox_per_image.items() if value == 57}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"new_sample = '03e6ecfa6f6fb33dfeac6ca4f9b459c9'\nbounding_boxes_in_pil_image(new_sample)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Why so much bounding boxes\n - different detectors so diffrent places\n - it has different problems that's why so much boxes\n\nFirst case ís availble it is sure. Let me see whether second case is availble \nWe need to change the colours. At first based on problems and then different doctors\n"},{"metadata":{},"cell_type":"markdown","source":"### first define colors for the Radiologist\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"# I want sort the radiologist. Therefore sorted function key\n# would be then the number and `func_name` just search for it \nfunc_name = lambda x: int(x[1:])\n\n# we have a sorted list for Radiologist now\nall_radiologist_list = sorted(list(set(classified_df['rad_id'])), key= func_name)\n\n# searching for the color palltte from seaborn and \n# colors will be the number of total radiologist\ncolors = sns.color_palette(None, len(all_radiologist_list))\n\n# creating a dictionary where key will be radiologist and \n# value will be the color\nrediologist_color_map = {key: color for key, color in zip(all_radiologist_list, colors)}\ncolors\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We need to change the function where we create the bounding in a sample image"},{"metadata":{"trusted":true},"cell_type":"code","source":"def bounding_boxes_in_pil_image(sample:str,\n                               color_map=rediologist_color_map,\n                               maping='rad_id'):\n    \"\"\"\n    creating a bounding box in the image \n    sample: image id \n    color_map : a dictionary key is the color group e.g. Radiologist, value is the \n    color name \n    maping:str: which coloumn needs to be mapped in case of radiologist it is rad_id\n    \"\"\"\n    \n    sample_box = classified_df.loc[classified_df['image_id'] == sample, :]\n    base_file = train_dir\n    file_name = f'{base_file}/{sample}.dicom'\n    image = dicom_to_pil(file_name)\n    image_pil = (image)\n    rgbimg = PIL.Image.new(\"RGBA\", image_pil.size)\n    rgbimg.paste(image_pil)\n    for i in sample_box.index:\n    # creating bounding box for each row\n        x_min, y_min, x_max, y_max = sample_box.loc[i, ['x_min','y_min','x_max', 'y_max']]\n        class_clr = sample_box.loc[i, maping]\n        clr_id = color_map[sample_box.loc[i, maping]]\n   \n        color = int(clr_id[0]*255), int(clr_id[1]*255), int(clr_id[2]*255)\n\n        draw_bounding_box_on_image(image=rgbimg,\n                          ymin=y_min,\n                          xmin=x_min,\n                          ymax=y_max,\n                          xmax=x_max,\n                          color=color,\n                          thickness=10,\n                          display_str = [class_clr],\n                          use_normalized_coordinates=False)\n    image_bbox = np.array(rgbimg)\n    \n\n  \n    \n    plt.figure(figsize=(18, 12))\n    plt.imshow(image_bbox)\n    plt.axis('off')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"{key for key, value in bbox_per_image.items() if value == 57}\nnew_sample = '03e6ecfa6f6fb33dfeac6ca4f9b459c9'\nbounding_boxes_in_pil_image(new_sample)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Now we need to see for each class "},{"metadata":{"trusted":true},"cell_type":"code","source":"class_name_list = sorted(list(set(classified_df['class_name'])))\n\nclass_name_color = sns.color_palette(None, len(class_name_list))\nclass_name_color_map = {key: color for key, color in zip(class_name_list, class_name_color)}\nclass_name_color","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bounding_boxes_in_pil_image(new_sample,  color_map=class_name_color_map,\n                               maping='class_name')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Box Fusion"},{"metadata":{},"cell_type":"markdown","source":"Normally to to remmove overlapping area one technique called `Non-max Supression`. [here](https://paperswithcode.com/method/non-maximum-suppression) is nice explanation"},{"metadata":{"trusted":true},"cell_type":"markdown","source":"- We will go through all the images \n  - if more than one radiologist is avilable we will see iou accuracy \n  - if more than a threshold then may be same area so we need to somehow take only one not three\n      - need to take one base box don't know may be see the data\n      \n"},{"metadata":{"trusted":true},"cell_type":"code","source":"new_sample = '011244ab511b20130d846f5f8f0c3866'\nbounding_boxes_in_pil_image(new_sample,\n                            color_map = rediologist_color_map,\n                            maping='rad_id')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"After analysis I have found that each image consists of Three radiologist bounding box.\n- If each radiologist has only one box then I will take the bounding box which covers all radiologist area\n- If one radioligist has more bounding box then the radiologist who has more bounding boxes will only be chosen and others will be removed"},{"metadata":{},"cell_type":"markdown","source":"First start simple. look only the images which has only three bounding boxes, means one bounding box per radiologist"},{"metadata":{"trusted":true},"cell_type":"code","source":"simple_image_id = [grp for grp, data in classified_df.groupby('image_id') if len(data) == 3]\nlen(simple_image_id)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We have 370 images which has only one box per radiologist\n"},{"metadata":{},"cell_type":"markdown","source":"let's try to see the image"},{"metadata":{"trusted":true},"cell_type":"code","source":"def fused_box_in_image(sample,x_min,\n                      y_min, x_max, \n                      y_max,color_map=rediologist_color_map,\n                      maping='rad_id', all=True):\n    \"\"\"\n    sample: sample image id\n    x_min: combined box x_min\n    y_min: combined box y_min\n    x_max: combined box x_max\n    x_min: combined box y_min\n    color_map : a color maping of seaborn based on number of unique instance:\n    here it is number of radiologist\n    \n    maping: which column will be mapped based on color maping\n    \n    2 Column image first one will be combined bounding box \n    second one will be with both combined image and all radiologist detection\n    \"\"\"\n    \n    sample_box = classified_df.loc[classified_df['image_id'] == sample, :]\n    base_file = train_dir\n    file_name = f'{base_file}/{sample}.dicom'\n    image = dicom_to_pil(file_name)\n    image_pil = (image)\n    rgbimg = PIL.Image.new(\"RGBA\", image_pil.size)\n    \n    rgbimg.paste(image_pil)\n    plt.figure(figsize=(18, 12))\n    plt.subplot(121)\n    \n    draw_bounding_box_on_image(image=rgbimg,\n                          ymin=y_min,\n                          xmin=x_min,\n                          ymax=y_max,\n                          xmax=x_max,\n                          color='red',\n                          thickness=10,\n                          display_str = ['combined box'],\n                          use_normalized_coordinates=False)\n    plt.imshow(np.array(rgbimg))\n    plt.axis('off')\n    if all:\n        for i in sample_box.index:\n        # creating bounding box for each row\n            x_min, y_min, x_max, y_max = sample_box.loc[i, ['x_min','y_min','x_max', 'y_max']]\n            class_clr = sample_box.loc[i, maping]\n            clr_id = color_map[sample_box.loc[i, maping]]\n\n            color = int(clr_id[0]*255), int(clr_id[1]*255), int(clr_id[2]*255)\n\n            draw_bounding_box_on_image(image=rgbimg,\n                              ymin=y_min,\n                              xmin=x_min,\n                              ymax=y_max,\n                              xmax=x_max,\n                              color=color,\n                              thickness=10,\n                              display_str = [class_clr],\n                              use_normalized_coordinates=False)\n    image_bbox = np.array(rgbimg)\n    plt.subplot(122)\n    plt.imshow(image_bbox)\n    plt.axis('off')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_df = classified_df.loc[classified_df['image_id'] == simple_image_id[0],:]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x_min_n, y_min_n, x_max_n, y_max_n = np.min(sample_df['x_min']),np.min(sample_df['y_min']),np.max(sample_df['x_max']),np.max(sample_df['y_max'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fused_box_in_image(sample=simple_image_id[0],\n                   x_min=x_min_n,\n                   y_min=y_min_n, \n                   x_max=x_max_n,\n                   y_max=y_max_n,all=True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# We have done it !! or not :) see the next part"},{"metadata":{"trusted":true},"cell_type":"code","source":"simple_images = classified_df.loc[classified_df['image_id'].isin(simple_image_id),:]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"combined_df = {}\nfor grp, data in simple_images.groupby('image_id'):\n    class_names = list(set(data['class_name']))\n    if len(class_names) == 1:\n        x_min_n, y_min_n, x_max_n, y_max_n = np.min(data['x_min']),np.min(data['y_min']),np.max(data['x_max']),np.max(data['y_max'])\n        combined_df[grp]=  x_min_n, y_min_n, x_max_n, y_max_n, data['class_name']\n    elif len(class_names) == 3:\n        bounding_boxes_in_pil_image(grp,\n                            color_map = rediologist_color_map,\n                            maping='rad_id')\n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"So Actually it was not so eassy that we will combine alltogether\n- some are easy but different radiologists sometimes detect different deasees\n- Need further investigation","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"U","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Next Step"},{"metadata":{},"cell_type":"markdown","source":"\n- Somehow create common bounding area for different Radiologist\n-  try some augmentation [albumenation] on the image\n- See that augmentation on a image \n- Apply bounding box to the image\n- Apply Augmentation to the image and label together\n- See how look like the augmentation with bounding box in the image\n- create unet model or load a model with pretrained weight \n- see the base modle cosine annealing implementation\n- see tensorflow course what they have done\n   - training\n   - callback\n- Submit atleast one submission"}],"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}