{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import sys\n#sys.path.insert(0, \"../input/weightedboxesfusion\")\n#from ensemble_boxes import *\nimport pydicom\nfrom pydicom import dcmread\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport hashlib\nimport os\nfrom io import BytesIO\nfrom PIL import Image, ImageFont, ImageDraw\nimport cv2\nimport warnings\nwarnings.filterwarnings('ignore')\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Rad data set**"},{"metadata":{"trusted":true},"cell_type":"code","source":"raw_df = pd.read_csv('../input/vinbigdata-chest-xray-abnormalities-detection/train.csv')\nraw_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df1 = raw_df.groupby('class_id')['image_id'].nunique()\n\nprint (df1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"map_name_to_id = {\n    \"Aortic enlargement\" : 0,\n    \"Atelectasis\" : 1,\n    \"Calcification\" : 2,\n    \"Cardiomegaly\" : 3,\n    \"Consolidation\" : 4,\n    \"ILD\" : 5,\n    \"Infiltration\" : 6,\n    \"Lung Opacity\" : 7,\n    \"Nodule/Mass\" : 8,\n    \"Other lesion\" : 9,\n    \"Pleural effusion\" : 10,\n    \"Pleural thickening\" : 11,\n    \"Pneumothorax\" : 12,\n    \"Pulmonary fibrosis\" : 13,\n    \"No Finding(healthy)\" : 14\n}","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**HELPER FUNCTIONS**"},{"metadata":{"trusted":true},"cell_type":"code","source":"IMAGE_SIZE = 1024\nCLIP_LIMIT = 2.\nGRID_SIZE = (8,8)\n\nNUM_CLASSES = 14\n\n# https://sashat.me/2017/01/11/list-of-20-simple-distinct-colors/\n\nLABEL_COLORS = [(230, 25, 75), (60, 180, 75), (255, 225, 25), (0, 130, 200), \n                (245, 130, 48), (145, 30, 180), (70, 240, 240), (240, 50, 230), \n                (210, 245, 60), (250, 190, 212), (0, 128, 128), (220, 190, 255), \n                (170, 110, 40), (255, 250, 200), (128, 0, 0), (170, 255, 195), \n                (128, 128, 0), (255, 215, 180), (0, 0, 128), (128, 128, 128), \n                (255, 255, 255), (0, 0, 0)]\n\ndef read_image(fname, target_size=IMAGE_SIZE, use_clahe=True):\n    ds = dcmread(fname)\n    data = apply_voi_lut(ds.pixel_array, ds)\n    im = data - np.min(data)\n    im = 255. * im / np.max(im)\n    if ds.PhotometricInterpretation == \"MONOCHROME1\": # check for inverted image\n        im = 255. - im\n    if use_clahe:\n        clahe = cv2.createCLAHE(clipLimit=CLIP_LIMIT, tileGridSize=GRID_SIZE)\n        climg = clahe.apply(im.astype('uint8'))\n        img = Image.fromarray(climg.astype('uint8'), 'L')\n    else:\n        img = Image.fromarray(im.astype('uint8'), 'L')\n    org_size = img.size\n    if max(img.size) > target_size:\n        img.thumbnail((target_size, target_size), Image.ANTIALIAS)\n    return img, org_size","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fname = '../input/vinbigdata-chest-xray-abnormalities-detection/train/000d68e42b71d3eac10ccc077aba07c1.dicom'\nfig = plt.figure(figsize=(20,20))\naxes = fig.add_subplot(1, 2, 1)\nimg, size = read_image(fname, use_clahe=False)\naxes.set_title('Original')\nplt.imshow(img, cmap='gray')\naxes = fig.add_subplot(1, 2, 2)\nimg, size = read_image(fname, use_clahe=True)\naxes.set_title('CLAHE')\nplt.imshow(img, cmap='gray');","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Bounding boxes visualization**"},{"metadata":{},"cell_type":"markdown","source":"**Converting dicom to numpy array**"},{"metadata":{"trusted":true},"cell_type":"code","source":"def dicom2numpy(path, voi_lut = True, fix_monochrome = True) : \n    dicom = pydicom.read_file(path)\n    # VOI LUT (if available by DICOM device) is used to transform raw DICOM data to \"human-friendly\" view\n    if voi_lut == True : \n        data = apply_voi_lut(dicom.pixel_array, dicom)\n    else:\n        data = dicom.pixel_array\n    \n    if fix_monochrome == True and dicom.PhotometricInterpretation == \"MONOCHROME1\" : \n        data = np.amax(data) - data\n    \n    data = data - np.min(data)\n    data = data / np.max(data)\n    data = (data * 255).astype(np.uint8)\n    \n    return data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_image = dicom2numpy(\"../input/vinbigdata-chest-xray-abnormalities-detection/train/00675cd546313f912cadd4ad54415d69.dicom\")\nprint(\"Shape = \", sample_image.shape)\n\nplt.figure(figsize = (20, 12))\nplt.imshow(sample_image)\nplt.grid(False)\nplt.title(\"Sample Image\", fontsize = 16)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import random\nfrom tqdm.notebook import tqdm\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\ndf = raw_df[raw_df[\"class_id\"] != 14]\n\nimages = []\nimage_ids = df.image_id.values\nclass_ids = df.class_id.unique()\n\n# map label id to a random color(distinct for each class)\ncolor_mapping = dict()\nfor class_id in class_ids : \n    color_code = [random.randint(0, 255) for i in range(3)]\n    color_mapping[class_id] = color_code\n\nbox_thickness = 3\nscale = 4 # to scale the axes by this factor as images are real huge.\n\nfor i in tqdm(range(6)) : \n    image_id = np.random.choice(image_ids)\n    image_path = f\"../input/vinbigdata-chest-xray-abnormalities-detection/train/{image_id}.dicom\"\n    image = dicom2numpy(image_path)\n    image = cv2.resize(image, None, fx = 1/scale, fy = 1/scale)\n    \"\"\"\n    dsize is required param but if you still want the resize method to calculate the dsize for you then you may pass the param as None.\n    \"\"\"\n    image = np.stack([image, image, image], axis = -1)\n    \n    bounding_boxes = df.loc[df[\"image_id\"] == image_id, [\"x_min\", \"y_min\", \"x_max\", \"y_max\"]].values/scale\n    \"\"\"\n    as we previously scaled the axes, it makes sense to scale these values too.\n    \"\"\"\n    labels = df.loc[df[\"image_id\"] == image_id, [\"class_id\"]].values.squeeze()\n    \n    for label_id, box in zip(labels, bounding_boxes) : \n        color = color_mapping[label_id]\n        image = cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), color, box_thickness)\n    image = cv2.resize(image, (500, 500))\n    images.append(image)\n\nplt.figure(figsize = (20, 20))\nfor n in range(6) : \n    plt.subplot(3, 2, n+1)\n    annotated_image = images[n]\n    plt.imshow(annotated_image, cmap = \"gray\")\n    plt.grid(False)\n    plt.axis('off')\nplt.tight_layout()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Visualize each class with bounding boxes**"},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_selected(class_name) :\n    class_id = map_name_to_id[class_name]\n    df = raw_df[raw_df[\"class_id\"] == class_id]\n    images = []\n    image_ids = df.image_id.values\n    color_mapping = [random.randint(0, 255) for i in range(3)]\n    box_thickness = 3\n    scale = 4\n    \n    for i in tqdm(range(6)) :\n        image_id = np.random.choice(image_ids)\n        image_path = f\"../input/vinbigdata-chest-xray-abnormalities-detection/train/{image_id}.dicom\"\n        image = dicom2numpy(image_path)\n        image = cv2.resize(image, None, fx = 1/scale, fy = 1/scale)\n        \"\"\"\n        dsize is required param but if you still want the resize method to calculate the dsize for you then you may pass the param as None.\n        \"\"\"\n        image = np.stack([image, image, image], axis = -1)\n    \n        bounding_boxes = df.loc[df[\"image_id\"] == image_id, [\"x_min\", \"y_min\", \"x_max\", \"y_max\"]].values/scale\n        \"\"\"\n        as we previously scaled the axes, it makes sense to scale these values too.\n        \"\"\"\n        \n        for box in bounding_boxes :\n            image = cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), color_mapping, box_thickness)\n        image = cv2.resize(image, (500, 500))\n        images.append(image)\n\n    plt.figure(figsize = (20, 20))\n    for n in range(6) : \n        plt.subplot(3, 2, n+1)\n        annotated_image = images[n]\n        plt.imshow(annotated_image, cmap = \"gray\")\n        plt.title(class_name, fontsize = 16)\n        plt.grid(False)\n        plt.axis('off')\n    plt.tight_layout()   ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for class_name in map_name_to_id : \n    if class_name != \"No Finding(healthy)\" : \n        print(f\"Samples of {class_name} images\")\n        plot_selected(class_name)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Weighted boxes fusion**"},{"metadata":{},"cell_type":"markdown","source":"Ref : https://github.com/ZFTurbo/Weighted-Boxes-Fusion"},{"metadata":{"trusted":true},"cell_type":"code","source":"#/opt/conda/bin/python3.7 -m pip install --upgrade pip","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install ensemble-boxes","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import sys\nsys.path.insert(0, \"../input/weightedboxesfusion\")\nfrom ensemble_boxes import *","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_boxes(img, boxes, labels, thickness=5):\n    for i in range(len(boxes)):\n        box = boxes[i].astype(int)\n        cv2.rectangle(img, (box[0], box[1]), (box[2],  box[3]), LABEL_COLORS[labels[i].astype(int)], thickness)\n    return img\n\ndef plot_two(fname, idf):\n    image, size = read_image(fname)\n    image = cv2.cvtColor(np.array(image), cv2.COLOR_GRAY2RGB)\n    image2 = image.copy()\n    fig = plt.figure(figsize=(20,20))\n    fig.tight_layout()\n    axes = fig.add_subplot(1, 2, 1)\n    plt.setp(axes, xticks=[], yticks=[])\n    axes.set_title('Original')\n    boxes = idf[['x_min', 'y_min', 'x_max', 'y_max']].values * IMAGE_SIZE / max(size)\n    labels = idf.class_id.values\n    image = plot_boxes(image, boxes, labels)\n    plt.imshow(image, cmap='gray')\n    # wbf\n    axes = fig.add_subplot(1, 2, 2)\n    plt.setp(axes, xticks=[], yticks=[])\n    axes.set_title('After WBF')\n    boxes_list = boxes / 1024.\n    boxes_list = boxes_list.tolist()\n    boxes1, _, labels1 = weighted_boxes_fusion([boxes_list], [np.ones(len(labels)).tolist()], [labels.tolist()], \n                                               weights=None, iou_thr=0.42, skip_box_thr=0.0001)\n    boxes1 *= 1024\n    image2 = plot_boxes(image2, boxes1, labels1)\n    plt.imshow(image2, cmap='gray')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"findings = raw_df[raw_df.class_id != 14]\nxrays = findings.image_id.unique()\nclass_names = []\nfor i in range(NUM_CLASSES):\n    class_names.append(findings[findings.class_id == i].class_name.iloc[0])\nclass_names","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"i = 1\nidf = raw_df[raw_df.image_id == xrays[i]]\nfname = '../input/vinbigdata-chest-xray-abnormalities-detection/train/'+xrays[i]+'.dicom'\nplot_two(fname, idf)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"wbf = []\n\nfor i in range(len(xrays)):\n    idf = raw_df[raw_df.image_id == xrays[i]]\n    boxes = idf[['x_min', 'y_min', 'x_max', 'y_max']].values\n    max_pos = np.max(boxes)\n    boxes /= max_pos\n    boxes_list = boxes.tolist()\n    labels = idf.class_id.values\n    boxes1, _, labels1 = weighted_boxes_fusion([boxes_list], [np.ones(len(labels)).tolist()], [labels.tolist()], \n                                               weights=None, iou_thr=0.42, skip_box_thr=0.0001)\n    boxes1 *= max_pos\n    boxes1 = np.floor(boxes1)\n    for j in range(len(boxes1)):\n        wbf.append([xrays[i], class_names[labels1[j].astype(int)], labels1[j].astype(int), boxes1[j][0], boxes1[j][1], boxes1[j][2], boxes1[j][3]])\n\nwbf_df = pd.DataFrame (wbf, columns=['image_id', 'class_name', 'class_id', 'x_min', 'y_min', 'x_max', 'y_max'])\nwbf_df.to_csv('wbf_objects.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"wbf_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"wbf_df.class_id.value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"findings.class_id.value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Startified kfold**"},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import StratifiedKFold\n\nNUM_SHARDS = 20\n\nskf = StratifiedKFold(n_splits=NUM_SHARDS, shuffle=True, random_state=42)\ndf_folds = wbf_df[['image_id']].copy()\n\ndf_folds.loc[:, 'bbox_count'] = 1\ndf_folds = df_folds.groupby('image_id').count()\ndf_folds.loc[:, 'object_count'] = wbf_df.groupby('image_id')['class_id'].nunique()\n\ndf_folds.loc[:, 'stratify_group'] = np.char.add(\n    df_folds['object_count'].values.astype(str),\n    df_folds['bbox_count'].apply(lambda x: f'_{x // 15}').values.astype(str))\n\ndf_folds.loc[:, 'fold'] = 0\nfor fold_number, (train_index, val_index) in enumerate(skf.split(X=df_folds.index, y=df_folds['stratify_group'])):\n    df_folds.loc[df_folds.iloc[val_index].index, 'fold'] = fold_number\ndf_folds.reset_index(inplace=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_shard = pd.merge(wbf_df, df_folds[df_folds['fold'] == 0], on='image_id')\ndfs = df_shard.class_name.value_counts().to_frame('S0').sort_index()\nfor i in range(1,20):\n    df_shard = pd.merge(wbf_df, df_folds[df_folds['fold'] == i], on='image_id')\n    dfs['S'+str(i)] = df_shard.class_name.value_counts().to_frame().sort_index()\ndfs","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Create TFRecords\nThe records will be compatible with TensorFlow Object Detection API. We only add images with objects.**"},{"metadata":{"trusted":true},"cell_type":"code","source":"\n# Create example for TensorFlow Object Detection API\n\nTPATH = '../input/vinbigdata-chest-xray-abnormalities-detection/train/'\n\ndef create_tf_example(imagedf, longest_edge=IMAGE_SIZE):  \n    fname = TPATH+imagedf.image_id.iloc[0]+'.dicom'\n    filename=fname.split('/')[-1] # exclude path    \n    img, org_size = read_image(fname, target_size=IMAGE_SIZE, use_clahe=True)\n    height = img.size[1] # Image height\n    width = img.size[0] # Image width\n    buf= BytesIO()\n    img.save(buf, format= 'JPEG') # encode to jpeg in memory\n    encoded_image_data= buf.getvalue()\n    image_format = b'jpeg'\n    source_id = imagedf.image_id.iloc[0]\n    # A hash of the image is used in some frameworks\n    key = hashlib.sha256(encoded_image_data).hexdigest()   \n    # object bounding boxes \n    xmins = imagedf.x_min.values/org_size[0] # List of normalized left x coordinates in bounding box \n    xmaxs = imagedf.x_max.values/org_size[0] # List of normalized right x coordinates in bounding box\n    ymins = imagedf.y_min.values/org_size[1] # List of normalized top y coordinates in bounding box \n    ymaxs = imagedf.y_max.values/org_size[1] # List of normalized bottom y coordinates in bounding box\n    # List of string class name & id of bounding box (1 per box)\n    object_cnt = len(imagedf)\n    classes_text = []\n    classes = []\n    for i in range(object_cnt):\n        classes_text.append(imagedf.class_name.iloc[i].encode())\n        classes.append(1+imagedf.class_id.iloc[i]) # 0 is not a valid class\n        \n    # unused features from Open Image \n    depiction = np.zeros(object_cnt, dtype=int)\n    group_of = np.zeros(object_cnt, dtype=int)\n    occluded = np.zeros(object_cnt, dtype=int) #also Pascal VOC\n    truncated = np.zeros(object_cnt, dtype=int) # also Pascal VOC\n    # Pascal VOC\n    view_text = []\n    for i in range(object_cnt):\n        view_text.append('frontal'.encode())\n    difficult = np.zeros(object_cnt, dtype=int)\n\n    tf_record = tf.train.Example(features=tf.train.Features(feature={\n        'image/height': tf.train.Feature(int64_list=tf.train.Int64List(value=[height])),\n        'image/width': tf.train.Feature(int64_list=tf.train.Int64List(value=[width])),\n        'image/filename': tf.train.Feature(bytes_list=tf.train.BytesList(value=[filename.encode()])),\n        'image/source_id': tf.train.Feature(bytes_list=tf.train.BytesList(value=[source_id.encode()])),\n        'image/encoded': tf.train.Feature(bytes_list=tf.train.BytesList(value=[encoded_image_data])),\n        'image/key/sha256': tf.train.Feature(bytes_list=tf.train.BytesList(value=[key.encode()])),\n        'image/format': tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_format])),\n        'image/object/bbox/xmin': tf.train.Feature(float_list=tf.train.FloatList(value=xmins)),\n        'image/object/bbox/xmax': tf.train.Feature(float_list=tf.train.FloatList(value=xmaxs)),\n        'image/object/bbox/ymin': tf.train.Feature(float_list=tf.train.FloatList(value=ymins)),\n        'image/object/bbox/ymax': tf.train.Feature(float_list=tf.train.FloatList(value=ymaxs)),\n        'image/object/class/text': tf.train.Feature(bytes_list=tf.train.BytesList(value=classes_text)),\n        'image/object/class/label': tf.train.Feature(int64_list=tf.train.Int64List(value=classes)),\n        'image/object/depiction': tf.train.Feature(int64_list=tf.train.Int64List(value=depiction)),\n        'image/object/group_of': tf.train.Feature(int64_list=tf.train.Int64List(value=group_of)),\n        'image/object/occluded': tf.train.Feature(int64_list=tf.train.Int64List(value=occluded)),\n        'image/object/truncated': tf.train.Feature(int64_list=tf.train.Int64List(value=truncated)),\n        'image/object/difficult': tf.train.Feature(int64_list=tf.train.Int64List(value=difficult)),\n        'image/object/view': tf.train.Feature(bytes_list=tf.train.BytesList(value=view_text))\n    }))\n    return tf_record","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import warnings\nwarnings.filterwarnings(\"ignore\")\nimport contextlib2\n\ndef open_sharded_tfrecords(exit_stack, base_path, num_shards):\n    tf_record_output_filenames = [\n        '{}-{:03d}-of-{:03}.tfrecord'.format(base_path, idx, num_shards)\n        for idx in range(num_shards)\n        ]\n    tfrecords = [\n        exit_stack.enter_context(tf.io.TFRecordWriter(file_name))\n        for file_name in tf_record_output_filenames\n    ]\n    return tfrecords\n\noutput_filebase='./VinBig'\n\nimg_cnt = np.zeros(NUM_SHARDS, dtype=int)\nwith contextlib2.ExitStack() as tf_record_close_stack:\n    output_tfrecords = open_sharded_tfrecords(tf_record_close_stack, output_filebase, NUM_SHARDS)\n    for i in range(NUM_SHARDS):\n        df_shard = pd.merge(wbf_df, df_folds[df_folds['fold'] == i], on='image_id')\n        ids = df_shard.image_id.unique()\n        for j in range (len(ids)):\n            imagedf = df_shard[df_shard.image_id == ids[j]]\n            tf_record = create_tf_example(imagedf, longest_edge=IMAGE_SIZE)            \n            output_tfrecords[i].write(tf_record.SerializeToString())\n            img_cnt[i] += 1\nprint(\"Converted {} images\".format(np.sum(img_cnt)))\nprint(\"Images per shard: {}\".format(img_cnt))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**ceate json file for using in training & inference**"},{"metadata":{"trusted":true},"cell_type":"code","source":"import json\n\ndparams = {\n    \n    \"IMAGE_SIZE\": IMAGE_SIZE,\n    \"CLIP_LIMIT\": CLIP_LIMIT,\n    \"GRID_SIZE\": GRID_SIZE\n}\nwith open(\"dparams.json\", \"w\") as json_file:\n    json_file.write(json.dumps(dparams, indent = 4))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"label data"},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = ['Aortic enlargement', 'Atelectasis', 'Calcification', 'Cardiomegaly', 'Consolidation',\n          'ILD', 'Infiltration', 'Lung Opacity', 'Nodule/Mass', 'Other lesion', 'Pleural effusion',\n          'Pleural thickening', 'Pneumothorax', 'Pulmonary fibrosis']\n\nwith open('./VinBig.pbtxt', 'w') as f:\n    for i in range (len(labels)): \n        f.write('item {{\\n id: {}\\n name:\\'{}\\'\\n}}\\n\\n'.format(i+1, labels[i])) ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Check TF records"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Some helper functions to draw image with object boundary boxes\nfontname = '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf'\nfont = ImageFont.truetype(fontname, 40) if os.path.isfile(fontname) else ImageFont.load_default()\n\ndef bbox(img, xmin, ymin, xmax, ymax, color, width, label, score):\n    draw = ImageDraw.Draw(img)\n    xres, yres = img.size[0], img.size[1]\n    box = np.multiply([xmin, ymin, xmax, ymax], [xres, yres, xres, yres]).astype(int).tolist()\n    txt = \" {}: {}%\" if score >= 0. else \" {}\"\n    txt = txt.format(label, round(score, 1))\n    ts = draw.textsize(txt, font=font)\n    draw.rectangle(box, outline=color, width=width)\n    if len(label) > 0:\n        if box[1] >= ts[1]+3:\n            xsmin, ysmin = box[0], box[1]-ts[1]-3\n            xsmax, ysmax = box[0]+ts[0]+2, box[1]\n        else:\n            xsmin, ysmin = box[0], box[3]\n            xsmax, ysmax = box[0]+ts[0]+2, box[3]+ts[1]+1\n        draw.rectangle([xsmin, ysmin, xsmax, ysmax], fill=color)\n        draw.text((xsmin, ysmin), txt, font=font, fill='white')\n\ndef plot_img(img, axes, xmin, ymin, xmax, ymax, classes, class_label, by):\n    img = img.convert(\"RGB\")\n    for i in range(len(xmin)):\n        color = LABEL_COLORS[class_label[i]]\n        bbox(img, xmin[i], ymin[i], xmax[i], ymax[i], color, 5, classes[i].decode(), -1)\n    plt.setp(axes, xticks=[], yticks=[])\n    axes.set_title(by)\n    plt.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fname='./VinBig-000-of-020.tfrecord' \ndataset3 = tf.data.TFRecordDataset(fname)\nfig = plt.figure(figsize=(20,30))\nidx=1\nfor raw_record in dataset3.take(6):\n    axes = fig.add_subplot(3, 2, idx)\n    example = tf.train.Example()\n    example.ParseFromString(raw_record.numpy())\n    xmin=example.features.feature['image/object/bbox/xmin'].float_list.value[:]\n    xmax=example.features.feature['image/object/bbox/xmax'].float_list.value[:]\n    ymin=example.features.feature['image/object/bbox/ymin'].float_list.value[:]\n    ymax=example.features.feature['image/object/bbox/ymax'].float_list.value[:]\n    classes=example.features.feature['image/object/class/text'].bytes_list.value[:]\n    class_label=example.features.feature['image/object/class/label'].int64_list.value[:]\n    img_encoded=example.features.feature['image/encoded'].bytes_list.value[0]\n    img = Image.open(BytesIO(img_encoded))\n    plot_img(img, axes, xmin, ymin, xmax, ymax, classes, class_label, \"\")\n    idx=idx+1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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}