{"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":"markdown","source":"# Install and Import Libs","metadata":{}},{"cell_type":"code","source":"import os, glob\nimport sys\nimport json\nfrom PIL import Image\nfrom collections import Counter\nimport gc\nimport numpy as np\nimport pandas as pd\nimport plotly.express as px\nimport plotly.graph_objects as go\nimport tifffile as tiff\nimport matplotlib.pyplot as plt\nfrom tqdm.auto import tqdm\nimport torch\nimport cv2\n\nimport pandas as pd\n\nsys.path.append(\"/kaggle/input/detection-wheel\")","metadata":{"papermill":{"duration":5.190139,"end_time":"2023-07-25T11:34:43.392048","exception":false,"start_time":"2023-07-25T11:34:38.201909","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:03:32.992430Z","iopub.execute_input":"2023-08-10T14:03:32.993133Z","iopub.status.idle":"2023-08-10T14:03:35.672429Z","shell.execute_reply.started":"2023-08-10T14:03:32.993097Z","shell.execute_reply":"2023-08-10T14:03:35.671421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Install pycocotools package\n\n!mkdir /kaggle/working/packages\n!cp -r /kaggle/input/pycocotools/* /kaggle/working/packages\nos.chdir(\"/kaggle/working/packages/pycocotools-2.0.6/\")\n!python setup.py install -q\n!pip install . --no-index --find-links /kaggle/working/packages/ -q\n\n\n!pip install /kaggle/input/mmdetection-2-26-0/mmdetection-2-26-0/addict-2.4.0-py3-none-any.whl\n!pip install /kaggle/input/mmdetection-2-26-0/mmdetection-2-26-0/yapf-0.32.0-py2.py3-none-any.whl\n!pip install /kaggle/input/mmdetection-2-26-0/mmdetection-2-26-0/terminal-0.4.0-py3-none-any.whl\n!pip install /kaggle/input/mmdetection-2-26-0/mmdetection-2-26-0/terminaltables-3.1.10-py2.py3-none-any.whl\n\n!pip install /kaggle/input/mmdet3-wheels/mmcv_full-1.7.1-cp310-cp310-linux_x86_64.whl\n","metadata":{"papermill":{"duration":207.331596,"end_time":"2023-07-25T11:38:11.705498","exception":false,"start_time":"2023-07-25T11:34:44.373902","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:03:35.674219Z","iopub.execute_input":"2023-08-10T14:03:35.674978Z","iopub.status.idle":"2023-08-10T14:07:05.680083Z","shell.execute_reply.started":"2023-08-10T14:03:35.674941Z","shell.execute_reply":"2023-08-10T14:07:05.678882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cp -r /kaggle/input/mmdet2281/mmdetection /kaggle/working/\n%cd /kaggle/working/mmdetection","metadata":{"papermill":{"duration":8.346066,"end_time":"2023-07-25T11:38:20.064161","exception":false,"start_time":"2023-07-25T11:38:11.718095","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:07:05.682934Z","iopub.execute_input":"2023-08-10T14:07:05.683345Z","iopub.status.idle":"2023-08-10T14:07:11.226281Z","shell.execute_reply.started":"2023-08-10T14:07:05.683305Z","shell.execute_reply":"2023-08-10T14:07:11.225063Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -e . --no-deps\n%cd /kaggle/working/","metadata":{"papermill":{"duration":31.252561,"end_time":"2023-07-25T11:38:51.329498","exception":false,"start_time":"2023-07-25T11:38:20.076937","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:07:11.229809Z","iopub.execute_input":"2023-08-10T14:07:11.230198Z","iopub.status.idle":"2023-08-10T14:07:42.886572Z","shell.execute_reply.started":"2023-08-10T14:07:11.230168Z","shell.execute_reply":"2023-08-10T14:07:42.885327Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sys.path.append(\"/kaggle/input/mmdet2281/mmdetection\")","metadata":{"papermill":{"duration":0.020576,"end_time":"2023-07-25T11:38:51.362846","exception":false,"start_time":"2023-07-25T11:38:51.34227","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:07:42.889964Z","iopub.execute_input":"2023-08-10T14:07:42.890273Z","iopub.status.idle":"2023-08-10T14:07:42.894978Z","shell.execute_reply.started":"2023-08-10T14:07:42.890243Z","shell.execute_reply":"2023-08-10T14:07:42.894052Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install --no-index --no-deps /kaggle/input/mmdet-2x/openmmlab-repos/openmmlab-repos/src/mmcls-0.25.0-py2.py3-none-any.whl\n!pip install --no-index --no-deps /kaggle/input/d2coat/einops-0.6.1-py3-none-any.whl","metadata":{"papermill":{"duration":2.624672,"end_time":"2023-07-25T11:38:53.999841","exception":false,"start_time":"2023-07-25T11:38:51.375169","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:07:42.896245Z","iopub.execute_input":"2023-08-10T14:07:42.896588Z","iopub.status.idle":"2023-08-10T14:07:47.793215Z","shell.execute_reply.started":"2023-08-10T14:07:42.896558Z","shell.execute_reply":"2023-08-10T14:07:47.792029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport numpy as np\nimport torch\nfrom PIL import Image\nfrom mmdet.apis import init_detector, inference_detector,show_result_pyplot, set_random_seed\nfrom mmcv import Config\nimport mmcv\nfrom pathlib import Path\nfrom collections import defaultdict","metadata":{"papermill":{"duration":5.140876,"end_time":"2023-07-25T11:39:01.208997","exception":false,"start_time":"2023-07-25T11:38:56.068121","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:07:47.795608Z","iopub.execute_input":"2023-08-10T14:07:47.795995Z","iopub.status.idle":"2023-08-10T14:07:53.557313Z","shell.execute_reply.started":"2023-08-10T14:07:47.795958Z","shell.execute_reply":"2023-08-10T14:07:53.556339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Helpers","metadata":{}},{"cell_type":"code","source":"import base64\nimport numpy as np\nfrom pycocotools import _mask as coco_mask\nimport pycocotools.mask as mask_util\nimport typing as t\nimport zlib\n\ndef 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":{"papermill":{"duration":0.026122,"end_time":"2023-07-25T11:39:01.282308","exception":false,"start_time":"2023-07-25T11:39:01.256186","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:07:53.559039Z","iopub.execute_input":"2023-08-10T14:07:53.559394Z","iopub.status.idle":"2023-08-10T14:07:53.568592Z","shell.execute_reply.started":"2023-08-10T14:07:53.559346Z","shell.execute_reply":"2023-08-10T14:07:53.567664Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Merge tiles","metadata":{}},{"cell_type":"code","source":"import json, cv2, numpy as np, itertools, random, pandas as pd\n\nimport matplotlib.pyplot as plt\nfrom pathlib import Path\n","metadata":{"execution":{"iopub.status.busy":"2023-08-10T14:07:53.570053Z","iopub.execute_input":"2023-08-10T14:07:53.572106Z","iopub.status.idle":"2023-08-10T14:07:53.587762Z","shell.execute_reply.started":"2023-08-10T14:07:53.572071Z","shell.execute_reply":"2023-08-10T14:07:53.586745Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_jsonl(path):\n    infos = []\n    with open(path, mode=\"r\", encoding=\"utf-8\") as f:\n        for line in f:\n            infos.append(json.loads(line))\n\n    return infos\n\ndef load_json(path):\n    with open(path, mode='r', encoding='utf-8') as f:\n        json_dict = json.load(f)\n        f.close()\n    return json_dict\n\ndef show_image(img, to_rgb=True):\n    if to_rgb:\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    plt.figure(figsize=(5, 5))\n    plt.imshow(img)\n    plt.show()\n    \ndef show_mask(img):\n    plt.figure(figsize=(5, 5))\n    plt.imshow(img, cmap=\"gray\")\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-08-10T14:07:53.592541Z","iopub.execute_input":"2023-08-10T14:07:53.592818Z","iopub.status.idle":"2023-08-10T14:07:53.602394Z","shell.execute_reply.started":"2023-08-10T14:07:53.592795Z","shell.execute_reply":"2023-08-10T14:07:53.601527Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_coords(center_i, center_j, step_size):\n    \n    center_x, center_y =center_i, center_j\n\n    coord_11 = (center_x - step_size, center_y - step_size)\n    coord_12 = (center_x            , center_y - step_size)\n    coord_13 = (center_x + step_size, center_y - step_size)\n\n    coord_21 = (center_x - step_size, center_y)\n    coord_22 = (center_x            , center_y)\n    coord_23 = (center_x + step_size, center_y)\n\n    coord_31 = (center_x - step_size, center_y + step_size)\n    coord_32 = (center_x            , center_y + step_size)\n    coord_33 = (center_x + step_size, center_y + step_size)\n\n    all_coords = [[coord_11, coord_12, coord_13], [coord_21, coord_22, coord_23], [coord_31, coord_32, coord_33]]\n    base_coords = [[(0, 0),             (step_size, 0),             (step_size*2, 0)], \n                [(0, step_size),     (step_size, step_size),     (step_size*2, step_size)], \n                [(0, step_size * 2), (step_size, step_size * 2), (step_size*2, step_size * 2)]]\n    \n    return all_coords, base_coords","metadata":{"execution":{"iopub.status.busy":"2023-08-10T14:07:53.604104Z","iopub.execute_input":"2023-08-10T14:07:53.604561Z","iopub.status.idle":"2023-08-10T14:07:53.615639Z","shell.execute_reply.started":"2023-08-10T14:07:53.604530Z","shell.execute_reply":"2023-08-10T14:07:53.614687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"STEP_SIZE = 512\nTARGET_SHAPE = (512 * 3, 512 * 3)\nDEFAULT_SHAPE = (512, 512)\nIMG_ROOT = Path('/kaggle/input/hubmap-hacking-the-human-vasculature/test/')\n# IMG_ROOT = Path('/kaggle/input/hubmap-hacking-the-human-vasculature/train/')\nIMG_EXT = \".tif\"\n","metadata":{"execution":{"iopub.status.busy":"2023-08-10T14:07:53.616911Z","iopub.execute_input":"2023-08-10T14:07:53.617318Z","iopub.status.idle":"2023-08-10T14:07:53.633135Z","shell.execute_reply.started":"2023-08-10T14:07:53.617275Z","shell.execute_reply":"2023-08-10T14:07:53.632154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"xdata_infos = []\njsonl_file_path = \"/kaggle/input/hubmap-hacking-the-human-vasculature/polygons.jsonl\"\nwith open(jsonl_file_path, \"r\") as file:\n    for line in file:\n        xdata_infos.append(json.loads(line))\n\npolygon_infos = dict(map(lambda x: (x[\"id\"], x[\"annotations\"]), xdata_infos))","metadata":{"execution":{"iopub.status.busy":"2023-08-10T14:07:53.634586Z","iopub.execute_input":"2023-08-10T14:07:53.634962Z","iopub.status.idle":"2023-08-10T14:07:58.539583Z","shell.execute_reply.started":"2023-08-10T14:07:53.634931Z","shell.execute_reply":"2023-08-10T14:07:58.538579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta_df_path = Path(\"/kaggle/input/hubmap-hacking-the-human-vasculature/tile_meta.csv\")\ndf = pd.read_csv(meta_df_path)\n\ndf[\"d_w\"] = df.apply(lambda x: (x[\"dataset\"], x[\"source_wsi\"]), axis = 1)\ndf[\"coord\"] = df.apply(lambda x: (x[\"i\"], x[\"j\"]), axis = 1)\ndf = df[[\"coord\", \"id\", \"d_w\"]]\n\ndf_ref = df[[\"d_w\", \"id\"]]\nstem2dw = df_ref.set_index(\"id\", drop=True)\nstem2dw = stem2dw.to_dict()[\"d_w\"]\n\ndf_infos  = list(info for info in df.groupby(\"d_w\"))\ndw2infors = dict()\nfor df_info in df_infos:\n    d_w = df_info[0]\n    info = df_info[1]\n    df_ref = info[[\"coord\", \"id\"]]\n    \n    stem2coords = df_ref.set_index(\"id\", drop=True)\n    stem2coords = stem2coords.to_dict()[\"coord\"]\n    \n    coords2stem = df_ref.set_index(\"coord\", drop=True)\n    coords2stem = coords2stem.to_dict()[\"id\"]\n    \n    dw2infors[d_w] = dict(coords2stem=coords2stem, stem2coords=stem2coords)\n    ","metadata":{"execution":{"iopub.status.busy":"2023-08-10T14:07:58.540890Z","iopub.execute_input":"2023-08-10T14:07:58.541746Z","iopub.status.idle":"2023-08-10T14:07:58.838262Z","shell.execute_reply.started":"2023-08-10T14:07:58.541712Z","shell.execute_reply":"2023-08-10T14:07:58.837290Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_fake_9tiles(img):\n    fake_tile = np.ones((*TARGET_SHAPE, 3), dtype=img.dtype) * 128\n    fake_tile[STEP_SIZE:STEP_SIZE*2,STEP_SIZE:STEP_SIZE*2,:] = img\n    return fake_tile\n\ndef get_9tiles(img_stem, img):\n    try:\n        d_w = stem2dw.get(img_stem, None)\n\n        if d_w is None:\n            return create_fake_9tiles(img)\n\n        cur_info = dw2infors.get(d_w, None)\n\n        center_coord = cur_info[\"stem2coords\"][img_stem]\n\n        all_coords, base_coords = get_coords(center_coord[0], center_coord[1], STEP_SIZE)\n\n        infer_regions = []\n\n        for coords, bases in zip(all_coords, base_coords):\n            infer_tiles = []\n            for coord, base_o in zip(coords, bases):\n                ids = cur_info[\"coords2stem\"].get(coord, None)\n                infer_info = (ids, base_o)\n                if ids is None:\n                    infer_tile = np.ones((*DEFAULT_SHAPE, 3), dtype=img.dtype) * 128\n                else:\n                    img_path = IMG_ROOT.joinpath(f\"{ids}{IMG_EXT}\")\n                    infer_tile = cv2.imread(str(img_path))\n                infer_tiles.append(infer_tile)\n\n            infer_sub_region = cv2.hconcat(infer_tiles)\n\n            infer_regions.append(infer_sub_region)\n\n        merged_infer_9tile = cv2.vconcat(infer_regions)\n    except:\n        merged_infer_9tile = create_fake_9tiles(img)\n    \n    return merged_infer_9tile","metadata":{"execution":{"iopub.status.busy":"2023-08-10T14:07:58.839852Z","iopub.execute_input":"2023-08-10T14:07:58.840184Z","iopub.status.idle":"2023-08-10T14:07:58.851151Z","shell.execute_reply.started":"2023-08-10T14:07:58.840154Z","shell.execute_reply":"2023-08-10T14:07:58.850027Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def crop_full_tile(img, margin=128):\n    base_size = 512\n    img_h, img_w = img.shape[:2]\n    assert img_h == base_size * 3\n    assert img_w == base_size * 3\n    crop_h, crop_w = base_size + margin * 2, base_size + margin * 2\n    x0 = base_size - margin\n    y0 = base_size - margin\n\n    x1 = x0 + crop_w\n    y1 = y0 + crop_h\n    center_region = img[y0:y1, x0:x1]\n    bbox = [x0, y0, x1, y1]\n    return center_region\n","metadata":{"execution":{"iopub.status.busy":"2023-08-10T14:07:58.852911Z","iopub.execute_input":"2023-08-10T14:07:58.853253Z","iopub.status.idle":"2023-08-10T14:07:58.869960Z","shell.execute_reply.started":"2023-08-10T14:07:58.853221Z","shell.execute_reply":"2023-08-10T14:07:58.868942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Post-Processing Helpers","metadata":{}},{"cell_type":"code","source":"def coordinates_to_masks(coordinates, shape):\n    masks = []\n    for coord in coordinates:\n        mask = np.zeros(shape, dtype=np.uint8)\n        cv2.fillPoly(mask, [np.array(coord)], 1)\n        masks.append(mask)\n    return masks\n\n\ndef coordinate_to_mask(coordinate, shape):\n    mask = np.zeros(shape, dtype=np.uint8)\n    cv2.fillPoly(mask, [np.array(coordinate)], 1)\n    return mask\n\n\ndef lstsegm2mask(lstsegm, shape):\n    mask = np.zeros(shape, dtype=np.uint8)\n    for coordinates in lstsegm:\n        for coord in coordinates:\n            cv2.fillPoly(mask, [np.array(coord)], 1)\n    return mask   \n\n\ndef check_cropable(bbox, img_shape, bound):\n    im_h, im_w = img_shape\n    x_min = bound\n    x_max = im_w - bound\n\n    y_min = bound\n    y_max = im_h - bound\n\n    x1, y1, x2, y2 = bbox\n\n    if x1 >= x_min and x2 <= x_max and y1 >= y_min and y2 <= y_max:\n        return False\n    \n    return True     \n\n\ndef crop_result_tiles(result, margin=128, base=512, pixel_thresh=32, filter_multi=False):\n    res_results = []\n    for bbox_results, mask_results in result:\n        res_bbox_results, res_mask_results = [], []\n        for bbox_result, mask_result in zip(bbox_results, mask_results):\n            bboxs = bbox_result\n            masks = np.array(mask_result)\n            \n            crop_masks = masks[:, margin:margin+base, margin:margin+base]\n            fg_pixels = np.sum(crop_masks.reshape(crop_masks.shape[0], -1), axis=-1)\n            idxs = fg_pixels > pixel_thresh\n            masks = crop_masks[idxs]\n            bboxs = bboxs[idxs]\n            \n            bboxs[:, 0] -= margin\n            bboxs[:, 1] -= margin\n            bboxs[:, 2] -= margin\n            bboxs[:, 3] -= margin\n            bboxs = np.clip(bboxs, 0, base)\n            \n            new_masks = []\n            new_bboxs = []\n\n            for bbox, mask in zip(bboxs, masks):\n                if filter_multi:\n                    ys, xs = np.where(mask)\n                    x1, x2 = min(xs), max(xs)\n                    y1, y2 = min(ys), max(ys)\n                    mask_bbox = [x1, y1, x2, y2]\n                    \n                    if not check_cropable(mask_bbox, mask.shape, bound=2):\n                        new_masks.append(mask)\n                        new_bboxs.append(bbox)\n                        continue\n                \n                contours, _ = cv2.findContours(mask.astype(np.uint8), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)\n                \n                if len(contours) == 1:\n                    new_masks.append(mask)\n                    new_bboxs.append(bbox)\n                else:\n                    # show_mask(mask)\n                    insts = [np.transpose(inst, (1, 0, 2)).tolist() for inst in contours]\n                    \n                    mask_size = list(map(lambda x: np.array(x).size, insts))\n                    # print(mask_size)\n                    max_ids = np.argmax(mask_size)\n                    inst = insts[max_ids]\n\n                    new_mask = coordinate_to_mask(inst, shape=(base, base))\n                    new_mask = new_mask.astype(np.bool_)\n                    num_fg = np.sum(new_mask.astype(np.uint8))\n                    if num_fg > pixel_thresh:\n                        ys, xs = np.where(new_mask)\n                        x1, x2 = min(xs), max(xs)\n                        y1, y2 = min(ys), max(ys)\n                        new_bbox = np.array([x1, y1, x2, y2, bbox[-1]], dtype=np.float32)\n                        new_masks.append(new_mask)\n                        new_bboxs.append(new_bbox)\n            \n            new_bboxs = np.array(new_bboxs)\n            \n            res_bbox_results.append(new_bboxs)\n            res_mask_results.append(new_masks)\n        res_results.append((res_bbox_results, res_mask_results))\n    return res_results \n    ","metadata":{"execution":{"iopub.status.busy":"2023-08-10T14:07:58.872342Z","iopub.execute_input":"2023-08-10T14:07:58.873042Z","iopub.status.idle":"2023-08-10T14:07:58.895386Z","shell.execute_reply.started":"2023-08-10T14:07:58.873009Z","shell.execute_reply":"2023-08-10T14:07:58.894177Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\n\ndef calculate_iou(mask1, mask2):\n    intersection = np.logical_and(mask1, mask2)\n    union = np.logical_or(mask1, mask2)\n    iou = np.sum(intersection) / np.sum(union)\n    return iou\n\n# Modified from https://www.kaggle.com/code/theoviel/sartorius-inference-final\ndef masking_nms(masks, scores, bboxs, iou_threshold=0.5, q_ins_factor=0):\n    \"\"\"\n    NMS with masks.\n    Removes more masks than the tweaking fct.\n    \"\"\"\n    order = np.argsort(scores)[::-1]\n    masks = masks[order]\n    scores = scores[order]\n    bboxs = bboxs[order]\n\n    rle_pred = [mask_util.encode(np.asarray(m, order='F')) for m in masks]\n    ious = mask_util.iou(rle_pred, rle_pred, [0] * len(rle_pred))\n\n    picks = []\n    idxs = list(range(len(ious)))\n    # removed = []\n    num_ovls = []\n\n    while len(idxs) > 0:\n        idx = idxs[0]\n        overlapping = np.where(ious[idx] > iou_threshold)[0]\n\n        # removed += [v for v in overlapping if v > idx]\n\n        if len(overlapping):\n            num_ovls.append(len(overlapping))\n            picks.append(idx)\n            idxs = [i for i in idxs if i not in overlapping]\n        else:\n            idxs = idxs[1:]\n\n    if q_ins_factor > 0:\n        num_ovls = np.array(num_ovls)\n        density = np.unique(num_ovls)\n        ovl_thresh = max(int(np.quantile(density, q_ins_factor)), 1)\n        picks = np.array(picks)\n\n        ids = num_ovls > ovl_thresh\n        picks = picks[ids]\n        picks = picks.tolist()\n\n\n    masks = masks[picks]\n    scores = scores[picks]\n    bboxs = bboxs[picks]\n    \n    return masks, scores, bboxs","metadata":{"papermill":{"duration":0.030473,"end_time":"2023-07-25T11:39:01.325463","exception":false,"start_time":"2023-07-25T11:39:01.29499","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:07:58.897364Z","iopub.execute_input":"2023-08-10T14:07:58.898073Z","iopub.status.idle":"2023-08-10T14:07:58.913944Z","shell.execute_reply.started":"2023-08-10T14:07:58.898041Z","shell.execute_reply":"2023-08-10T14:07:58.912839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')\nset_random_seed(0, deterministic=False)\n\nMAX_PER_IMG = 100\ndef load_model(model_info):\n    cfg = Config.fromfile(model_info['cf_path'])\n    \n    cfg.data.test.pipeline[1].img_scale = model_info[\"cfg_info\"][\"img_scale\"]\n    cfg.model.test_cfg.rcnn.score_thr = model_info[\"cfg_info\"][\"rcnn_score_thr\"]\n    max_per_img = model_info[\"cfg_info\"].get(\"max_per_img\", MAX_PER_IMG)\n    cfg.model.test_cfg.rcnn.max_per_img = max_per_img\n    \n    \n    model = init_detector(cfg, model_info['ckpt_path'], device=device)\n    model.eval()\n    return model","metadata":{"papermill":{"duration":0.021409,"end_time":"2023-07-25T11:39:01.429933","exception":false,"start_time":"2023-07-25T11:39:01.408524","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:07:58.948059Z","iopub.execute_input":"2023-08-10T14:07:58.949091Z","iopub.status.idle":"2023-08-10T14:07:58.956472Z","shell.execute_reply.started":"2023-08-10T14:07:58.949058Z","shell.execute_reply":"2023-08-10T14:07:58.955602Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def ensemble_instance(list_preds, num_classes):\n    res_bbox_results, res_mask_results = [], []\n    for x_pred in list_preds:\n        bboxes, masks = x_pred\n        res_bbox_results.append(bboxes)\n        res_mask_results.append(masks)\n    \n    ensemble_bboxes = [[]] * NUM_CLASSES\n    ensemble_masks = [[]] * NUM_CLASSES\n    \n    for idx in range(len(ensemble_bboxes)):\n        res_bboxes = []\n        for res_bbox in res_bbox_results:\n            res_bboxes.append(res_bbox[idx])\n            \n        en_bboxes = np.concatenate(res_bboxes, axis=0)\n        \n        res_masks = []\n\n        for res_mask in res_mask_results:\n            np_res_mask = np.array(res_mask[idx])\n            if np.size(np_res_mask) == 0:\n                continue\n            res_masks.append(np_res_mask)\n        if len(res_masks) > 0:\n            en_masks = np.concatenate(res_masks, axis=0)\n            en_masks = [en_m for en_m in en_masks]\n        else:\n            en_masks = [[]]\n\n        ensemble_bboxes[idx] = en_bboxes\n        ensemble_masks[idx] = en_masks\n    \n    return (ensemble_bboxes, ensemble_masks)","metadata":{"papermill":{"duration":0.024041,"end_time":"2023-07-25T11:39:01.466576","exception":false,"start_time":"2023-07-25T11:39:01.442535","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:07:58.959713Z","iopub.execute_input":"2023-08-10T14:07:58.959978Z","iopub.status.idle":"2023-08-10T14:07:58.973324Z","shell.execute_reply.started":"2023-08-10T14:07:58.959956Z","shell.execute_reply":"2023-08-10T14:07:58.972160Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def coordinate_to_mask(coordinate, shape):\n    mask = np.zeros(shape, dtype=np.uint8)\n    cv2.fillPoly(mask, [np.array(coordinate)], 1)\n    return mask\n\n\ndef lstsegm2mask(lstsegm, shape):\n    mask = np.zeros(shape, dtype=np.uint8)\n    for coordinates in lstsegm:\n        for coord in coordinates:\n            cv2.fillPoly(mask, [np.array(coord)], 1)\n    return mask   \n\n\ndef get_glo_mask(anno_id, polygon_infos, img_h, img_w):\n    target_shape = (img_h, img_w)\n    \n    info = polygon_infos.get(anno_id, None)\n    if info is None:\n        return None \n    \n    glomerulus_infos = list(filter(lambda x: x[\"type\"] == \"glomerulus\", info))\n    \n    if len(glomerulus_infos) == 0:\n        return None\n    else:\n        all_glos = list(map(lambda x: x[\"coordinates\"], glomerulus_infos))\n        glo_mask = lstsegm2mask(all_glos, target_shape)\n        \n        glo_mask = glo_mask.astype(np.bool_)\n        \n    return glo_mask\n\n\ndef filter_overlap_glo(masks, bboxs, glo_mask, img_shape, glom_ovl_thresh):\n    masks = np.array(masks)\n    \n    rle_pred = [mask_util.encode(np.asarray(m, order='F')) for m in masks]\n    rle_glo = [mask_util.encode(np.asarray(glo_mask, order='F'))]\n    \n    ious = mask_util.iou(rle_pred, rle_glo, [0] * len(rle_glo))\n    ious = np.squeeze(ious, axis=-1)\n    \n    non_ovl_masks = masks[ious == 0]\n    non_ovl_bboxs = bboxs[ious == 0]\n    \n    ovl_masks = masks[ious > 0]\n    ovl_bboxs = bboxs[ious > 0]\n    \n    \n    if len(ovl_masks) == 0:\n        non_ovl_masks = [mask for mask in non_ovl_masks]\n        return non_ovl_masks, non_ovl_bboxs\n    \n    corrected_ovl_masks = []\n    corrected_ovl_bboxs = []\n    \n    for ovl_mask, ovl_bbox in zip(ovl_masks, ovl_bboxs):\n        ovl_conf = ovl_bbox[-1]\n        \n        filtered_mask = np.logical_and(np.logical_xor(ovl_mask, glo_mask), ovl_mask)\n        \n        if (np.sum(ovl_mask) - np.sum(filtered_mask)) / np.sum(ovl_mask) > glom_ovl_thresh:\n            continue\n        \n        if np.sum(filtered_mask.astype(np.uint8)) == 0:\n            continue\n        \n        corrected_ovl_masks.append(ovl_mask)\n        corrected_ovl_bboxs.append(ovl_bbox)\n        \n    \n    if len(corrected_ovl_masks) > 0:\n        corrected_ovl_masks = np.stack(corrected_ovl_masks)\n        corrected_ovl_bboxs = np.stack(corrected_ovl_bboxs)\n        # merge non_ovl and corrected_ovl\n        final_masks = np.concatenate((corrected_ovl_masks, non_ovl_masks), axis=0, dtype=np.bool_)\n        final_bboxs = np.concatenate((corrected_ovl_bboxs, non_ovl_bboxs), axis=0)\n    else:\n        final_masks = np.array(non_ovl_masks, dtype=np.bool_)\n        final_bboxs = np.array(non_ovl_bboxs)\n    \n    sorted_indices = np.argsort(final_bboxs[:, -1])[::-1]\n    final_masks = final_masks[sorted_indices]\n    final_bboxs = final_bboxs[sorted_indices]\n    \n    final_masks = [mask for mask in final_masks]      \n    \n    return final_masks, final_bboxs","metadata":{"papermill":{"duration":0.032747,"end_time":"2023-07-25T11:39:01.511873","exception":false,"start_time":"2023-07-25T11:39:01.479126","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:07:58.974761Z","iopub.execute_input":"2023-08-10T14:07:58.975326Z","iopub.status.idle":"2023-08-10T14:07:58.994040Z","shell.execute_reply.started":"2023-08-10T14:07:58.975286Z","shell.execute_reply":"2023-08-10T14:07:58.992913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def filter_candidate(masks, bboxs, quantile_factor=0.25):\n    count_pixel_mask = np.sum(masks, axis=0)\n    \n    density = np.unique(count_pixel_mask)\n    pixel_thresh = max(int(np.quantile(density, quantile_factor)), 1)\n\n    thresh_mask = count_pixel_mask <= pixel_thresh\n    \n    cand_mask = masks.astype(np.int8) - thresh_mask.astype (np.int8) > 0\n    \n    num_pxs = np.sum(cand_mask.reshape(cand_mask.shape[0], -1), axis=-1)\n    \n    ids = num_pxs > 0\n    \n    masks = masks[ids]\n    bboxs = bboxs[ids]\n    return masks, bboxs","metadata":{"execution":{"iopub.status.busy":"2023-08-10T14:07:58.995455Z","iopub.execute_input":"2023-08-10T14:07:58.995936Z","iopub.status.idle":"2023-08-10T14:07:59.010512Z","shell.execute_reply.started":"2023-08-10T14:07:58.995905Z","shell.execute_reply":"2023-08-10T14:07:59.009614Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from copy import deepcopy","metadata":{"execution":{"iopub.status.busy":"2023-08-10T14:07:59.013586Z","iopub.execute_input":"2023-08-10T14:07:59.013874Z","iopub.status.idle":"2023-08-10T14:07:59.022663Z","shell.execute_reply.started":"2023-08-10T14:07:59.013840Z","shell.execute_reply":"2023-08-10T14:07:59.021746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def filter_result(result, iou_thresh=1e-3, conf_thresh=0.01, \n                  pixel_threshs=64, glo_mask=None, img_shape=(512, 512), \n                  glom_ovl_thresh=0.1, quantile_factor=0, q_ins_factor=0):\n    res_results = []\n    for bbox_results, mask_results in result:\n        res_bbox_results, res_mask_results = [], []\n        for bbox_result, mask_result in zip(bbox_results, mask_results):\n            try:\n                # filter glomerulus\n                if glo_mask is not None:\n                    mask_result, bbox_result = filter_overlap_glo(mask_result, bbox_result, glo_mask, img_shape, glom_ovl_thresh)\n\n                bboxs = bbox_result\n                masks = np.array(mask_result)\n                # filter pixel candidate\n                if quantile_factor > 0:\n                    masks, bboxs = filter_candidate(masks, bboxs, quantile_factor=quantile_factor)\n\n                scores = bboxs[:, -1]\n\n                # conf filter\n                if conf_thresh > 0:\n                    ids = scores > conf_thresh\n                    scores = scores[ids]\n                    masks = masks[ids]\n                    bboxs = bboxs[ids]\n\n                # nms filter\n                if iou_thresh > 0:\n                    masks, scores, bboxs = masking_nms(masks, scores, bboxs, iou_threshold=iou_thresh, q_ins_factor=q_ins_factor)\n\n                if pixel_threshs > 0:\n                    # pixel filter\n                    num_inst = masks.shape[0]\n                    ids = np.sum(masks.reshape(num_inst, -1).astype(np.uint8), axis=1) > pixel_threshs\n                    masks = masks[ids]\n                    bboxs = bboxs[ids]\n\n                masks = [mask for mask in masks]\n                res_bbox_results.append(bboxs)\n                res_mask_results.append(masks)\n            except:\n                res_bbox_results.append(bbox_result)\n                res_mask_results.append(mask_result) \n\n        res_results.append((res_bbox_results, res_mask_results))\n    return res_results ","metadata":{"papermill":{"duration":0.0255,"end_time":"2023-07-25T11:39:01.549909","exception":false,"start_time":"2023-07-25T11:39:01.524409","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:08:29.557209Z","iopub.execute_input":"2023-08-10T14:08:29.557929Z","iopub.status.idle":"2023-08-10T14:08:29.569584Z","shell.execute_reply.started":"2023-08-10T14:08:29.557896Z","shell.execute_reply":"2023-08-10T14:08:29.568450Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Configs","metadata":{}},{"cell_type":"code","source":"ensemble_infos = [\n    # swin-t\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_swin_t_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/swint_d1w1l_fold0.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(640, 1333), (672, 1333), (704, 1333)],\n            'rcnn_score_thr': 0.01\n        }\n    },\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_swin_t_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/swint_d1w2l_fold2.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(736, 1333), (768, 1333), (800, 1333)],\n            'rcnn_score_thr': 0.01\n        }\n    },\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_swin_t_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/swint_d1w2r_fold3.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(736, 1333), (768, 1333), (800, 1333)],\n            'rcnn_score_thr': 0.01\n        }\n    },\n    # end swin-t\n    ####################################################################################################\n    # coat\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_coat_small_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/coat_small_ds1_w1l_fold0.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(800, 800), (896, 896), (1024, 1024)],\n            'rcnn_score_thr': 0.01\n        }\n    },\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_coat_small_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/coat_small_ds1_w2r_fold3.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(640, 1333), (672, 1333), (704, 1333)],\n            'rcnn_score_thr': 0.01\n        }\n    },\n    # end coat\n    ####################################################################################################\n    # conv-t\n\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_convnext_t_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/conv_t_d1w1r.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(736, 1333), (768, 1333), (800, 1333)],\n            'rcnn_score_thr': 0.01\n        }\n    },\n\n    # end conv-t\n    ####################################################################################################\n    # conv-s\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_convnext_s_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/conv_s_d1w2l.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(800, 800), (896, 896), (1024, 1024)],\n            'rcnn_score_thr': 0.01\n        }\n    },\n\n    # end conv-s\n    ####################################################################################################\n    # swin-t crop 128\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_swin_t_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/swint_f0d1w1l_9tiles_crop128.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(800, 800), (896, 896), (1024, 1024)],\n            'rcnn_score_thr': 0.01,\n            'max_per_img': 200\n        },\n        \"is_crop_tile\": True,\n        \"margin\": 128\n    },\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_swin_t_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/swint_f2d1w2l_9tiles_crop128.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(1280, 1280), (1333, 1333), (1024, 1024)],\n            'rcnn_score_thr': 0.01,\n             'max_per_img': 200\n        },\n        \"is_crop_tile\": True,\n        \"margin\": 128\n    },\n\n    ####################################################################################################\n    # coat crop 128\n\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_coat_small_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/coat_small_f1d1w1r_9tiles_crop128.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(800, 800)],\n            'rcnn_score_thr': 0.01,\n             'max_per_img': 200\n        },\n        \"is_crop_tile\": True,\n        \"margin\": 128\n    },\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_coat_small_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/coat_small_f3d1w2r_9tiles_crop128.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(800, 800), (896, 896), (1024, 1024)],\n            'rcnn_score_thr': 0.01,\n            'max_per_img': 200\n        },\n        \"is_crop_tile\": True,\n        \"margin\": 128\n    },\n    ####################################################################################################\n    # full data\n    # swin-t\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_swin_t_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/swin_t_1cls_ds1_full_ft.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(736, 1333), (768, 1333), (800, 1333)],\n            'rcnn_score_thr': 0.01\n        }\n    },\n    # coat\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_coat_small_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/coat_small_1cls_full_ft.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(640, 1333), (672, 1333), (704, 1333)],\n            'rcnn_score_thr': 0.01\n        }\n    },\n    # conv-t\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_convnext_t_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/convnext_t_1cls_full_ft.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(640, 1333), (672, 1333), (704, 1333)],\n            'rcnn_score_thr': 0.01\n        }\n    },\n    # conv-s\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_convnext_s_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/convnext_s_1cls_full_ft.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(640, 1333), (672, 1333), (704, 1333)],\n            'rcnn_score_thr': 0.01\n        }\n    },\n    ####################################################################################################\n    # full data crop128\n    # swin-t\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_swin_t_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/swin_t_1cls_full_9tiles_crop128.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(896, 896), (960, 960), (1024, 1024)],\n            'rcnn_score_thr': 0.01,\n            'max_per_img': 250\n        },\n        \"is_crop_tile\": True,\n        \"margin\": 128\n\n    },\n    # coat\n    {\n        \"cf_path\": \"/kaggle/input/hubmap-weights/cascade_mask_rcnn_coat_small_1cls.py\",\n        \"ckpt_path\": \"/kaggle/input/hubmap-weights/coat_small_1cls_full_9tiles_crop128.pth\",\n        \"cfg_info\": {\n            \"img_scale\": [(896, 896), (960, 960), (1024, 1024)],\n            'rcnn_score_thr': 0.01,\n            'max_per_img': 250\n        },\n        \"is_crop_tile\": True,\n        \"margin\": 128\n    },\n]","metadata":{"execution":{"iopub.status.busy":"2023-08-10T14:10:09.797150Z","iopub.execute_input":"2023-08-10T14:10:09.797531Z","iopub.status.idle":"2023-08-10T14:10:09.820761Z","shell.execute_reply.started":"2023-08-10T14:10:09.797500Z","shell.execute_reply":"2023-08-10T14:10:09.819666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Predicting","metadata":{}},{"cell_type":"code","source":"NUM_CLASSES = 1\nMAX_PER_IMG = 100\nensemble_results = defaultdict(list)","metadata":{"papermill":{"duration":0.020225,"end_time":"2023-07-25T11:39:01.617385","exception":false,"start_time":"2023-07-25T11:39:01.59716","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:10:11.542135Z","iopub.execute_input":"2023-08-10T14:10:11.542830Z","iopub.status.idle":"2023-08-10T14:10:11.547600Z","shell.execute_reply.started":"2023-08-10T14:10:11.542794Z","shell.execute_reply":"2023-08-10T14:10:11.546630Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# IMG_ROOT = Path('/kaggle/input/hubmap-hacking-the-human-vasculature/train/')\n# IMG_ROOT = Path('/kaggle/input/hubmap-hacking-the-human-vasculature/test/')\n\nall_imgs = list(IMG_ROOT.glob(\"*.tif\"))\nids = []\nheights = []\nwidths = []\nprediction_strings = []\n\nBATCH_SIZE = 2\n\ndef divide_chunks(l, n):\n    # looping till length l\n    for i in range(0, len(l), n): \n        yield l[i:i + n]\n        \nlist_batch_imgs = list(divide_chunks(all_imgs, BATCH_SIZE))","metadata":{"papermill":{"duration":0.024638,"end_time":"2023-07-25T11:39:01.654727","exception":false,"start_time":"2023-07-25T11:39:01.630089","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:10:12.512931Z","iopub.execute_input":"2023-08-10T14:10:12.513992Z","iopub.status.idle":"2023-08-10T14:10:12.526635Z","shell.execute_reply.started":"2023-08-10T14:10:12.513948Z","shell.execute_reply":"2023-08-10T14:10:12.525664Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def run_pred(model, img_array):\n    pred = inference_detector(model, img_array)\n    return pred","metadata":{"papermill":{"duration":0.020875,"end_time":"2023-07-25T11:39:06.790795","exception":false,"start_time":"2023-07-25T11:39:06.76992","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:10:13.603085Z","iopub.execute_input":"2023-08-10T14:10:13.603475Z","iopub.status.idle":"2023-08-10T14:10:13.608438Z","shell.execute_reply.started":"2023-08-10T14:10:13.603443Z","shell.execute_reply":"2023-08-10T14:10:13.607081Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"list_models = [load_model(model_info) for model_info in ensemble_infos]","metadata":{"papermill":{"duration":14.907773,"end_time":"2023-07-25T11:39:21.711107","exception":false,"start_time":"2023-07-25T11:39:06.803334","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:10:15.168140Z","iopub.execute_input":"2023-08-10T14:10:15.169274Z","iopub.status.idle":"2023-08-10T14:11:28.486526Z","shell.execute_reply.started":"2023-08-10T14:10:15.169231Z","shell.execute_reply":"2023-08-10T14:11:28.485496Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample = None\nblood_case = 0\nIOU_THRESH = 0.65\nPIXEL_THRESH = 64\nCONF_THRESH = 0.01\nQ_INST_FACTOR = 0.075","metadata":{"papermill":{"duration":0.020481,"end_time":"2023-07-25T11:39:21.745032","exception":false,"start_time":"2023-07-25T11:39:21.724551","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:11:31.081198Z","iopub.execute_input":"2023-08-10T14:11:31.081976Z","iopub.status.idle":"2023-08-10T14:11:31.086854Z","shell.execute_reply.started":"2023-08-10T14:11:31.081940Z","shell.execute_reply":"2023-08-10T14:11:31.085785Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"FILTER_IOU_THRESH = 0 # 0.75\nFILTER_CONF_THRESH = 0 # 0.01\nFILTER_PIXEL_THRESH = 0 # 64\nGLOM_OVL_THRESH = 0.6\nENS_QUANTILE_FACTOR = 0.05 #0.1\nSINGLE_QUANTILE_FACTOR = -1 #0.1","metadata":{"papermill":{"duration":0.020467,"end_time":"2023-07-25T11:39:21.778308","exception":false,"start_time":"2023-07-25T11:39:21.757841","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:11:32.022019Z","iopub.execute_input":"2023-08-10T14:11:32.023067Z","iopub.status.idle":"2023-08-10T14:11:32.028386Z","shell.execute_reply.started":"2023-08-10T14:11:32.023028Z","shell.execute_reply":"2023-08-10T14:11:32.027413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for batch_imgs in tqdm(list_batch_imgs):\n    ensemble_results = defaultdict(list)\n    for idx, model in enumerate(list_models):\n        if isinstance(model, dict):\n            model = load_model(model)\n        model_info = ensemble_infos[idx]\n        \n        is_croptile = model_info.get(\"is_crop_tile\", False)\n        margin = model_info.get(\"margin\", 0)\n\n        for img_path in batch_imgs:\n            im_stem = img_path.stem\n            img_array = mmcv.imread(str(img_path), channel_order='bgr')\n            \n            [h, w, c] = img_array.shape \n            img_shape = (h, w)\n            \n            if is_croptile:\n                full_9tiles = get_9tiles(im_stem, img_array)\n                img_array = crop_full_tile(full_9tiles, margin)\n\n            result = run_pred(model, [img_array])\n        \n            if is_croptile:\n                result = crop_result_tiles(result, margin=margin, base=512, pixel_thresh=PIXEL_THRESH)\n            \n            glo_mask = None\n            result = filter_result(result, FILTER_IOU_THRESH, FILTER_CONF_THRESH, FILTER_PIXEL_THRESH, \n                                   glo_mask, img_shape, GLOM_OVL_THRESH, SINGLE_QUANTILE_FACTOR)\n            \n            pred = result[0]\n            ensemble_results[im_stem].append(pred)\n            \n            del img_array, glo_mask\n            gc.collect()\n\n        gc.collect()\n        torch.cuda.empty_cache()\n\n    merged_ens_results = dict()\n    for stem, list_preds in ensemble_results.items():\n        merged_ens_results[stem] = ensemble_instance(list_preds, NUM_CLASSES)\n        \n    del ensemble_results\n    \n    for img_path in batch_imgs:\n        im_stem = img_path.stem\n        print(im_stem)\n        img_array = mmcv.imread(str(img_path), channel_order='rgb')\n        [h, w, c] = img_array.shape \n        del img_array\n        pred = merged_ens_results[im_stem]\n        \n        glo_mask = None\n        img_shape = (512, 512)\n        pred = filter_result([pred], IOU_THRESH, CONF_THRESH, PIXEL_THRESH, glo_mask, img_shape, GLOM_OVL_THRESH, ENS_QUANTILE_FACTOR, Q_INST_FACTOR)[0]\n        \n        pred_string = ''\n        \n        pred_class = pred[0]\n        \n        pred_mask = pred[1]\n        \n        for i, classe in enumerate(pred_class):\n            if classe.shape != (0, 5):\n                print(classe.shape)\n                if(i==blood_case): #blood case \n                    bbs = classe\n                    sgs = pred_mask[i]\n                    cnfs = bbs[:, 4]\n                    sgs = np.array(sgs)\n                    sgs, cnfs, bbs = masking_nms(sgs, cnfs, bbs, IOU_THRESH)\n                    num_inst = sgs.shape[0]\n                    pids = np.sum(sgs.reshape(num_inst, -1).astype(np.uint8), axis=1) > PIXEL_THRESH\n                    sgs = sgs[pids]\n                    bbs = bbs[pids]\n                    sgs = [sg for sg in sgs]\n                    print(len(sgs))\n                    m=0\n                    validcount=0\n                    for bb, sg in zip(bbs,sgs):\n                        box = bb[:4]\n                        cnf = bb[4] \n                        if cnf < CONF_THRESH:\n                            continue\n                        #dilation ------\n#                         sg = sg.astype(np.uint8)\n#                         kernel = np.ones(shape=(3, 3), dtype=np.uint8)\n#                         binary_mask = cv2.dilate(sg, kernel, 3)    \n#                         binary_mask = binary_mask.astype(bool)\n                        #-------------------------\n                        binary_mask = sg\n\n                        encoded = encode_binary_mask(binary_mask)\n                        if m==0:\n                            pred_string += f\"0 {cnf} {encoded.decode('utf-8')}\"\n                            m=m+1\n                        else:\n                            pred_string += f\" 0 {cnf} {encoded.decode('utf-8')}\"\n#                     del classe, bbs, cnfs, sgs\n#         del pred                    \n        ids.append(os.path.basename(img_path).split('.')[0])\n        heights.append(h)\n        widths.append(w)\n        prediction_strings.append(pred_string)\n    del merged_ens_results\n    gc.collect()\n    torch.cuda.empty_cache()\n","metadata":{"papermill":{"duration":7.026222,"end_time":"2023-07-25T11:39:28.818316","exception":false,"start_time":"2023-07-25T11:39:21.792094","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:11:32.987376Z","iopub.execute_input":"2023-08-10T14:11:32.987742Z","iopub.status.idle":"2023-08-10T14:12:19.761561Z","shell.execute_reply.started":"2023-08-10T14:11:32.987713Z","shell.execute_reply":"2023-08-10T14:12:19.760472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submission","metadata":{}},{"cell_type":"code","source":"submission = pd.DataFrame()\nsubmission['id'] = ids\nsubmission['height'] = heights\nsubmission['width'] = widths\nsubmission['prediction_string'] = prediction_strings\nsubmission = submission.set_index('id')\nsubmission.to_csv(\"submission.csv\")\nsubmission.head()","metadata":{"papermill":{"duration":0.04336,"end_time":"2023-07-25T11:39:29.025471","exception":false,"start_time":"2023-07-25T11:39:28.982111","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:12:28.622979Z","iopub.execute_input":"2023-08-10T14:12:28.623341Z","iopub.status.idle":"2023-08-10T14:12:28.646992Z","shell.execute_reply.started":"2023-08-10T14:12:28.623311Z","shell.execute_reply":"2023-08-10T14:12:28.646036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!rm -rf mmdetection\n!rm -rf packages","metadata":{"papermill":{"duration":2.078327,"end_time":"2023-07-25T11:39:31.118127","exception":false,"start_time":"2023-07-25T11:39:29.0398","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-10T14:12:37.320470Z","iopub.execute_input":"2023-08-10T14:12:37.320880Z","iopub.status.idle":"2023-08-10T14:12:39.410725Z","shell.execute_reply.started":"2023-08-10T14:12:37.320847Z","shell.execute_reply":"2023-08-10T14:12:39.409369Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}