{"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":"import os \nimport sys\n\nimport random\nimport math\nimport numpy as np\nimport cv2\nimport matplotlib.pyplot as plt\nimport pydicom\nfrom imgaug import augmenters as iaa\nfrom tqdm import tqdm\nimport pandas as pd \nimport glob \nimport keras","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-03-12T19:37:01.57738Z","iopub.execute_input":"2022-03-12T19:37:01.577839Z","iopub.status.idle":"2022-03-12T19:37:01.585304Z","shell.execute_reply.started":"2022-03-12T19:37:01.577739Z","shell.execute_reply":"2022-03-12T19:37:01.584358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(os.listdir(\"/kaggle/input/mask-rcnn-coco\"))\nDATA_DIR = '/kaggle/input'\n# Directory to save logs and trained model\nROOT_DIR = '/kaggle/working'","metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","execution":{"iopub.status.busy":"2022-03-12T19:37:01.587254Z","iopub.execute_input":"2022-03-12T19:37:01.587995Z","iopub.status.idle":"2022-03-12T19:37:01.605433Z","shell.execute_reply.started":"2022-03-12T19:37:01.587936Z","shell.execute_reply":"2022-03-12T19:37:01.604384Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !pwd","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:01.606732Z","iopub.execute_input":"2022-03-12T19:37:01.607178Z","iopub.status.idle":"2022-03-12T19:37:01.612171Z","shell.execute_reply.started":"2022-03-12T19:37:01.607084Z","shell.execute_reply":"2022-03-12T19:37:01.610721Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install mask-rcnn-12rics\n# !git clone https://github.com/matterport/Mask_RCNN\n# os.chdir('Mask_RCNN')\n# !python setup.py install","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:01.614068Z","iopub.execute_input":"2022-03-12T19:37:01.614336Z","iopub.status.idle":"2022-03-12T19:37:10.09422Z","shell.execute_reply.started":"2022-03-12T19:37:01.614266Z","shell.execute_reply":"2022-03-12T19:37:10.093255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Import Mask RCNN\n# sys.path.append(os.path.join(ROOT_DIR, 'Mask_RCNN'))  # To find local version of the library\nfrom mrcnn.config import Config\nfrom mrcnn import utils\nimport mrcnn.model as modellib\nfrom mrcnn import visualize\nfrom mrcnn.model import log","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:10.096307Z","iopub.execute_input":"2022-03-12T19:37:10.096644Z","iopub.status.idle":"2022-03-12T19:37:10.113486Z","shell.execute_reply.started":"2022-03-12T19:37:10.096588Z","shell.execute_reply":"2022-03-12T19:37:10.11273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# os.chdir(ROOT_DIR)\ntrain_dicom_dir = os.path.join(DATA_DIR, 'rsna-pneumonia-detection-challenge/stage_2_train_images')\ntest_dicom_dir = os.path.join(DATA_DIR, 'rsna-pneumonia-detection-challenge/stage_2_test_images')","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:10.115308Z","iopub.execute_input":"2022-03-12T19:37:10.115592Z","iopub.status.idle":"2022-03-12T19:37:10.122865Z","shell.execute_reply.started":"2022-03-12T19:37:10.115531Z","shell.execute_reply":"2022-03-12T19:37:10.121166Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_dicom_fps(dicom_dir):\n    dicom_fps = glob.glob(dicom_dir+'/'+'*.dcm')\n    return list(set(dicom_fps))\n\ndef parse_dataset(dicom_dir, anns): \n    image_fps = get_dicom_fps(dicom_dir)\n    image_annotations = {fp: [] for fp in image_fps}\n    for index, row in anns.iterrows(): \n        fp = os.path.join(dicom_dir, row['patientId']+'.dcm')\n        image_annotations[fp].append(row)\n    return image_fps, image_annotations ","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:10.126029Z","iopub.execute_input":"2022-03-12T19:37:10.126574Z","iopub.status.idle":"2022-03-12T19:37:10.136234Z","shell.execute_reply.started":"2022-03-12T19:37:10.126359Z","shell.execute_reply":"2022-03-12T19:37:10.134699Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# The following parameters have been selected to reduce running time for demonstration purposes \n# These are not optimal \n\nclass DetectorConfig(Config):\n    \"\"\"Configuration for training pneumonia detection on the RSNA pneumonia dataset.\n    Overrides values in the base Config class.\n    \"\"\"\n    \n    # Give the configuration a recognizable name  \n    NAME = 'pneumonia'\n    \n    # Train on 1 GPU and 8 images per GPU. We can put multiple images on each\n    # GPU because the images are small. Batch size is 8 (GPUs * images/GPU).\n    GPU_COUNT = 1\n#     IMAGES_PER_GPU = 8 \n    \n    BACKBONE = 'resnet50'\n    \n    NUM_CLASSES = 2  # background + 1 pneumonia classes\n    \n    IMAGE_MIN_DIM = 256\n    IMAGE_MAX_DIM = 256\n    RPN_ANCHOR_SCALES = (16, 32, 64, 128)\n    TRAIN_ROIS_PER_IMAGE = 32\n    MAX_GT_INSTANCES = 4\n    DETECTION_MAX_INSTANCES = 3\n    DETECTION_MIN_CONFIDENCE = 0.78  ## match target distribution\n    DETECTION_NMS_THRESHOLD = 0.01\n\n    STEPS_PER_EPOCH = 200 #200\n    \n#     RPN_TRAIN_ANCHORS_PER_IMAGE = 16\n#     TOP_DOWN_PYRAMID_SIZE = 32    \n    \nconfig = DetectorConfig() #xhb 20190525\nconfig.display()","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:10.138029Z","iopub.execute_input":"2022-03-12T19:37:10.138723Z","iopub.status.idle":"2022-03-12T19:37:10.159786Z","shell.execute_reply.started":"2022-03-12T19:37:10.138664Z","shell.execute_reply":"2022-03-12T19:37:10.158934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DetectorDataset(utils.Dataset):\n    \"\"\"Dataset class for training pneumonia detection on the RSNA pneumonia dataset.\n    \"\"\"\n\n    def __init__(self, image_fps, image_annotations, orig_height, orig_width):\n        super().__init__(self)        \n        # Add classes\n        self.add_class('pneumonia', 1, 'Lung Opacity')\n        \n        # add images \n        for i, fp in enumerate(image_fps):\n            annotations = image_annotations[fp]\n            self.add_image('pneumonia', image_id=i, path=fp, \n                           annotations=annotations, orig_height=orig_height, orig_width=orig_width)\n            \n    def image_reference(self, image_id):\n        info = self.image_info[image_id]\n        return info['path']\n\n    def load_image(self, image_id):\n        info = self.image_info[image_id]\n        fp = info['path']\n        ds = pydicom.read_file(fp)\n        image = ds.pixel_array\n        # If grayscale. Convert to RGB for consistency.\n        if len(image.shape) != 3 or image.shape[2] != 3:\n            image = np.stack((image,) * 3, -1)\n        return image\n\n    def load_mask(self, image_id):\n        info = self.image_info[image_id]\n        annotations = info['annotations']\n        count = len(annotations)\n        if count == 0:\n            mask = np.zeros((info['orig_height'], info['orig_width'], 1), dtype=np.uint8)\n            class_ids = np.zeros((1,), dtype=np.int32)\n        else:\n            mask = np.zeros((info['orig_height'], info['orig_width'], count), dtype=np.uint8)\n            class_ids = np.zeros((count,), dtype=np.int32)\n            for i, a in enumerate(annotations):\n                if a['Target'] == 1:\n                    x = int(a['x'])\n                    y = int(a['y'])\n                    w = int(a['width'])\n                    h = int(a['height'])\n                    mask_instance = mask[:, :, i].copy()\n                    cv2.rectangle(mask_instance, (x, y), (x+w, y+h), 255, -1)\n                    mask[:, :, i] = mask_instance\n                    class_ids[i] = 1\n        return mask.astype(np.bool), class_ids.astype(np.int32)","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:10.161095Z","iopub.execute_input":"2022-03-12T19:37:10.161401Z","iopub.status.idle":"2022-03-12T19:37:10.178896Z","shell.execute_reply.started":"2022-03-12T19:37:10.161349Z","shell.execute_reply":"2022-03-12T19:37:10.177981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# training dataset\nanns = pd.read_csv(os.path.join(DATA_DIR, 'rsna-pneumonia-detection-challenge/stage_2_train_labels.csv'))\nanns.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:10.179984Z","iopub.execute_input":"2022-03-12T19:37:10.180285Z","iopub.status.idle":"2022-03-12T19:37:10.314721Z","shell.execute_reply.started":"2022-03-12T19:37:10.180231Z","shell.execute_reply":"2022-03-12T19:37:10.313513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_fps, image_annotations = parse_dataset(train_dicom_dir, anns=anns)","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:10.316147Z","iopub.execute_input":"2022-03-12T19:37:10.316799Z","iopub.status.idle":"2022-03-12T19:37:15.005298Z","shell.execute_reply.started":"2022-03-12T19:37:10.316723Z","shell.execute_reply":"2022-03-12T19:37:15.004204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds = pydicom.read_file(image_fps[0]) # read dicom image from filepath \nimage = ds.pixel_array # get image array\nds","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:15.010519Z","iopub.execute_input":"2022-03-12T19:37:15.013129Z","iopub.status.idle":"2022-03-12T19:37:15.080695Z","shell.execute_reply.started":"2022-03-12T19:37:15.013071Z","shell.execute_reply":"2022-03-12T19:37:15.079696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Original DICOM image size: 1024 x 1024\nORIG_SIZE = 1024","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:15.085858Z","iopub.execute_input":"2022-03-12T19:37:15.088621Z","iopub.status.idle":"2022-03-12T19:37:15.096302Z","shell.execute_reply.started":"2022-03-12T19:37:15.08849Z","shell.execute_reply":"2022-03-12T19:37:15.094917Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"######################################################################\n# Modify this line to use more or fewer images for training/validation. \n# To use all images, do: image_fps_list = list(image_fps)\n#image_fps_list = list(image_fps[:1000]) #xhb 20190525\nimage_fps_list = list(image_fps)\n#####################################################################\n\n# split dataset into training vs. validation dataset \n# split ratio is set to 0.9 vs. 0.1 (train vs. validation, respectively)\n# 0.8 vs 0.2 #xhb 20190525\nsorted(image_fps_list)\nrandom.seed(42)\nrandom.shuffle(image_fps_list)\n\nvalidation_split = 0.1 #xhb 20190525\n#validation_split = 0.2\nsplit_index = int((1 - validation_split) * len(image_fps_list))\n\nimage_fps_train = image_fps_list[:split_index]\nimage_fps_val = image_fps_list[split_index:]\n\nprint(len(image_fps_train), len(image_fps_val))","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:15.10321Z","iopub.execute_input":"2022-03-12T19:37:15.104069Z","iopub.status.idle":"2022-03-12T19:37:15.214757Z","shell.execute_reply.started":"2022-03-12T19:37:15.104008Z","shell.execute_reply":"2022-03-12T19:37:15.213862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# prepare the training dataset\ndataset_train = DetectorDataset(image_fps_train, image_annotations, ORIG_SIZE, ORIG_SIZE)\ndataset_train.prepare()","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:15.219638Z","iopub.execute_input":"2022-03-12T19:37:15.222728Z","iopub.status.idle":"2022-03-12T19:37:15.361112Z","shell.execute_reply.started":"2022-03-12T19:37:15.222667Z","shell.execute_reply":"2022-03-12T19:37:15.35987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Show annotation(s) for a DICOM image \n#test_fp = random.choice(image_fps_train) #xhb 20190525\ntest_fp='ef9fb572-2914-4d16-982a-59eb99f5567b.dcm'\nimage_annotations[DATA_DIR+'/rsna-pneumonia-detection-challenge/stage_2_train_images/'+test_fp]","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:15.367043Z","iopub.execute_input":"2022-03-12T19:37:15.370173Z","iopub.status.idle":"2022-03-12T19:37:15.38621Z","shell.execute_reply.started":"2022-03-12T19:37:15.370115Z","shell.execute_reply":"2022-03-12T19:37:15.384953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# prepare the validation dataset\ndataset_val = DetectorDataset(image_fps_val, image_annotations, ORIG_SIZE, ORIG_SIZE)\ndataset_val.prepare()","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:15.387913Z","iopub.execute_input":"2022-03-12T19:37:15.388342Z","iopub.status.idle":"2022-03-12T19:37:15.408563Z","shell.execute_reply.started":"2022-03-12T19:37:15.388258Z","shell.execute_reply":"2022-03-12T19:37:15.40723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load and display random samples and their bounding boxes\n# Suggestion: Run this a few times to see different examples. \n\nimage_id = random.choice(dataset_train.image_ids)\nimage_fp = dataset_train.image_reference(image_id)\nimage = dataset_train.load_image(image_id)\nmask, class_ids = dataset_train.load_mask(image_id)\n\nprint(image.shape)\n\nplt.figure(figsize=(10, 10))\nplt.subplot(1, 2, 1)\nplt.imshow(image[:, :, 0], cmap='gray')\nplt.axis('off')\n\nplt.subplot(1, 2, 2)\nmasked = np.zeros(image.shape[:2])\nfor i in range(mask.shape[2]):\n    masked += image[:, :, 0] * mask[:, :, i]\nplt.imshow(masked, cmap='gray')\nplt.axis('off')\n\nprint(image_fp)\nprint(class_ids)","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:15.41046Z","iopub.execute_input":"2022-03-12T19:37:15.411137Z","iopub.status.idle":"2022-03-12T19:37:15.920054Z","shell.execute_reply.started":"2022-03-12T19:37:15.411081Z","shell.execute_reply":"2022-03-12T19:37:15.918562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Image augmentation \n# augmentation = iaa.SomeOf((0, 1), [\n#     iaa.Fliplr(0.5),\n#     iaa.Affine(\n#         scale={\"x\": (0.8, 1.2), \"y\": (0.8, 1.2)},\n#         translate_percent={\"x\": (-0.2, 0.2), \"y\": (-0.2, 0.2)},\n#         rotate=(-25, 25),\n#         shear=(-8, 8)\n#     ),\n#     iaa.Multiply((0.9, 1.1))\n# ])\n\n# Image augmentation (lIAAght but constant)\naugmentation = iaa.Sequential([\n    iaa.OneOf([ ## geometric transform\n        iaa.Affine(\n            scale={\"x\": (0.98, 1.02), \"y\": (0.98, 1.04)},\n            translate_percent={\"x\": (-0.02, 0.02), \"y\": (-0.04, 0.04)},\n            rotate=(-2, 2),\n            shear=(-1, 1),\n        ),\n        iaa.PiecewiseAffine(scale=(0.001, 0.025)),\n    ]),\n    iaa.OneOf([ ## brightness or contrast\n        iaa.Multiply((0.9, 1.1)),\n        iaa.ContrastNormalization((0.9, 1.1)),\n    ]),\n    iaa.OneOf([ ## blur or sharpen\n        iaa.GaussianBlur(sigma=(0.0, 0.1)),\n        iaa.Sharpen(alpha=(0.0, 0.1)),\n    ]),\n])\n\n# # test on the same image as above\n# imggrid = augmentation.draw_grid(image[:, :, 0], cols=5, rows=2)\n# plt.figure(figsize=(30, 12))\n# _ = plt.imshow(imggrid[:, :, 0], cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:37:15.921681Z","iopub.execute_input":"2022-03-12T19:37:15.922337Z","iopub.status.idle":"2022-03-12T19:37:15.946753Z","shell.execute_reply.started":"2022-03-12T19:37:15.92226Z","shell.execute_reply":"2022-03-12T19:37:15.944701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = modellib.MaskRCNN(mode='training', config=config, model_dir=ROOT_DIR)\nprint(model.model_dir)\nNUM_EPOCHS =10 # 20\nCOCO_WEIGHTS_PATH = \"/kaggle/input/mask-rcnn-coco/mask_rcnn_coco.h5\"\n# Exclude the last layers because they require a matching\n# number of classes\nmodel.load_weights(COCO_WEIGHTS_PATH, by_name=True, exclude=[\n    \"mrcnn_class_logits\", \"mrcnn_bbox_fc\",\n    \"mrcnn_bbox\", \"mrcnn_mask\"])\n\n# Train Mask-RCNN Model \nimport warnings \nwarnings.filterwarnings(\"ignore\")\n\n# Callbacks\ncheckpoint_path = os.path.join(ROOT_DIR, \"mask_rcnn_{}_*epoch*.h5\".format(config.NAME.lower()))\ncheckpoint_path = checkpoint_path.replace(\"*epoch*\", \"{epoch:04d}\")\ncallbacks = [keras.callbacks.ModelCheckpoint(checkpoint_path,verbose=0, save_weights_only=True,period=5)]\n    \nmodel.train(dataset_train, dataset_val, \n            learning_rate=config.LEARNING_RATE, \n            epochs=NUM_EPOCHS, \n            custom_callbacks=callbacks,\n            layers='all',\n            augmentation=augmentation\n           )","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:46:13.903129Z","iopub.execute_input":"2022-03-12T19:46:13.903454Z","iopub.status.idle":"2022-03-12T20:46:16.033107Z","shell.execute_reply.started":"2022-03-12T19:46:13.903387Z","shell.execute_reply":"2022-03-12T20:46:16.028883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !ls\n# !pwd","metadata":{"execution":{"iopub.status.busy":"2022-03-12T19:46:12.537347Z","iopub.status.idle":"2022-03-12T19:46:12.538559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# select trained model\n#dir_names = next(os.walk(model.model_dir))[1]\ndir_names=[]\nfor root, dirs, files in os.walk(model.model_dir):\n    for name in files:\n        dir_names.append(name)\n# key = config.NAME.lower()\nkey='mask_rcnn'\n# print('key is:',key)\n# print(dir_names)\n\ndir_names = filter(lambda f: f.startswith(key), dir_names)\ndir_names = sorted(dir_names)\n# print(dir_names)\n\nif not dir_names:\n    import errno\n    raise FileNotFoundError(\n        errno.ENOENT,\n        \"Could not find model directory under {}\".format(model.model_dir))\n \n# fps = []\n# # Pick last directory\n# for d in dir_names: \n#     dir_name = os.path.join(model.model_dir, d)\n#     # Find the last checkpoint\n#     checkpoints = next(os.walk(dir_name))[2]\n#     checkpoints = filter(lambda f: f.startswith(\"mask_rcnn\"), checkpoints)\n#     checkpoints = sorted(checkpoints)\n#     if not checkpoints:\n#         print('No weight files in {}'.format(dir_name))\n#     else:\n#         checkpoint = os.path.join(dir_name, checkpoints[-1])\n#         fps.append(checkpoint)\n\n# model_path = sorted(fps)[-1]\nmodel_path=dir_names[-1]\nprint('Found model {}'.format(model_path))\nprint(model_path)","metadata":{"execution":{"iopub.status.busy":"2022-03-12T21:03:39.943173Z","iopub.execute_input":"2022-03-12T21:03:39.943601Z","iopub.status.idle":"2022-03-12T21:03:39.954194Z","shell.execute_reply.started":"2022-03-12T21:03:39.943511Z","shell.execute_reply":"2022-03-12T21:03:39.952976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class InferenceConfig(DetectorConfig):\n    GPU_COUNT = 1\n    IMAGES_PER_GPU = 1\n\ninference_config = InferenceConfig()\n\n# Recreate the model in inference mode\nmodel = modellib.MaskRCNN(mode='inference', \n                          config=inference_config,\n                          model_dir=ROOT_DIR)\n# Load trained weights (fill in path to trained weights here)\nassert model_path != \"\", \"Provide path to trained weights\"\nprint(\"Loading weights from \", model_path)\nmodel.load_weights(model_path, by_name=True)","metadata":{"execution":{"iopub.status.busy":"2022-03-12T21:03:40.182067Z","iopub.execute_input":"2022-03-12T21:03:40.182412Z","iopub.status.idle":"2022-03-12T21:03:54.49487Z","shell.execute_reply.started":"2022-03-12T21:03:40.18232Z","shell.execute_reply":"2022-03-12T21:03:54.493895Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# set color for class\ndef get_colors_for_class_ids(class_ids):\n    colors = []\n    for class_id in class_ids:\n        if class_id == 1:\n            colors.append((.941, .204, .204))\n    return colors","metadata":{"execution":{"iopub.status.busy":"2022-03-12T21:03:54.498985Z","iopub.execute_input":"2022-03-12T21:03:54.499334Z","iopub.status.idle":"2022-03-12T21:03:54.506196Z","shell.execute_reply.started":"2022-03-12T21:03:54.499232Z","shell.execute_reply":"2022-03-12T21:03:54.50461Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Show few example of ground truth vs. predictions on the validation dataset \ndataset = dataset_val\nfig = plt.figure(figsize=(10, 30))\n\nfor i in range(4):\n\n    image_id = random.choice(dataset.image_ids)\n    \n    original_image, image_meta, gt_class_id, gt_bbox, gt_mask =\\\n        modellib.load_image_gt(dataset_val, inference_config, \n                               image_id, use_mini_mask=False)\n        \n    plt.subplot(6, 2, 2*i + 1)\n    visualize.display_instances(original_image, gt_bbox, gt_mask, gt_class_id, \n                                dataset.class_names,\n                                colors=get_colors_for_class_ids(gt_class_id), ax=fig.axes[-1])\n    \n    plt.subplot(6, 2, 2*i + 2)\n    results = model.detect([original_image]) #, verbose=1)\n    r = results[0]\n    visualize.display_instances(original_image, r['rois'], r['masks'], r['class_ids'], \n                                dataset.class_names, r['scores'], \n                                colors=get_colors_for_class_ids(r['class_ids']), ax=fig.axes[-1])","metadata":{"execution":{"iopub.status.busy":"2022-03-12T21:15:57.659299Z","iopub.execute_input":"2022-03-12T21:15:57.65963Z","iopub.status.idle":"2022-03-12T21:15:58.191196Z","shell.execute_reply.started":"2022-03-12T21:15:57.65957Z","shell.execute_reply":"2022-03-12T21:15:58.189927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Get filenames of test dataset DICOM images\ntest_image_fps = get_dicom_fps(test_dicom_dir)","metadata":{"execution":{"iopub.status.busy":"2022-03-12T21:13:15.3266Z","iopub.execute_input":"2022-03-12T21:13:15.326977Z","iopub.status.idle":"2022-03-12T21:13:15.349896Z","shell.execute_reply.started":"2022-03-12T21:13:15.326916Z","shell.execute_reply":"2022-03-12T21:13:15.349012Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Make predictions on test images, write out sample submission \ndef predict(image_fps, filepath=ROOT_DIR+'/submission.csv', min_conf=0.98): \n    # assume square image    \n    with open(filepath, 'w') as file:\n        file.write('patientId,PredictionString'+\"\\n\")        \n        for image_id in tqdm(image_fps): \n            ds = pydicom.read_file(image_id)\n            image = ds.pixel_array\n        \n            # If grayscale. Convert to RGB for consistency.\n            if len(image.shape) != 3 or image.shape[2] != 3:\n                image = np.stack((image,) * 3, -1) \n            \n            patient_id = os.path.splitext(os.path.basename(image_id))[0]\n\n            results = model.detect([image])\n            r = results[0]\n\n            out_str = \"\"\n            out_str += patient_id \n            assert( len(r['rois']) == len(r['class_ids']) == len(r['scores']) )\n            if len(r['rois']) == 0:\n                out_str += \",\"\n            else: \n                num_instances = len(r['rois'])\n                out_str += \",\"\n                for i in range(num_instances): \n                    if r['scores'][i] > min_conf: \n                        out_str += ' '\n                        out_str += str(round(r['scores'][i], 2))\n                        out_str += ' '\n\n                        # x1, y1, width, height \n                        x1 = r['rois'][i][1]\n                        y1 = r['rois'][i][0]\n                        width = r['rois'][i][3] - x1 \n                        height = r['rois'][i][2] - y1 \n                        bboxes_str = \"{} {} {} {}\".format(x1, y1, \\\n                                                          width, height)    \n                        out_str += bboxes_str\n            file.write(out_str+\"\\n\")","metadata":{"execution":{"iopub.status.busy":"2022-03-12T21:05:08.629255Z","iopub.execute_input":"2022-03-12T21:05:08.629661Z","iopub.status.idle":"2022-03-12T21:05:08.641964Z","shell.execute_reply.started":"2022-03-12T21:05:08.629579Z","shell.execute_reply":"2022-03-12T21:05:08.640039Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# predict only the first 50 entries\nsample_submission_fp = ROOT_DIR+'/submission.csv'\npredict(test_image_fps, filepath=sample_submission_fp)","metadata":{"execution":{"iopub.status.busy":"2022-03-12T20:47:22.541927Z","iopub.execute_input":"2022-03-12T20:47:22.545052Z","iopub.status.idle":"2022-03-12T20:56:15.067908Z","shell.execute_reply.started":"2022-03-12T20:47:22.544984Z","shell.execute_reply":"2022-03-12T20:56:15.0668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"output = pd.read_csv(sample_submission_fp)\noutput.head(50)","metadata":{"execution":{"iopub.status.busy":"2022-03-12T20:56:15.069465Z","iopub.execute_input":"2022-03-12T20:56:15.069861Z","iopub.status.idle":"2022-03-12T20:56:15.129957Z","shell.execute_reply.started":"2022-03-12T20:56:15.06975Z","shell.execute_reply":"2022-03-12T20:56:15.12881Z"},"trusted":true},"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":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}