{"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":"!cp -r /kaggle/input/pycocotools/ /kaggle/working/pycocotools\n!pip install -q /kaggle/working/pycocotools/pycocotools-2.0.6 --no-index --find-links=/kaggle/working/pycocotools/ \n\n!pip install -q /kaggle/input/mmdetection-wheels/mmdetection_wheels/addict-2.4.0-py3-none-any.whl\n!pip install -q /kaggle/input/mmdetection-wheels/mmdetection_wheels/terminaltables-3.1.10-py2.py3-none-any.whl\n!pip install -q /kaggle/input/mmdetection-wheels/mmdetection_wheels/mmengine-0.7.4-py3-none-any.whl\n!pip install -q /kaggle/input/mmdetection-wheels/mmdetection_wheels/mmcv-2.0.0-cp310-cp310-linux_x86_64.whl\n!pip install -q /kaggle/input/mmdetection-wheels/mmdetection_wheels/mmdet-3.0.0-py3-none-any.whl\n!pip install -q /kaggle/input/mmdetection-wheels/mmdetection_wheels/ordered_set-4.1.0-py3-none-any.whl\n!pip install -q /kaggle/input/mmdetection-wheels/mmdetection_wheels/model_index-0.1.11-py3-none-any.whl\n!pip install -q /kaggle/input/mmdetection-wheels/mmdetection_wheels/modelindex-0.0.2-py3-none-any.whl\n!pip install -q /kaggle/input/mmdetection-wheels/mmdetection_wheels/mmcls-1.0.0rc6-py2.py3-none-any.whl\n\n!pip install -q /kaggle/input/mmdetection-wheels/mmdetection_wheels/einops-0.6.1-py3-none-any.whl\n!pip install -q /kaggle/input/mmdetection-wheels/mmdetection_wheels/mat4py-0.5.0-py2.py3-none-any.whl\n!pip install -q /kaggle/input/mmdetection-wheels/mmdetection_wheels/mmpretrain-1.0.0rc8-py2.py3-none-any.whl\n\n","metadata":{"execution":{"iopub.status.busy":"2023-07-31T15:27:11.587551Z","iopub.execute_input":"2023-07-31T15:27:11.587914Z","iopub.status.idle":"2023-07-31T15:34:12.816064Z","shell.execute_reply.started":"2023-07-31T15:27:11.587879Z","shell.execute_reply":"2023-07-31T15:34:12.814852Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\nsys.path.append('/kaggle/input/ensemble-boxes/')\nfrom ensemble_boxes_wbf_index import weighted_boxes_fusion_index","metadata":{"execution":{"iopub.status.busy":"2023-07-31T15:34:12.822265Z","iopub.execute_input":"2023-07-31T15:34:12.824525Z","iopub.status.idle":"2023-07-31T15:34:12.844829Z","shell.execute_reply.started":"2023-07-31T15:34:12.824482Z","shell.execute_reply":"2023-07-31T15:34:12.844094Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from mmengine.config import Config, ConfigDict\nfrom mmcv.transforms import Compose\nfrom mmdet.apis import init_detector, inference_detector\n\nimport torch\nimport torch.nn as nn\nfrom torchvision.ops import nms\nimport cv2\nfrom cv2 import dilate\nimport matplotlib.pyplot as plt\nimport pandas as pd\nfrom tqdm import tqdm\nfrom pathlib import Path\nimport json\n# from skimage.morphology import binary_dilation\n\nfrom collections import defaultdict\n\nimport base64\nimport numpy as np\nfrom pycocotools import _mask as coco_mask\nimport typing as t\nimport zlib","metadata":{"execution":{"iopub.status.busy":"2023-07-31T15:34:12.848821Z","iopub.execute_input":"2023-07-31T15:34:12.85103Z","iopub.status.idle":"2023-07-31T15:34:19.011035Z","shell.execute_reply.started":"2023-07-31T15:34:12.850997Z","shell.execute_reply":"2023-07-31T15:34:19.009973Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:\n    test_img_dir_path = Path('/kaggle/input/hubmap-hacking-the-human-vasculature/test/')\n    test_img_paths = sorted(test_img_dir_path.iterdir())\n\n    test_polygons_jsonl_path = Path('/kaggle/input/hubmap-hacking-the-human-vasculature/polygons.jsonl')\n\n    config_file_paths = [\n        Path('/kaggle/input/cascade-mask-rcnn-convnext-t-v6/cascade_mask_rcnn_convnext_t_v6.py'),\n        Path('/kaggle/input/cascade-mask-rcnn-convnextv2-b-v1/cascade_mask_rcnn_convnextv2_b_v1.py'),\n        Path('/kaggle/input/cascade-mask-rcnn-convnext-t-v24/cascade_mask_rcnn_convnext_t_v24.py'),\n        Path('/kaggle/input/cascade-mask-rcnn-convnextv2-b-v0/cascade_mask_rcnn_convnextv2_b_v0.py'),\n    ]\n    checkpoint_file_paths = [\n        Path('/kaggle/input/cascade-mask-rcnn-convnext-t-v6/fold1_best_coco_segm_mAP_epoch_10.pth'),\n        Path('/kaggle/input/cascade-mask-rcnn-convnextv2-b-v1/fold0_best_coco_segm_mAP_epoch_13.pth'),\n        Path('/kaggle/input/cascade-mask-rcnn-convnext-t-v24/fold1_best_coco_segm_mAP_epoch_8.pth'),\n        Path('/kaggle/input/cascade-mask-rcnn-convnextv2-b-v0/fold0_best_coco_segm_mAP_epoch_14.pth'),\n    ]\n    ","metadata":{"execution":{"iopub.status.busy":"2023-07-31T15:34:19.01363Z","iopub.execute_input":"2023-07-31T15:34:19.013983Z","iopub.status.idle":"2023-07-31T15:34:19.023777Z","shell.execute_reply.started":"2023-07-31T15:34:19.013949Z","shell.execute_reply":"2023-07-31T15:34:19.022612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def encode_binary_mask(mask: np.ndarray) -> t.Text:\n    \"\"\"Converts a binary mask into OID challenge encoding ascii text.\"\"\"\n\n    # check input mask --\n    if mask.dtype != np.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 = coco_mask.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-07-31T15:34:19.025553Z","iopub.execute_input":"2023-07-31T15:34:19.026063Z","iopub.status.idle":"2023-07-31T15:34:19.036407Z","shell.execute_reply.started":"2023-07-31T15:34:19.026012Z","shell.execute_reply":"2023-07-31T15:34:19.035471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_img_polygons = {}\nwith open(CFG.test_polygons_jsonl_path, \"r\") as file:\n    for line in file:\n        data = json.loads(line)\n        test_img_polygons[data['id']] = data['annotations']","metadata":{"execution":{"iopub.status.busy":"2023-07-31T15:34:19.03765Z","iopub.execute_input":"2023-07-31T15:34:19.038729Z","iopub.status.idle":"2023-07-31T15:34:23.503467Z","shell.execute_reply.started":"2023-07-31T15:34:19.038695Z","shell.execute_reply":"2023-07-31T15:34:23.502473Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_0_cfg = Config.fromfile(CFG.config_file_paths[0])\nmodel_1_cfg = Config.fromfile(CFG.config_file_paths[1])\nmodel_2_cfg = Config.fromfile(CFG.config_file_paths[2])\nmodel_3_cfg = Config.fromfile(CFG.config_file_paths[3])\n\nmodel_0_cfg.model.test_cfg.rcnn.mask_thr_binary = 0.4\nmodel_0_cfg.model.test_cfg.rcnn.score_thr = 0.005\n\nmodel_1_cfg.model.test_cfg.rcnn.mask_thr_binary = 0.4\nmodel_1_cfg.model.test_cfg.rcnn.score_thr = 0.005\n\nmodel_2_cfg.model.test_cfg.rcnn.mask_thr_binary = 0.4\nmodel_2_cfg.model.test_cfg.rcnn.score_thr = 0.005\n\nmodel_3_cfg.model.test_cfg.rcnn.mask_thr_binary = 0.4\nmodel_3_cfg.model.test_cfg.rcnn.score_thr = 0.005\n\nmodels = [\n    init_detector(\n        config = model_0_cfg,\n        checkpoint = str(CFG.checkpoint_file_paths[0]),\n        device='cuda:0'\n    ),\n    init_detector(\n        config = model_1_cfg,\n        checkpoint = str(CFG.checkpoint_file_paths[1]),\n        device='cuda:0'\n    ),\n    init_detector(\n        config = model_2_cfg,\n        checkpoint = str(CFG.checkpoint_file_paths[2]),\n        device='cuda:0'\n    ),\n    init_detector(\n        config = model_3_cfg,\n        checkpoint = str(CFG.checkpoint_file_paths[3]),\n        device='cuda:0'\n    ),\n]","metadata":{"execution":{"iopub.status.busy":"2023-07-31T15:34:23.504789Z","iopub.execute_input":"2023-07-31T15:34:23.505167Z","iopub.status.idle":"2023-07-31T15:35:03.042762Z","shell.execute_reply.started":"2023-07-31T15:34:23.505134Z","shell.execute_reply":"2023-07-31T15:35:03.041774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"scales = [(544, 544), (576, 576), (608, 608), (640, 640), (672, 672), (704, 704)]\n\nids = []\nheights = []\nwidths = []\nprediction_strings = []\n\nfor img_path in tqdm(CFG.test_img_paths, total=len(CFG.test_img_paths)):\n    id = str(img_path).split('/')[-1].split('.')[0]\n    \n    height, width = None, None\n    \n    num_models = len(models)\n    bboxes = [[] for _ in range(num_models)]\n    scores = [[] for _ in range(num_models)]\n    masks = [[] for _ in range(num_models)]\n    \n    for idx_model, model in enumerate(models):\n        for scale in scales:\n            test_pipeline = Compose([\n                dict(type='LoadImageFromFile', backend_args=None),\n                dict(type='Resize', scale=scale, keep_ratio=True),\n                dict(\n                    type='PackDetInputs',\n                    meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                            'scale_factor'))\n            ])\n            pred = inference_detector(model=model, imgs=img_path, test_pipeline=test_pipeline)\n\n            height, width = pred.ori_shape\n            bboxes[idx_model] += [[bbox[0]/width, bbox[1]/width, bbox[2]/height, bbox[3]/height] for bbox in pred.pred_instances.bboxes]\n            scores[idx_model] += pred.pred_instances.scores\n            masks[idx_model] += pred.pred_instances.masks\n    \n\n    prediction_string = ''\n\n    labels = [[0 for j in range(len(bboxes[i]))] for i in range(num_models)]\n    if sum([len(bboxes[i]) for i in range(num_models)])>0:\n        wbf_boxes, wbf_scores, _, wbf_org_indexes = weighted_boxes_fusion_index(bboxes, scores, labels, weights=None, iou_thr=0.48, conf_type='max')\n        \n        glomerulus_mask = np.full((height, width), 1, dtype=np.uint8)\n        if id in test_img_polygons:\n            annos = test_img_polygons[id]\n            for anno in annos:\n                if anno['type'] != 'glomerulus':\n                    continue\n                for coord in anno['coordinates']:\n                    cv2.fillPoly(glomerulus_mask, [np.array(coord)], 0)\n        \n        for i in range(len(wbf_boxes)):\n            score = wbf_scores[i]\n#             box = wbf_boxes[i]\n\n#             x1, y1, x2, y2 = int(box[0]*width), int(box[1]*height), int(box[2]*width), int(box[3]*height)\n#             box_mask = np.zeros((height, width), dtype=np.uint8)\n#             box_mask[y1:y2+1, x1:x2+1] = 1\n\n            mask = np.full((height, width), 0, dtype=np.uint8)\n            for idx_model, pred_idx in wbf_org_indexes[i]:\n                tmp_mask = masks[idx_model][pred_idx].cpu().numpy()\n                mask += tmp_mask\n                \n            mask = (mask >= (len(wbf_org_indexes[i])*0.5)).astype(np.uint8)\n            \n#             mask = mask * box_mask\n            \n#             kernel = np.ones((3, 3), np.uint8)\n#             mask = dilate(mask, kernel)\n  \n            \n            mask = (mask * glomerulus_mask).astype(np.bool_)\n            \n            if np.sum(mask) < 100:\n                continue\n            \n            mask_encoded = encode_binary_mask(mask)\n            mask_str = mask_encoded.decode('utf-8')\n            prediction_string += f' 0 {score} {mask_str}'\n    \n    ids.append(id)\n    heights.append(height)\n    widths.append(width)\n    prediction_strings.append(prediction_string.lstrip())\n    \nsubmission = pd.DataFrame()\nsubmission['id'] = ids\nsubmission['height'] = heights\nsubmission['width'] = widths\nsubmission['prediction_string'] = prediction_strings\n\nsubmission = submission.set_index('id')\nsubmission.to_csv(\"/kaggle/working/submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-07-31T15:41:43.430734Z","iopub.execute_input":"2023-07-31T15:41:43.431152Z","iopub.status.idle":"2023-07-31T15:41:50.826102Z","shell.execute_reply.started":"2023-07-31T15:41:43.431118Z","shell.execute_reply":"2023-07-31T15:41:50.824983Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !cat /kaggle/working/submission.csv","metadata":{"execution":{"iopub.status.busy":"2023-07-31T15:41:54.803725Z","iopub.execute_input":"2023-07-31T15:41:54.804168Z","iopub.status.idle":"2023-07-31T15:41:54.809358Z","shell.execute_reply.started":"2023-07-31T15:41:54.804127Z","shell.execute_reply":"2023-07-31T15:41:54.808181Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}