{"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 /kaggle/input/mmdet3-wheels/addict-2.4.0-py3-none-any.whl\n!pip install /kaggle/input/mmdet3-wheels/mmengine-0.7.3-py3-none-any.whl\n!pip install /kaggle/input/mmdet3-wheels/mmcv-2.0.0-cp310-cp310-linux_x86_64.whl\n!pip install /kaggle/input/pycocotools-206/wheels/pycocotools-2.0.6-cp310-cp310-linux_x86_64.whl\n!pip install /kaggle/input/mmdet3-wheels/terminaltables-3.1.10-py2.py3-none-any.whl\n!pip install /kaggle/input/mmdet3-wheels/mmdet-3.0.0-py3-none-any.whl","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:32:22.009812Z","iopub.execute_input":"2023-07-03T12:32:22.010683Z","iopub.status.idle":"2023-07-03T12:35:35.531112Z","shell.execute_reply.started":"2023-07-03T12:32:22.010646Z","shell.execute_reply":"2023-07-03T12:35:35.529941Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install /kaggle/input/mmpretrain/einops-0.6.1-py3-none-any.whl\n!pip install /kaggle/input/mmpretrain/mat4py-0.5.0-py2.py3-none-any.whl\n!pip install /kaggle/input/mmpretrain/ordered_set-4.1.0-py3-none-any.whl\n!pip install /kaggle/input/mmpretrain/model_index-0.1.11-py3-none-any.whl\n!pip install /kaggle/input/mmpretrain/modelindex-0.0.2-py3-none-any.whl\n!pip install /kaggle/input/mmpretrain/mmpretrain-1.0.0rc8-py2.py3-none-any.whl","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:35:35.542695Z","iopub.execute_input":"2023-07-03T12:35:35.543174Z","iopub.status.idle":"2023-07-03T12:38:43.155113Z","shell.execute_reply.started":"2023-07-03T12:35:35.543144Z","shell.execute_reply":"2023-07-03T12:38:43.153977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Import","metadata":{}},{"cell_type":"code","source":"import mmdet\nimport mmcv\nimport mmengine\nfrom mmengine import Config\nfrom mmengine.runner import set_random_seed\nfrom mmengine.runner import Runner\nfrom mmdet.apis import init_detector, inference_detector\nfrom mmengine.visualization import Visualizer\nfrom mmcv.transforms import Compose","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:38:43.159338Z","iopub.execute_input":"2023-07-03T12:38:43.159659Z","iopub.status.idle":"2023-07-03T12:38:49.048489Z","shell.execute_reply.started":"2023-07-03T12:38:43.159631Z","shell.execute_reply":"2023-07-03T12:38:49.047580Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom tqdm import tqdm_notebook as tqdm\nfrom fastcore.all import *\nimport matplotlib.pyplot as plt\nimport json\n\nimport warnings\nwarnings.filterwarnings('ignore') #Ignore \"future\" warnings and Data-Frame-Slicing warnings.\n\nfrom sklearn.model_selection import KFold, StratifiedKFold\nfrom pytorch_lightning import seed_everything\n\nimport cv2\nimport base64\nfrom pycocotools import _mask as coco_mask\nimport typing as t\nimport zlib\n\nimport torch\nimport gc","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:38:49.049829Z","iopub.execute_input":"2023-07-03T12:38:49.050207Z","iopub.status.idle":"2023-07-03T12:38:59.673823Z","shell.execute_reply.started":"2023-07-03T12:38:49.050177Z","shell.execute_reply":"2023-07-03T12:38:59.672871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Config","metadata":{}},{"cell_type":"code","source":"class CFG:\n    class general:\n        #project_name = \"HuBMAP2023\"\n        input_path = \"/kaggle/input\"\n        output_path = \"/kaggle/working\"\n        #save_name = \"debug\"\n        seed = 0\n        cv = True\n        #wandb_desabled = True\n        n_splits = 5\n        fold = [0] # list (0-idx start) or null. Set one element list, hold-out mode.","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:38:59.675461Z","iopub.execute_input":"2023-07-03T12:38:59.675848Z","iopub.status.idle":"2023-07-03T12:38:59.684065Z","shell.execute_reply.started":"2023-07-03T12:38:59.675814Z","shell.execute_reply":"2023-07-03T12:38:59.683126Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Utils","metadata":{}},{"cell_type":"code","source":"# from https://github.com/ZFTurbo/Weighted-Boxes-Fusion\n\"\"\"\nMIT License\n\nCopyright (c) 2020 ZFTurbo (Roman Solovyev)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\"\"\"\n\n# coding: utf-8\n__author__ = 'ZFTurbo: https://kaggle.com/zfturbo'\n\nimport numpy as np\nfrom numba import jit\n\n\ndef prepare_boxes(boxes, scores, labels, masks):\n    result_boxes = boxes.copy()\n\n    cond = (result_boxes < 0)\n    cond_sum = cond.astype(np.int32).sum()\n    if cond_sum > 0:\n        print('Warning. Fixed {} boxes coordinates < 0'.format(cond_sum))\n        result_boxes[cond] = 0\n\n    cond = (result_boxes > 1)\n    cond_sum = cond.astype(np.int32).sum()\n    if cond_sum > 0:\n        print('Warning. Fixed {} boxes coordinates > 1. Check that your boxes was normalized at [0, 1]'.format(cond_sum))\n        result_boxes[cond] = 1\n\n    boxes1 = result_boxes.copy()\n    result_boxes[:, 0] = np.min(boxes1[:, [0, 2]], axis=1)\n    result_boxes[:, 2] = np.max(boxes1[:, [0, 2]], axis=1)\n    result_boxes[:, 1] = np.min(boxes1[:, [1, 3]], axis=1)\n    result_boxes[:, 3] = np.max(boxes1[:, [1, 3]], axis=1)\n\n    area = (result_boxes[:, 2] - result_boxes[:, 0]) * (result_boxes[:, 3] - result_boxes[:, 1])\n    cond = (area == 0)\n    cond_sum = cond.astype(np.int32).sum()\n    if cond_sum > 0:\n        print('Warning. Removed {} boxes with zero area!'.format(cond_sum))\n        result_boxes = result_boxes[area > 0]\n        scores = scores[area > 0]\n        labels = labels[area > 0]\n        masks = masks[area > 0]\n\n    return result_boxes, scores, labels, masks\n\n\ndef cpu_soft_nms_float(dets, sc, Nt, sigma, thresh, method):\n    \"\"\"\n    Based on: https://github.com/DocF/Soft-NMS/blob/master/soft_nms.py\n    It's different from original soft-NMS because we have float coordinates on range [0; 1]\n\n    :param dets:   boxes format [x1, y1, x2, y2]\n    :param sc:     scores for boxes\n    :param Nt:     required iou \n    :param sigma:  \n    :param thresh: \n    :param method: 1 - linear soft-NMS, 2 - gaussian soft-NMS, 3 - standard NMS\n    :return: index of boxes to keep\n    \"\"\"\n\n    # indexes concatenate boxes with the last column\n    N = dets.shape[0]\n    indexes = np.array([np.arange(N)])\n    dets = np.concatenate((dets, indexes.T), axis=1)\n\n    # the order of boxes coordinate is [y1, x1, y2, x2]\n    y1 = dets[:, 1]\n    x1 = dets[:, 0]\n    y2 = dets[:, 3]\n    x2 = dets[:, 2]\n    scores = sc\n    areas = (x2 - x1) * (y2 - y1)\n\n    for i in range(N):\n        # intermediate parameters for later parameters exchange\n        tBD = dets[i, :].copy()\n        tscore = scores[i].copy()\n        tarea = areas[i].copy()\n        pos = i + 1\n\n        #\n        if i != N - 1:\n            maxscore = np.max(scores[pos:], axis=0)\n            maxpos = np.argmax(scores[pos:], axis=0)\n        else:\n            maxscore = scores[-1]\n            maxpos = 0\n        if tscore < maxscore:\n            dets[i, :] = dets[maxpos + i + 1, :]\n            dets[maxpos + i + 1, :] = tBD\n            tBD = dets[i, :]\n\n            scores[i] = scores[maxpos + i + 1]\n            scores[maxpos + i + 1] = tscore\n            tscore = scores[i]\n\n            areas[i] = areas[maxpos + i + 1]\n            areas[maxpos + i + 1] = tarea\n            tarea = areas[i]\n\n        # IoU calculate\n        xx1 = np.maximum(dets[i, 1], dets[pos:, 1])\n        yy1 = np.maximum(dets[i, 0], dets[pos:, 0])\n        xx2 = np.minimum(dets[i, 3], dets[pos:, 3])\n        yy2 = np.minimum(dets[i, 2], dets[pos:, 2])\n\n        w = np.maximum(0.0, xx2 - xx1)\n        h = np.maximum(0.0, yy2 - yy1)\n        inter = w * h\n        ovr = inter / (areas[i] + areas[pos:] - inter)\n\n        # Three methods: 1.linear 2.gaussian 3.original NMS\n        if method == 1:  # linear\n            weight = np.ones(ovr.shape)\n            weight[ovr > Nt] = weight[ovr > Nt] - ovr[ovr > Nt]\n        elif method == 2:  # gaussian\n            weight = np.exp(-(ovr * ovr) / sigma)\n        else:  # original NMS\n            weight = np.ones(ovr.shape)\n            weight[ovr > Nt] = 0\n\n        scores[pos:] = weight * scores[pos:]\n\n    # select the boxes and keep the corresponding indexes\n    inds = dets[:, 4][scores > thresh]\n    keep = inds.astype(int)\n    return keep\n\n\n@jit(nopython=True)\ndef nms_float_fast(dets, scores, thresh):\n    \"\"\"\n    # It's different from original nms because we have float coordinates on range [0; 1]\n    :param dets: numpy array of boxes with shape: (N, 5). Order: x1, y1, x2, y2, score. All variables in range [0; 1]\n    :param thresh: IoU value for boxes\n    :return: index of boxes to keep\n    \"\"\"\n    x1 = dets[:, 0]\n    y1 = dets[:, 1]\n    x2 = dets[:, 2]\n    y2 = dets[:, 3]\n\n    areas = (x2 - x1) * (y2 - y1)\n    order = scores.argsort()[::-1]\n\n    keep = []\n    while order.size > 0:\n        i = order[0]\n        keep.append(i)\n        xx1 = np.maximum(x1[i], x1[order[1:]])\n        yy1 = np.maximum(y1[i], y1[order[1:]])\n        xx2 = np.minimum(x2[i], x2[order[1:]])\n        yy2 = np.minimum(y2[i], y2[order[1:]])\n\n        w = np.maximum(0.0, xx2 - xx1)\n        h = np.maximum(0.0, yy2 - yy1)\n        inter = w * h\n        ovr = inter / (areas[i] + areas[order[1:]] - inter)\n        inds = np.where(ovr <= thresh)[0]\n        order = order[inds + 1]\n\n    return keep\n\n\ndef nms_method(boxes, scores, labels, masks, method=3, iou_thr=0.5, sigma=0.5, thresh=0.001, weights=None):\n    \"\"\"\n    :param boxes: list of boxes predictions from each model, each box is 4 numbers. \n    It has 3 dimensions (models_number, model_preds, 4)\n    Order of boxes: x1, y1, x2, y2. We expect float normalized coordinates [0; 1] \n    :param scores: list of scores for each model \n    :param labels: list of labels for each model\n    :param method: 1 - linear soft-NMS, 2 - gaussian soft-NMS, 3 - standard NMS\n    :param iou_thr: IoU value for boxes to be a match \n    :param sigma: Sigma value for SoftNMS\n    :param thresh: threshold for boxes to keep (important for SoftNMS)\n    :param weights: list of weights for each model. Default: None, which means weight == 1 for each model\n\n    :return: boxes: boxes coordinates (Order of boxes: x1, y1, x2, y2). \n    :return: scores: confidence scores\n    :return: labels: boxes labels\n    \"\"\"\n\n    # If weights are specified\n    if weights is not None:\n        if len(boxes) != len(weights):\n            print('Incorrect number of weights: {}. Must be: {}. Skip it'.format(len(weights), len(boxes)))\n        else:\n            weights = np.array(weights)\n            for i in range(len(weights)):\n                scores[i] = (np.array(scores[i]) * weights[i]) / weights.sum()\n\n    # We concatenate everything\n    boxes = np.concatenate(boxes)\n    scores = np.concatenate(scores)\n    labels = np.concatenate(labels)\n    masks = np.concatenate(masks)\n\n    # Fix coordinates and removed zero area boxes\n    boxes, scores, labels, masks = prepare_boxes(boxes, scores, labels, masks)\n\n    # Run NMS independently for each label\n    unique_labels = np.unique(labels)\n    final_boxes = []\n    final_scores = []\n    final_labels = []\n    final_masks = []\n    for l in unique_labels:\n        condition = (labels == l)\n        boxes_by_label = boxes[condition]\n        scores_by_label = scores[condition]\n        labels_by_label = np.array([l] * len(boxes_by_label))\n        masks_by_label = masks[condition]\n\n        if method != 3:\n            keep = cpu_soft_nms_float(boxes_by_label.copy(), scores_by_label.copy(), Nt=iou_thr, sigma=sigma, thresh=thresh, method=method)\n        else:\n            # Use faster function\n            keep = nms_float_fast(boxes_by_label, scores_by_label, thresh=iou_thr)\n\n        final_boxes.append(boxes_by_label[keep])\n        final_scores.append(scores_by_label[keep])\n        final_labels.append(labels_by_label[keep])\n        final_masks.append(masks_by_label[keep])\n    final_boxes = np.concatenate(final_boxes)\n    final_scores = np.concatenate(final_scores)\n    final_labels = np.concatenate(final_labels)\n    final_masks = np.concatenate(final_masks)\n\n    return final_boxes, final_scores, final_labels, final_masks\n\n\ndef nms(boxes, scores, labels, masks, iou_thr=0.5, weights=None):\n    \"\"\"\n    Short call for standard NMS \n    \n    :param boxes: \n    :param scores: \n    :param labels: \n    :param iou_thr: \n    :param weights: \n    :return: \n    \"\"\"\n    return nms_method(boxes, scores, labels, masks, method=3, iou_thr=iou_thr, weights=weights)\n\n\ndef soft_nms(boxes, scores, labels, masks, method=2, iou_thr=0.5, sigma=0.5, thresh=0.001, weights=None):\n    \"\"\"\n    Short call for Soft-NMS\n     \n    :param boxes: \n    :param scores: \n    :param labels: \n    :param method: \n    :param iou_thr: \n    :param sigma: \n    :param thresh: \n    :param weights: \n    :return: \n    \"\"\"\n    return nms_method(boxes, scores, labels, masks, method=method, iou_thr=iou_thr, sigma=sigma, thresh=thresh, weights=weights)","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:38:59.685422Z","iopub.execute_input":"2023-07-03T12:38:59.685922Z","iopub.status.idle":"2023-07-03T12:39:00.331257Z","shell.execute_reply.started":"2023-07-03T12:38:59.685891Z","shell.execute_reply":"2023-07-03T12:39:00.330330Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# From https://www.kaggle.com/stainsby/fast-tested-rle\ndef rle_decode(mask_rle, shape=(512, 512)):\n    '''\n    mask_rle: run-length as string formated (start length)\n    shape: (height,width) of array to return \n    Returns numpy array, 1 - mask, 0 - background\n\n    '''\n    s = mask_rle.split()\n    starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]\n    starts -= 1\n    ends = starts + lengths\n    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)\n    for lo, hi in zip(starts, ends):\n        img[lo:hi] = 1\n    return img.reshape(shape)  # Needed to align to RLE direction\n\ndef rle_encode(img):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    '''\n    pixels = img.flatten()\n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)\n\ndef nms_predictions(classes, scores, bboxes, masks, \n                    iou_th=.5, shape=(512, 512), per_image=None):\n    he, wd = shape[0], shape[1]\n    boxes_list = [[x[0] / wd, x[1] / he, x[2] / wd, x[3] / he]\n                  for x in bboxes]\n    scores_list = [x for x in scores]\n    labels_list = [x for x in classes]\n    masks_list = [x for x in masks]\n    nms_bboxes, nms_scores, nms_classes, nms_masks = nms(\n        [boxes_list], \n        [scores_list], \n        [labels_list],\n        [masks_list],\n        weights=None,\n        iou_thr=iou_th,\n    )\n    \n    if per_image is None:\n        return nms_classes, nms_scores, nms_bboxes, nms_masks\n    else:\n        return nms_classes[:per_image], nms_scores[:per_image], nms_bboxes[:per_image], nms_masks[:per_image]\n\ndef get_classes_scores_masks(fn, predictor):\n    im = mmcv.imread(str(fn), channel_order=\"rgb\")\n    height, width, _ = im.shape\n    pred = inference_detector(predictor, im)\n    \n    if len(pred.pred_instances.masks) == 0:\n        return [None], [None], [None], [None], height, width\n    \n    pred_masks = pred.pred_instances.masks.cpu().numpy()\n    pred_classes = pred.pred_instances.labels.cpu().numpy().tolist()\n    pred_scores = pred.pred_instances.scores.cpu().numpy().tolist()\n    pred_boxes = pred.pred_instances.bboxes.cpu().numpy().tolist()\n    \n    return pred_classes, pred_scores, pred_masks, pred_boxes, height, width\n\ndef get_classes_scores_masks_tta(fn, predictor, TTA_SIZE):\n    im = mmcv.imread(str(fn), channel_order=\"rgb\")\n    height, width, _ = im.shape\n    pred_masks = []\n    pred_classes = []\n    pred_scores = []\n    pred_boxes = []\n    \n    for size in tqdm(TTA_SIZE):\n        test_pipeline = [\n            dict(type=\"mmdet.LoadImageFromNDArray\", backend_args=None),\n            dict(type=\"Resize\", scale=(size, size), keep_ratio=True),\n            dict(type=\"LoadAnnotations\", with_bbox=True, with_mask=True),\n            dict(\n                type=\"PackDetInputs\",\n                meta_keys=(\"img_id\", \"img_path\", \"ori_shape\", \"img_shape\", \"scale_factor\"))\n        ]\n        test_pipeline = Compose(test_pipeline)\n        \n        pred = inference_detector(predictor, im, test_pipeline)\n\n        pred_masks.extend(pred.pred_instances.masks.cpu().numpy())\n        pred_classes.extend(pred.pred_instances.labels.cpu().numpy().tolist())\n        pred_scores.extend(pred.pred_instances.scores.cpu().numpy().tolist())\n        pred_boxes.extend(pred.pred_instances.bboxes.cpu().numpy().tolist())\n        \n    if len(pred_masks) == 0:\n        return [None], [None], [None], [None], height, width\n    \n    pred_classes, pred_scores, pred_boxes, pred_masks = nms_predictions(pred_classes, pred_scores, pred_boxes, pred_masks)\n    \n    return pred_classes, pred_scores, pred_masks, pred_boxes, height, width","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:39:00.332804Z","iopub.execute_input":"2023-07-03T12:39:00.333509Z","iopub.status.idle":"2023-07-03T12:39:00.356917Z","shell.execute_reply.started":"2023-07-03T12:39:00.333475Z","shell.execute_reply":"2023-07-03T12:39:00.355692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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 = 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-03T12:39:00.358379Z","iopub.execute_input":"2023-07-03T12:39:00.359089Z","iopub.status.idle":"2023-07-03T12:39:00.372595Z","shell.execute_reply.started":"2023-07-03T12:39:00.358995Z","shell.execute_reply":"2023-07-03T12:39:00.371619Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Main","metadata":{"execution":{"iopub.status.busy":"2023-06-09T14:40:43.740676Z","iopub.execute_input":"2023-06-09T14:40:43.741086Z","iopub.status.idle":"2023-06-09T14:40:43.746681Z","shell.execute_reply.started":"2023-06-09T14:40:43.741054Z","shell.execute_reply":"2023-06-09T14:40:43.74501Z"}}},{"cell_type":"markdown","source":"### Read data","metadata":{"execution":{"iopub.status.busy":"2023-06-09T14:41:01.020711Z","iopub.execute_input":"2023-06-09T14:41:01.02116Z","iopub.status.idle":"2023-06-09T14:41:01.02618Z","shell.execute_reply.started":"2023-06-09T14:41:01.021127Z","shell.execute_reply":"2023-06-09T14:41:01.025056Z"}}},{"cell_type":"code","source":"Dir_testdata = Path(\"/kaggle/input/hubmap-hacking-the-human-vasculature\")\ntest_image_names = (Dir_testdata/\"test\").ls()\n#test_image_names = (Dir_testdata/\"train\").ls()","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:39:00.376227Z","iopub.execute_input":"2023-07-03T12:39:00.376489Z","iopub.status.idle":"2023-07-03T12:39:00.389034Z","shell.execute_reply.started":"2023-07-03T12:39:00.376466Z","shell.execute_reply":"2023-07-03T12:39:00.388194Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TTA = True\nTTA_SIZE = [1024, 1280, 1536]\nDILATION = False\nDILATION_ITER = 1\nERODE = False\nERODE_ITER = 1","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:39:00.390190Z","iopub.execute_input":"2023-07-03T12:39:00.390561Z","iopub.status.idle":"2023-07-03T12:39:00.397487Z","shell.execute_reply.started":"2023-07-03T12:39:00.390530Z","shell.execute_reply":"2023-07-03T12:39:00.396672Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from mmengine import Config","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:39:00.398703Z","iopub.execute_input":"2023-07-03T12:39:00.399356Z","iopub.status.idle":"2023-07-03T12:39:00.408298Z","shell.execute_reply.started":"2023-07-03T12:39:00.399199Z","shell.execute_reply":"2023-07-03T12:39:00.407437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg = Config.fromfile(\"/kaggle/input/mmdetection/configs/convnext/cascade-mask-rcnn_convnext-t-p4-w7_fpn_4conv1fc-giou_amp-ms-crop-3x_coco.py\")\n\n# dummy\ncfg.metainfo = {\n    #\"classes\": (\"glomerulus\", \"blood_vessel\", )\n    \"classes\": (\"blood_vessel\", )\n}\ncfg.test_pipeline = [\n            dict(type=\"LoadImageFromFile\", backend_args=None),\n        dict(type=\"Resize\", scale=(1024, 1024), keep_ratio=True),\n        dict(type=\"LoadAnnotations\", with_bbox=True, with_mask=True),\n        dict(\n            type=\"PackDetInputs\",\n            meta_keys=(\"img_id\", \"img_path\", \"ori_shape\", \"img_shape\", \"scale_factor\"))\n    ]\ncfg.val_dataloader.dataset.pipeline = cfg.test_pipeline\ncfg.data_root = \"\"\ncfg.train_dataloader.dataset.ann_file = \"\"\ncfg.train_dataloader.dataset.data_root = cfg.data_root\n#cfg.train_dataloader.dataset.data_prefix.img = \"train\"\ncfg.train_dataloader.dataset.metainfo = cfg.metainfo\ncfg.val_dataloader.dataset.ann_file = \"\"\ncfg.val_dataloader.dataset.data_root = cfg.data_root\n#cfg.val_dataloader.dataset.data_prefix.img = \"train\"\ncfg.val_dataloader.dataset.metainfo = cfg.metainfo\ncfg.test_dataloader = cfg.val_dataloader\ncfg.val_evaluator.ann_file = \"\"\ncfg.val_evaluator.metric = \"segm\"\ncfg.test_evaluator = cfg.val_evaluator\n\ncfg.model.roi_head.bbox_head[0].num_classes = 1\ncfg.model.roi_head.bbox_head[1].num_classes = 1\ncfg.model.roi_head.bbox_head[2].num_classes = 1\ncfg.model.roi_head.mask_head.num_classes = 1\ncheckpoint_file = \"/kaggle/input/convnext-all-pseudo2-095-lr-7-10000/epoch_1.pth\"\ncfg.model.test_cfg.rcnn.score_thr = 0.0\ncfg.model.test_cfg.rcnn.max_per_img = 100\n#cfg.model.test_cfg.rpn.min_bbox_size = 10\npredictor = init_detector(cfg, checkpoint_file)","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:39:00.409800Z","iopub.execute_input":"2023-07-03T12:39:00.410242Z","iopub.status.idle":"2023-07-03T12:39:16.961647Z","shell.execute_reply.started":"2023-07-03T12:39:00.410210Z","shell.execute_reply":"2023-07-03T12:39:16.960622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Predict","metadata":{}},{"cell_type":"code","source":"ids = []\nheights = []\nwidths = []\nprediction_strings = []\n\nfor fn in test_image_names:\n    if TTA:\n        classes, scores, masks, bboxes, height, width = get_classes_scores_masks_tta(fn, predictor, TTA_SIZE)\n    else:\n        classes, scores, masks, bboxes, height, width = get_classes_scores_masks(fn, predictor)\n    ids.append(fn.stem)\n    heights.append(height)\n    widths.append(width)\n    pred_string = \"\"\n    for i, (class_, score, mask) in enumerate(zip(classes, scores, masks)):\n        if class_ is None:\n            continue\n        #if int(class_) != 1:\n        #    continue\n            \n        if DILATION:\n            mask = np.array(mask, dtype=np.uint8)\n            mask = cv2.dilate(mask, np.ones((3, 3), dtype=np.uint8), iterations=DILATION_ITER)\n            mask = np.array(mask, dtype=bool)\n            \n        if ERODE:\n            mask = np.array(mask, dtype=np.uint8)\n            mask = cv2.erode(mask, np.ones((3, 3), dtype=np.uint8), iterations=ERODE_ITER)\n            mask = np.array(mask, dtype=bool)\n\n        sub_mask = encode_binary_mask(mask)\n        class_ = 0\n        if i == 0:\n            pred_string += f\"{int(class_)} {score} {sub_mask.decode('utf-8')}\"\n        else:\n            pred_string += f\" {int(class_)} {score} {sub_mask.decode('utf-8')}\"            \n    \n    prediction_strings.append(pred_string)\n    \ntorch.cuda.empty_cache()\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:39:16.963194Z","iopub.execute_input":"2023-07-03T12:39:16.963557Z","iopub.status.idle":"2023-07-03T12:39:26.752747Z","shell.execute_reply.started":"2023-07-03T12:39:16.963524Z","shell.execute_reply":"2023-07-03T12:39:26.751651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#\"\"\"\nif TTA:\n    classes, scores, masks, bboxes, height, width = get_classes_scores_masks_tta(test_image_names[0], predictor, TTA_SIZE)\nelse:\n    classes, scores, masks, bboxes, height, width = get_classes_scores_masks(test_image_names[0], predictor)\nprint(len(masks))\nif masks[0] is not None:\n    _, axs = plt.subplots(1,2, figsize=(40,30))\n    axs[1].imshow(cv2.imread(str(test_image_names[0])))\n    axs[1].axis(\"off\")\n    mask = np.zeros((512, 512))\n    for (class_, score_, mask_) in zip(classes, scores, masks):\n        #if int(class_) != 1:\n        #    continue\n            \n        #if score_ < 0.5:\n        #    continue\n            \n        if DILATION:\n            mask_ = np.array(mask_, dtype=np.uint8)\n            mask_ = cv2.dilate(mask_, np.ones((3, 3), dtype=np.uint8), iterations=DILATION_ITER)\n            mask_ = np.array(mask_, dtype=bool)\n            \n        if ERODE:\n            mask_ = np.array(mask_, dtype=np.uint8)\n            mask_ = cv2.erode(mask_, np.ones((3, 3), dtype=np.uint8), iterations=ERODE_ITER)\n            mask_ = np.array(mask_, dtype=bool)\n        \n        mask += np.array(mask_, dtype=\"int\")\n\n    mask = mask.clip(0,1)\n    axs[0].imshow(mask)\n    axs[0].axis(\"off\")\n#\"\"\"","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:39:26.754179Z","iopub.execute_input":"2023-07-03T12:39:26.754641Z","iopub.status.idle":"2023-07-03T12:39:30.375569Z","shell.execute_reply.started":"2023-07-03T12:39:26.754610Z","shell.execute_reply":"2023-07-03T12:39:30.373656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictor.cpu()\ndel predictor, cfg\ntorch.cuda.empty_cache()\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:39:30.376878Z","iopub.execute_input":"2023-07-03T12:39:30.377345Z","iopub.status.idle":"2023-07-03T12:39:31.067246Z","shell.execute_reply.started":"2023-07-03T12:39:30.377302Z","shell.execute_reply":"2023-07-03T12:39:31.066217Z"},"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\")\ndisplay(submission)","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:39:31.069112Z","iopub.execute_input":"2023-07-03T12:39:31.069527Z","iopub.status.idle":"2023-07-03T12:39:31.098940Z","shell.execute_reply.started":"2023-07-03T12:39:31.069489Z","shell.execute_reply":"2023-07-03T12:39:31.098006Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission[\"prediction_string\"][0]","metadata":{"execution":{"iopub.status.busy":"2023-07-03T12:39:31.100902Z","iopub.execute_input":"2023-07-03T12:39:31.101781Z","iopub.status.idle":"2023-07-03T12:39:31.108103Z","shell.execute_reply.started":"2023-07-03T12:39:31.101748Z","shell.execute_reply":"2023-07-03T12:39:31.107207Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}