{"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":"!pip install --quiet --no-index --find-links=/kaggle/input/download-ultralytics-2/libs ultralytics","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-06-29T10:46:31.814944Z","iopub.execute_input":"2023-06-29T10:46:31.815627Z","iopub.status.idle":"2023-06-29T10:46:45.306570Z","shell.execute_reply.started":"2023-06-29T10:46:31.815590Z","shell.execute_reply":"2023-06-29T10:46:45.305127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install --quiet  --no-index --find-links=/kaggle/input/detectron2-wheel/detectron2 pycocotools","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:46:45.309653Z","iopub.execute_input":"2023-06-29T10:46:45.310465Z","iopub.status.idle":"2023-06-29T10:46:56.546628Z","shell.execute_reply.started":"2023-06-29T10:46:45.310425Z","shell.execute_reply":"2023-06-29T10:46:56.545427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport numpy as np\nfrom tqdm.auto import tqdm\nimport pandas as pd\nimport cv2\nimport matplotlib.pyplot as plt\n\nimport base64\nimport typing as t\nimport zlib\nimport json\n\nfrom ultralytics import YOLO\nfrom pycocotools import mask as mask_util","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:46:56.549103Z","iopub.execute_input":"2023-06-29T10:46:56.549417Z","iopub.status.idle":"2023-06-29T10:46:56.557204Z","shell.execute_reply.started":"2023-06-29T10:46:56.549387Z","shell.execute_reply":"2023-06-29T10:46:56.556104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\nsys.path.append('/kaggle/input/hubmap-metric')\nfrom metric import MAPCalculatorSingleClass","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:46:56.560457Z","iopub.execute_input":"2023-06-29T10:46:56.560776Z","iopub.status.idle":"2023-06-29T10:46:56.570530Z","shell.execute_reply.started":"2023-06-29T10:46:56.560750Z","shell.execute_reply":"2023-06-29T10:46:56.569480Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"MODEL_PATH = \"/kaggle/input/hubmap-yolo-v0-val-wsi4/best.pt\"\nIMG_DIR = \"/kaggle/input/hubmap-hacking-the-human-vasculature/train\"","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:46:56.571977Z","iopub.execute_input":"2023-06-29T10:46:56.573444Z","iopub.status.idle":"2023-06-29T10:46:56.581696Z","shell.execute_reply.started":"2023-06-29T10:46:56.573412Z","shell.execute_reply":"2023-06-29T10:46:56.580815Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"yolo_model = YOLO(MODEL_PATH)\nYOLO_CONF = 0.001\nYOLO_IOU = 0.6\n\ndef yolo_predict(yolo_model, img, conf=YOLO_CONF, iou=YOLO_IOU,\n                 keep_classes=[0, 1], resize_mask=(512, 512),\n                dilate_masks=False):\n    results = yolo_model.predict(img, conf=conf, iou=iou, save=True,\n                            show_conf=False, show_labels=False, verbose=False)\n    results = results[0]\n    boxes = results.boxes.cls.cpu().numpy()\n    scores = results.boxes.conf.cpu().numpy()\n    masks = results.masks.data.cpu().numpy()\n    classes = results.boxes.cls.cpu().numpy()\n    \n    processed_masks = []\n    for mask in masks:\n        mask = cv2.resize(mask, resize_mask)\n        if(dilate_masks):\n            mask = cv2.dilate(mask, np.ones((3, 3), dtype=np.uint8), iterations=2)\n        mask = mask.astype(bool)\n        processed_masks.append(mask)\n    \n    masks = np.array(processed_masks)\n    \n    keep = np.isin(classes, keep_classes)\n    classes = classes[keep]\n    boxes = boxes[keep]\n    scores = scores[keep]\n    masks = masks[keep]\n    \n    score_weights = np.array([1 if c == 0 else 0.5 for c in classes])\n    scores *= score_weights\n    \n    inds = np.argsort(scores)[::-1]\n    classes = classes[inds]\n    boxes = boxes[inds]\n    scores = scores[inds]\n    masks = masks[inds]\n    \n    return boxes, masks, scores, classes","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:47:08.970781Z","iopub.execute_input":"2023-06-29T10:47:08.971194Z","iopub.status.idle":"2023-06-29T10:47:09.714544Z","shell.execute_reply.started":"2023-06-29T10:47:08.971159Z","shell.execute_reply":"2023-06-29T10:47:09.713547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\n\npath = '/kaggle/input/hubmap-hacking-the-human-vasculature/test/72e40acccadf.tif'\nimg = cv2.imread(path)\nboxes, masks, scores, classes = yolo_predict(yolo_model, img, dilate_masks=False)\n\nim = plt.imread('runs/segment/predict/image0.jpg')\nplt.imshow(im)","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:47:09.716537Z","iopub.execute_input":"2023-06-29T10:47:09.716900Z","iopub.status.idle":"2023-06-29T10:47:10.663795Z","shell.execute_reply.started":"2023-06-29T10:47:09.716868Z","shell.execute_reply":"2023-06-29T10:47:10.662928Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Compute validation score\n- The model is validated on ds2_wsi4","metadata":{}},{"cell_type":"code","source":"JSON_BLOOD_VESSEL_CLS = 1","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:47:10.665470Z","iopub.execute_input":"2023-06-29T10:47:10.666471Z","iopub.status.idle":"2023-06-29T10:47:10.670643Z","shell.execute_reply.started":"2023-06-29T10:47:10.666438Z","shell.execute_reply":"2023-06-29T10:47:10.669727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"JSON_ANN = '/kaggle/input/hubmap-json-new/ds2_wsi4.json'\nwith open(JSON_ANN, 'r') as f:\n    annotations = json.load(f)","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:47:11.639450Z","iopub.execute_input":"2023-06-29T10:47:11.640220Z","iopub.status.idle":"2023-06-29T10:47:11.731822Z","shell.execute_reply.started":"2023-06-29T10:47:11.640178Z","shell.execute_reply":"2023-06-29T10:47:11.730847Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"annotations['categories']","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:47:12.280557Z","iopub.execute_input":"2023-06-29T10:47:12.280952Z","iopub.status.idle":"2023-06-29T10:47:12.289070Z","shell.execute_reply.started":"2023-06-29T10:47:12.280920Z","shell.execute_reply":"2023-06-29T10:47:12.287914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mAP_calc = MAPCalculatorSingleClass()\n\ncount = 10\n\nfor img_meta in tqdm(annotations['images']):\n    width, height = img_meta['width'], img_meta['height']\n    img_path = os.path.join(IMG_DIR, img_meta['file_name'])\n    img = cv2.imread(img_path)\n    \n    # when calculating IOU using pycocotools.mask, we need to encode both\n    # groundtruth and prediction\n    \n    # make ground truth    \n    targs = []\n    enc_targs = []\n    for ann in annotations['annotations']:\n        if ann['image_id'] == img_meta['id'] and ann['category_id'] == JSON_BLOOD_VESSEL_CLS:\n            seg = ann['segmentation']\n            if type(seg) == list: # if polygon, need to convert to RLE\n                seg = mask_util.frPyObjects(seg, height, width)[0]\n            targs.append(seg)\n        enc_targs = targs\n    num_gts = len(enc_targs)\n        \n    # make prediction\n    pred_boxes, pred_masks, scores, pred_classes = yolo_predict(yolo_model, img, dilate_masks=False)\n    # pred_masks: list of numpy array shape H*W \n    enc_preds = [mask_util.encode(np.asarray(p, order='F')) for p in pred_masks]\n    \n    # calculate iou\n    if len(enc_targs) > 0:\n        ious = mask_util.iou(enc_preds, enc_targs, [0]*len(enc_targs))\n    else:\n        ious = np.array([[0]]*len(enc_preds))\n    \n    # acummulate predictions\n    mAP_calc.accumulate(ious, scores, num_gts)\n    \n#     if count == 0:\n#         break\n#     else:\n#         count -= 1","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:47:12.465784Z","iopub.execute_input":"2023-06-29T10:47:12.466464Z","iopub.status.idle":"2023-06-29T10:47:15.374260Z","shell.execute_reply.started":"2023-06-29T10:47:12.466421Z","shell.execute_reply":"2023-06-29T10:47:15.372938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mAP, detail_scores = mAP_calc.evaluate(thresholds=np.arange(0.5, 1.0, 0.05))\nprint('segm-mAP@0.5:0.95 by custom code:', mAP)","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:47:15.375401Z","iopub.status.idle":"2023-06-29T10:47:15.376470Z","shell.execute_reply.started":"2023-06-29T10:47:15.376230Z","shell.execute_reply":"2023-06-29T10:47:15.376256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mAP, detail_scores = mAP_calc.evaluate(thresholds=[0.6], vis=True)\nprint('segm-mAP@0.6 by custom code:', mAP)","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:47:06.755215Z","iopub.status.idle":"2023-06-29T10:47:06.757594Z","shell.execute_reply.started":"2023-06-29T10:47:06.757332Z","shell.execute_reply":"2023-06-29T10:47:06.757356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Infer on test","metadata":{}},{"cell_type":"code","source":"def encode_binary_mask(mask: np.ndarray) -> t.Text:\n    # check input mask --\n    if mask.dtype != bool:\n        raise ValueError(\n            \"encode_binary_mask expects a binary mask, received dtype == %s\" %\n            mask.dtype)\n\n    mask = np.squeeze(mask)\n    if len(mask.shape) != 2:\n        raise ValueError(\n            \"encode_binary_mask expects a 2d mask, received shape == %s\" %\n            mask.shape)\n\n    # convert input mask to expected COCO API input --\n    mask_to_encode = mask.reshape(mask.shape[0], mask.shape[1], 1)\n    mask_to_encode = mask_to_encode.astype(np.uint8)\n    mask_to_encode = np.asfortranarray(mask_to_encode)\n\n    # RLE encode mask --\n    encoded_mask = mask_util.encode(mask_to_encode)[0][\"counts\"]\n\n    # compress and base64 encoding --\n    binary_str = zlib.compress(encoded_mask, zlib.Z_BEST_COMPRESSION)\n    base64_str = base64.b64encode(binary_str)\n    return base64_str","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:47:17.562453Z","iopub.execute_input":"2023-06-29T10:47:17.562821Z","iopub.status.idle":"2023-06-29T10:47:17.570859Z","shell.execute_reply.started":"2023-06-29T10:47:17.562791Z","shell.execute_reply":"2023-06-29T10:47:17.569747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BLOOD_VESSEL_CLS = 0","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:47:17.854098Z","iopub.execute_input":"2023-06-29T10:47:17.854450Z","iopub.status.idle":"2023-06-29T10:47:17.861555Z","shell.execute_reply.started":"2023-06-29T10:47:17.854421Z","shell.execute_reply":"2023-06-29T10:47:17.860607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_path = \"/kaggle/input/hubmap-hacking-the-human-vasculature/test\"\nsample_submission = pd.read_csv('/kaggle/input/hubmap-hacking-the-human-vasculature/sample_submission.csv')\nids = []\nheights = []\nwidths = []\nprediction_strings = []\n\n\nfor test_name in tqdm(os.listdir(test_path)):\n    inp_path = os.path.join(test_path, test_name)\n    img = cv2.imread(inp_path)\n    h, w, _ = img.shape\n    pred_boxes, pred_masks, scores, pred_classes = yolo_predict(yolo_model, img, dilate_masks=False)\n\n    pred_string = \"\"\n    for i, mask in enumerate(pred_masks):\n        encoded = encode_binary_mask(mask)\n        \n        if i == 0:\n            pred_string += f\"{int(pred_classes[i])} {scores[i]} {encoded.decode('utf-8')}\"\n        else:\n            pred_string += f\" {int(pred_classes[i])} {scores[i]} {encoded.decode('utf-8')}\"\n            \n    ids.append(test_name.split('.')[0])\n    heights.append(h)\n    widths.append(w)\n    prediction_strings.append(pred_string)\n    \n#     break","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:47:19.165503Z","iopub.execute_input":"2023-06-29T10:47:19.165865Z","iopub.status.idle":"2023-06-29T10:47:19.590964Z","shell.execute_reply.started":"2023-06-29T10:47:19.165836Z","shell.execute_reply":"2023-06-29T10:47:19.590007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pd.DataFrame({'id':ids, 'height':heights, 'width':widths, \n                    'prediction_string':prediction_strings})","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:47:19.716209Z","iopub.execute_input":"2023-06-29T10:47:19.716572Z","iopub.status.idle":"2023-06-29T10:47:19.722723Z","shell.execute_reply.started":"2023-06-29T10:47:19.716529Z","shell.execute_reply":"2023-06-29T10:47:19.721531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:47:20.657479Z","iopub.execute_input":"2023-06-29T10:47:20.658248Z","iopub.status.idle":"2023-06-29T10:47:20.668654Z","shell.execute_reply.started":"2023-06-29T10:47:20.658209Z","shell.execute_reply":"2023-06-29T10:47:20.667621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-06-29T10:47:25.320383Z","iopub.execute_input":"2023-06-29T10:47:25.320755Z","iopub.status.idle":"2023-06-29T10:47:25.328604Z","shell.execute_reply.started":"2023-06-29T10:47:25.320722Z","shell.execute_reply":"2023-06-29T10:47:25.327401Z"},"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":[]}]}