{"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/mmdetectionv2140/addict-2.4.0-py3-none-any.whl > /dev/null\n!pip install /kaggle/input/mmdetectionv2140/yapf-0.31.0-py2.py3-none-any.whl > /dev/null\n!pip install /kaggle/input/mmdetectionv2140/terminal-0.4.0-py3-none-any.whl > /dev/null\n!pip install /kaggle/input/mmdetectionv2140/terminaltables-3.1.0-py3-none-any.whl > /dev/null\n!pip install /kaggle/input/mmdetectionv2140/pycocotools-2.0.2/pycocotools-2.0.2 > /dev/null\n!pip install /kaggle/input/mmdetectionv2140/mmpycocotools-12.0.3/mmpycocotools-12.0.3 > /dev/nullnull\nimport sys\nsys.path.append('../input/timm-pytorch-image-models/pytorch-image-models-master')\n\n\n!pip install ../input/mmdetection/mmcv_full-1.3.10-cp37-cp37m-linux_x86_64.whl > /dev/null\n!pip install ../input/mmdetection/mmdet-2.15.0-py3-none-any.whl > /dev/null","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-12-23T22:14:22.052712Z","iopub.execute_input":"2021-12-23T22:14:22.053283Z","iopub.status.idle":"2021-12-23T22:18:19.475604Z","shell.execute_reply.started":"2021-12-23T22:14:22.053195Z","shell.execute_reply":"2021-12-23T22:18:19.47467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport cv2\nimport glob\nimport json\nimport copy\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nfrom tqdm.auto import tqdm\nfrom itertools import product\nimport pycocotools.mask as mutils\nfrom pycocotools.coco import COCO\n\nimport torch\nfrom mmcv.ops import nms\nfrom mmdet.core import bbox_mapping_back, merge_aug_proposals, multiclass_nms, bbox2result, bbox2roi, bbox_mapping, merge_aug_bboxes, merge_aug_masks\nfrom mmdet.apis.inference import init_detector, replace_ImageToTensor, Compose, collate, scatter\n\ndef mask2rle(msk):\n    pixels = msk.flatten()\n    pad    = np.array([0])\n    pixels = np.concatenate([pad, pixels, pad])\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 rle2mask(rle, shape = [520, 704]):\n    s = 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)\n\n\n\nconfigs = [\n    \"../input/sartorius-submission/r2htc101_1x_hvflip_rot90_tiny_d2_800_all.py\",\n    \"../input/sartorius-submission/htcx101_1x_d2_800_all.py\",\n    \"../input/sartorius-submission/htcr2101_1x_d2_800_f0.py\",\n]\n\nckpts = [\n    \"../input/sartorius-submission/r2htc101_1x_hvflip_rot90_tiny_d2_800_all.pth\",\n    \"../input/sartorius-submission/htcx101_1x_d2_800_all.pth\",\n    \"../input/sartorius-submission/htcr2101_1x_d2_800_f0.pth\",\n]\n\nmodel_weights = [\n    1, \n    1,\n    1\n]\nmodel_weights = np.array(model_weights) / sum(model_weights) * len(model_weights)\n\ncfg_options = [{\n    \"data.test.pipeline.1.img_scale\": [(1333,1333),(1024,1024)],\n    \"data.test.pipeline.1.flip\": True,\n    \"data.test.pipeline.1.flip_direction\": ['horizontal','vertical'],\n    \"moedl.test_cfg.rcnn.score_thr\": 0.3,\n    \"model.test_cfg.rcnn.nms.type\": \"weighted_cluster_nms\",\n    \"model.test_cfg.rcnn.nms.iou_method\": \"diou\",\n    \"model.test_cfg.rcnn.nms.iou_threshold\": 0.45\n},{\n    \"data.test.pipeline.1.img_scale\": [(1333,1333),(1024,1024)],\n    \"data.test.pipeline.1.flip\": True,\n    \"data.test.pipeline.1.flip_direction\": ['horizontal','vertical'],\n    \"moedl.test_cfg.rcnn.score_thr\": 0.3,\n    \"model.test_cfg.rcnn.nms.type\": \"weighted_cluster_nms\",\n    \"model.test_cfg.rcnn.nms.iou_method\": \"diou\",\n    \"model.test_cfg.rcnn.nms.iou_threshold\": 0.45\n},{\n    \"data.test.pipeline.1.img_scale\": [(1333,1333),(1024,1024)],\n    \"data.test.pipeline.1.flip\": True,\n    \"data.test.pipeline.1.flip_direction\": ['horizontal','vertical'],\n    \"moedl.test_cfg.rcnn.score_thr\": 0.3,\n    \"model.test_cfg.rcnn.nms.type\": \"weighted_cluster_nms\",\n    \"model.test_cfg.rcnn.nms.iou_method\": \"diou\",\n    \"model.test_cfg.rcnn.nms.iou_threshold\": 0.45\n}]\n\n\nmodels = [init_detector(config, ckpt, cfg_options = c) for config, ckpt, c in zip(configs, ckpts, cfg_options)]\nTHRESHOLDS_small = [0.4, 0.45, 0.7]\nMIN_PIXELS = [80, 150, 60]\nMAX_OVERLAP = [0.2, 0.2, 0.2]\nsmall_ids = [0,1,2]\n\nimg_files = glob.glob(\"../input/sartorius-cell-instance-segmentation/test/*.*\")\nprint(len(img_files))","metadata":{"execution":{"iopub.status.busy":"2021-12-23T22:18:19.478155Z","iopub.execute_input":"2021-12-23T22:18:19.478602Z","iopub.status.idle":"2021-12-23T22:19:05.614325Z","shell.execute_reply.started":"2021-12-23T22:18:19.478564Z","shell.execute_reply":"2021-12-23T22:19:05.61256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def extract_feats(models, imgs):\n    \"\"\"Inference image(s) with the detector.\n\n    Args:\n        model (nn.Module): The loaded detector.\n        imgs (str/ndarray or list[str/ndarray] or tuple[str/ndarray]):\n           Either image files or loaded images.\n\n    Returns:\n        If imgs is a list or tuple, the same length list type results\n        will be returned, otherwise return the detection results directly.\n    \"\"\"\n    model = models[0]\n    if isinstance(imgs, (list, tuple)):\n        is_batch = True\n    else:\n        imgs = [imgs]\n        is_batch = False\n\n    cfg = model.cfg\n    device = next(model.parameters()).device  # model device\n\n    if isinstance(imgs[0], np.ndarray):\n        cfg = cfg.copy()\n        # set loading pipeline type\n        cfg.data.test.pipeline[0].type = 'LoadImageFromWebcam'\n\n    cfg.data.test.pipeline = replace_ImageToTensor(cfg.data.test.pipeline)\n    test_pipeline = Compose(cfg.data.test.pipeline)\n\n    datas = []\n    for img in imgs:\n        # prepare data\n        if isinstance(img, np.ndarray):\n            # directly add img\n            data = dict(img=img)\n        else:\n            # add information into dict\n            data = dict(img_info=dict(filename=img), img_prefix=None)\n        # build the data pipeline\n        data = test_pipeline(data)\n        datas.append(data)\n\n    data = collate(datas, samples_per_gpu=len(imgs))\n    # just get the actual data from DataContainer\n    data['img_metas'] = [img_metas.data[0] for img_metas in data['img_metas']]\n    data['img'] = [img.data[0] for img in data['img']]\n    if next(model.parameters()).is_cuda:\n        # scatter to specified GPU\n        data = scatter(data, [device])[0]\n    else:\n        for m in model.modules():\n            assert not isinstance(\n                m, RoIPool\n            ), 'CPU inference with RoIPool is not supported currently.'\n\n    # forward the model\n    res = []\n    for model in models:\n        with torch.no_grad():\n            results = model.extract_feats(data[\"img\"])\n        res.append(results)\n    return res, data[\"img\"], data[\"img_metas\"]\n\ndef rpn_head_aug_test(models, res, img_metas):\n    samples_per_gpu = len(img_metas[0])\n    aug_proposals = [[] for _ in range(samples_per_gpu)]\n    aug_img_metas = []\n    cfg = models[0].rpn_head.test_cfg\n\n    for model, feats in zip(models, res):\n        for x, img_meta in zip(feats, img_metas):\n            proposal_list = model.rpn_head.simple_test_rpn(x, img_meta)\n            for i, proposals in enumerate(proposal_list):\n                aug_proposals[i].append(proposals)\n        # reorganize the order of 'img_metas' to match the dimensions\n        # of 'aug_proposals'\n        for i in range(samples_per_gpu):\n            aug_img_meta = []\n            for j in range(len(img_metas)):\n                aug_img_meta.append(img_metas[j][i])\n            aug_img_metas.append(aug_img_meta)\n    return aug_proposals, aug_img_metas, cfg\n    # after merging, proposals will be rescaled to the original image size\n    # merged_proposals = [\n    #     merge_aug_proposals(proposals, aug_img_meta, cfg)\n    #     for proposals, aug_img_meta in zip(aug_proposals, aug_img_metas)\n    # ]\n    # return merged_proposals\n    \ndef merge_aug_proposals(aug_proposals, img_metas, transposed, cfg):\n    cfg = copy.deepcopy(cfg)\n\n    # deprecate arguments warning\n    if 'nms' not in cfg or 'max_num' in cfg or 'nms_thr' in cfg:\n        warnings.warn(\n            'In rpn_proposal or test_cfg, '\n            'nms_thr has been moved to a dict named nms as '\n            'iou_threshold, max_num has been renamed as max_per_img, '\n            'name of original arguments and the way to specify '\n            'iou_threshold of NMS will be deprecated.')\n    if 'nms' not in cfg:\n        cfg.nms = ConfigDict(dict(type='nms', iou_threshold=cfg.nms_thr))\n    if 'max_num' in cfg:\n        if 'max_per_img' in cfg:\n            assert cfg.max_num == cfg.max_per_img, f'You set max_num and ' \\\n                f'max_per_img at the same time, but get {cfg.max_num} ' \\\n                f'and {cfg.max_per_img} respectively' \\\n                f'Please delete max_num which will be deprecated.'\n        else:\n            cfg.max_per_img = cfg.max_num\n    if 'nms_thr' in cfg:\n        assert cfg.nms.iou_threshold == cfg.nms_thr, f'You set ' \\\n            f'iou_threshold in nms and ' \\\n            f'nms_thr at the same time, but get ' \\\n            f'{cfg.nms.iou_threshold} and {cfg.nms_thr}' \\\n            f' respectively. Please delete the nms_thr ' \\\n            f'which will be deprecated.'\n\n    recovered_proposals = []\n    for proposals, img_info, t in zip(aug_proposals, img_metas, transposed):\n        img_shape = img_info['img_shape']\n        scale_factor = img_info['scale_factor']\n        flip = img_info['flip']\n        flip_direction = img_info['flip_direction']\n        _proposals = proposals.clone()\n        _proposals[:, :4] = bbox_mapping_back(_proposals[:, :4], img_shape,\n                                              scale_factor, flip,\n                                              flip_direction)\n        if t:\n            _proposals[:,:4] = _proposals[:,:4][:,[1,0,3,2]]\n        recovered_proposals.append(_proposals)\n    aug_proposals = torch.cat(recovered_proposals, dim=0)\n    merged_proposals, _ = nms(aug_proposals[:, :4].contiguous(),\n                              aug_proposals[:, -1].contiguous(),\n                              cfg.nms.iou_threshold)\n    scores = merged_proposals[:, 4]\n    _, order = scores.sort(0, descending=True)\n    num = min(cfg.max_per_img, merged_proposals.shape[0])\n    order = order[:num]\n    merged_proposals = merged_proposals[order, :]\n    return merged_proposals\n\ndef roi_head_aug_test_bbox(models, res, proposal_list, img_metas):\n    rcnn_test_cfg = models[0].roi_head.test_cfg\n    aug_bboxes = []\n    aug_scores = []\n    for model, img_feats in zip(models, res):\n        for x, img_meta in zip(img_feats, img_metas):\n            # only one image in the batch\n            img_shape = img_meta[0]['img_shape']\n            scale_factor = img_meta[0]['scale_factor']\n            flip = img_meta[0]['flip']\n            flip_direction = img_meta[0]['flip_direction']\n\n            proposals = bbox_mapping(proposal_list[0][:, :4], img_shape,\n                                     scale_factor, flip, flip_direction)\n            # \"ms\" in variable names means multi-stage\n            ms_scores = []\n\n            rois = bbox2roi([proposals])\n\n            if rois.shape[0] == 0:\n                # There is no proposal in the single image\n                aug_bboxes.append(rois.new_zeros(0, 4))\n                aug_scores.append(rois.new_zeros(0, 1))\n                continue\n\n            for i in range(model.roi_head.num_stages):\n                bbox_head = model.roi_head.bbox_head[i]\n                bbox_results = model.roi_head._bbox_forward(\n                    i, x, rois, semantic_feat=None)\n                ms_scores.append(bbox_results['cls_score'])\n\n                if i < model.roi_head.num_stages - 1:\n                    bbox_label = bbox_results['cls_score'].argmax(dim=1)\n                    rois = bbox_head.regress_by_class(\n                        rois, bbox_label, bbox_results['bbox_pred'],\n                        img_meta[0])\n\n            cls_score = sum(ms_scores) / float(len(ms_scores))\n            bboxes, scores = model.roi_head.bbox_head[-1].get_bboxes(\n                rois,\n                cls_score,\n                bbox_results['bbox_pred'],\n                img_shape,\n                scale_factor,\n                rescale=False,\n                cfg=None)\n            aug_bboxes.append(bboxes)\n            aug_scores.append(scores)\n\n    # after merging, bboxes will be rescaled to the original image size\n    merged_bboxes, merged_scores = merge_aug_bboxes(\n        aug_bboxes, aug_scores, img_metas, rcnn_test_cfg)\n    return merged_bboxes, merged_scores, rcnn_test_cfg, models[0].roi_head.bbox_head[-1].num_classes\n#     det_bboxes, det_labels = multiclass_nms(merged_bboxes, merged_scores,\n#                                             rcnn_test_cfg.score_thr,\n#                                             rcnn_test_cfg.nms,\n#                                             rcnn_test_cfg.max_per_img)\n\n#     bbox_result = bbox2result(det_bboxes, det_labels,\n#                               models[0].roi_head.bbox_head[-1].num_classes)\n#     return det_bboxes, det_labels, bbox_result\n\ndef roi_head_aug_test_segm(models, model_weights, res, img_metas, det_bboxes, det_labels):\n    rcnn_test_cfg = models[0].roi_head.test_cfg\n    if det_bboxes.shape[0] == 0:\n        return None, img_metas[0][0]['ori_shape'], models[0].roi_head.mask_head[-1].get_seg_masks, rcnn_test_cfg\n#         segm_result = [[[] for _ in range(models[0].roi_head.mask_head[-1].num_classes)]]\n    else:\n        aug_masks = []\n        aug_img_metas = []\n        for model, img_feats, model_weight in zip(models, res, model_weights):\n            for x, img_meta in zip(img_feats, img_metas):\n                img_shape = img_meta[0]['img_shape']\n                scale_factor = img_meta[0]['scale_factor']\n                flip = img_meta[0]['flip']\n                flip_direction = img_meta[0]['flip_direction']\n                _bboxes = bbox_mapping(det_bboxes[:, :4], img_shape, scale_factor, flip, flip_direction)\n                mask_rois = bbox2roi([_bboxes])\n                mask_feats = model.roi_head.mask_roi_extractor[-1](\n                    x[:len(model.roi_head.mask_roi_extractor[-1].featmap_strides)],\n                    mask_rois)\n                last_feat = None\n                for i in range(model.roi_head.num_stages):\n                    mask_head = model.roi_head.mask_head[i]\n                    if model.roi_head.mask_info_flow:\n                        mask_pred, last_feat = mask_head(\n                            mask_feats, last_feat)\n                    else:\n                        mask_pred = mask_head(mask_feats)\n                    aug_masks.append(mask_pred.sigmoid().cpu().numpy() * model_weight)\n                    aug_img_metas.append(img_meta)\n#         return aug_masks, aug_img_metas, models[0].roi_head.test_cfg\n        merged_masks = merge_aug_masks(aug_masks, aug_img_metas, models[0].roi_head.test_cfg)\n        return merged_masks, img_metas[0][0]['ori_shape'], models[0].roi_head.mask_head[-1].get_seg_masks, rcnn_test_cfg\n#         ori_shape = img_metas[0][0]['ori_shape']\n#         segm_result = models[0].roi_head.mask_head[-1].get_seg_masks(\n#             merged_masks,\n#             det_bboxes,\n#             det_labels,\n#             rcnn_test_cfg,\n#             ori_shape,\n#             scale_factor=1.0,\n#             rescale=False)\n#     return segm_result\n\ndef inference_detectors(models, model_weights, img_cut):\n    res, imgs, img_metas = extract_feats(models, img_cut)\n    aug_proposals, aug_img_metas, cfg = rpn_head_aug_test(models, res, img_metas)\n    proposal_list = [merge_aug_proposals(aug_proposal, aug_img_meta, [False] * len(aug_proposal), cfg) for aug_proposal, aug_img_meta in zip(aug_proposals, aug_img_metas)]\n    \n    merged_bboxes, merged_scores, cfg, num_classes = roi_head_aug_test_bbox(models, res, proposal_list, img_metas)\n    det_bboxes, det_labels = multiclass_nms(torch.cat([merged_bboxes]), \n                                            torch.cat([merged_scores]), \n                                            cfg.score_thr, cfg.nms, cfg.max_per_img)\n    bbox_result = bbox2result(det_bboxes, det_labels, num_classes)\n    \n    merged_masks, ori_shape, get_seg_masks, rcnn_test_cfg = roi_head_aug_test_segm(models, model_weights, res, img_metas, det_bboxes, det_labels)\n    if merged_masks is None:\n        segm_result = [[[] for _ in range(models[0].roi_head.mask_head[-1].num_classes)]]\n    else:\n        segm_result = get_seg_masks(merged_masks, \n                                det_bboxes,\n                                det_labels,\n                                rcnn_test_cfg,\n                                ori_shape,\n                                scale_factor=1.0,\n                                rescale=False)\n    return bbox_result, segm_result\n\ndef inference_detectors_transpose(models, model_weights, img_cut):\n    res, imgs, img_metas = extract_feats(models, img_cut)\n    res_t, imgs_t, img_metas_t = extract_feats(models, img_cut.transpose(1,0,2))\n    \n    aug_proposals, aug_img_metas, cfg = rpn_head_aug_test(models, res, img_metas)\n    aug_proposals_t, aug_img_metas_t, cfg_t = rpn_head_aug_test(models, res_t, img_metas_t)\n    proposal_list = [merge_aug_proposals(aug_proposal + aug_proposal_t, aug_img_meta + aug_img_meta_t, [False] * len(aug_proposal) + [True] * len(aug_proposal_t), cfg) for aug_proposal, aug_proposal_t, aug_img_meta, aug_img_meta_t in zip(aug_proposals, aug_proposals_t, aug_img_metas, aug_img_metas_t)]\n    \n    merged_bboxes, merged_scores, cfg, num_classes = roi_head_aug_test_bbox(models, res, proposal_list, img_metas)\n    merged_bboxes_t, merged_scores_t, cfg, num_classes = roi_head_aug_test_bbox(models, res_t, [_[:,[1,0,3,2,4]] for _ in proposal_list], img_metas_t)\n    det_bboxes, det_labels = multiclass_nms(torch.cat([merged_bboxes, merged_bboxes_t[:,[1,0,3,2]]]), \n                                            torch.cat([merged_scores, merged_scores_t]), \n                                            cfg.score_thr, cfg.nms, cfg.max_per_img)\n    bbox_result = bbox2result(det_bboxes, det_labels, num_classes)\n    \n    merged_masks, ori_shape, get_seg_masks, rcnn_test_cfg = roi_head_aug_test_segm(models, model_weights, res, img_metas, det_bboxes, det_labels)\n    merged_masks_t, _, _, _ = roi_head_aug_test_segm(models, model_weights, res_t, img_metas_t, det_bboxes[:,[1,0,3,2,4]], det_labels)\n    if merged_masks is None and merged_masks_t is None:\n        segm_result = [[[] for _ in range(models[0].roi_head.mask_head[-1].num_classes)]]\n    elif merged_masks is None or merged_masks_t is None:\n        segm_result = get_seg_masks(merged_masks_t.transpose(0,1,3,2) if merged_masks is None else merged_masks, \n                                    det_bboxes,\n                                    det_labels,\n                                    rcnn_test_cfg,\n                                    ori_shape,\n                                    scale_factor=1.0,\n                                    rescale=False)\n    else:\n        segm_result = get_seg_masks((merged_masks_t.transpose(0,1,3,2) + merged_masks) / 2, \n                                    det_bboxes,\n                                    det_labels,\n                                    rcnn_test_cfg,\n                                    ori_shape,\n                                    scale_factor=1.0,\n                                    rescale=False)\n    return bbox_result, segm_result","metadata":{"execution":{"iopub.status.busy":"2021-12-23T22:19:05.672926Z","iopub.execute_input":"2021-12-23T22:19:05.673594Z","iopub.status.idle":"2021-12-23T22:19:05.756818Z","shell.execute_reply.started":"2021-12-23T22:19:05.673554Z","shell.execute_reply":"2021-12-23T22:19:05.756082Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = []\nfor img_file in tqdm(img_files):\n    img_id = os.path.basename(img_file).split(\".\")[0]\n    img = cv2.imread(img_file)\n    H, W = img.shape[:2]\n    annotations = []\n\n    dets = []\n    for i, j in product(range(4), range(4)):\n        img_cut = img[i * H // 5: (i + 2) * H // 5, j * W // 5: (j + 2) * W // 5]\n        with torch.no_grad():\n            small_det = inference_detectors(models, model_weights, img_cut)\n        dets.append([i, j, small_det])\n        \n    cnt_per_class = np.array([[len(_) for _ in det] for i, j, (det, _) in dets]).sum(0).tolist()\n    class_id = cnt_per_class.index(max(cnt_per_class))\n        \n    for i, j, small_det in dets:\n        small_box, small_seg = small_det\n        \n        if isinstance(small_seg, list) and isinstance(small_seg[0], list) and len(small_seg[0]) != 0 and isinstance(small_seg[0][0], list):\n            small_seg = small_seg[0]\n\n        small_box = small_box[class_id]\n        small_seg = small_seg[class_id]\n\n        valid = (small_box[:,-1] > THRESHOLDS_small[class_id]) & \\\n            ~((i <= 2) & (small_box[:,[1,3]].mean(1) > 3 * H / 10)) & \\\n            ~((i >= 1) & (small_box[:,[1,3]].mean(1) < H / 10)) & \\\n            ~((j <= 2) & (small_box[:,[0,2]].mean(1) > 3 * W / 10)) & \\\n            ~((j >= 1) & (small_box[:,[0,2]].mean(1) < W / 10))\n        small_box = small_box[valid]\n        small_seg = [_ for _, v in zip(small_seg, valid) if v]\n\n        for box, seg in zip(small_box, small_seg):\n            if seg.sum() < MIN_PIXELS[class_id]: continue\n            x1, y1, x2, y2, s = [float(_) for _ in box]\n            seg = np.asfortranarray(seg)\n            rle = mutils.encode(seg)\n            annotations.append([[x1, y1, x2 - x1, y2 - y1], rle, s, i, j])\n\n    annotations = sorted(annotations, key = lambda x: -x[-3])\n    masks = np.zeros((H, W), dtype = np.uint); mask_idx = 1\n    \n    for ann in annotations:\n        bbox, rle, s, i, j = ann\n        mask = mutils.decode(rle)\n\n        assign = (mask != 0) & (masks[i * H // 5: (i + 2) * H // 5, j * W // 5: (j + 2) * W // 5] == 0)\n        assign_area = assign.sum()\n        if assign_area < MIN_PIXELS[class_id]:\n            continue\n        num_connected, _ = cv2.connectedComponents(assign.astype(np.uint8))\n        if num_connected > 2:\n            continue\n        overlap_ratio = 1 - assign_area / mask.sum()\n        if overlap_ratio > MAX_OVERLAP[class_id]:\n            continue\n        masks[i * H // 5: (i + 2) * H // 5, j * W // 5: (j + 2) * W // 5][assign] = mask_idx\n\n\n        mask_idx += 1\n\n    if mask_idx > 1:\n        for idx in range(1, mask_idx):\n            rle = mask2rle((masks == idx).astype(np.uint8))\n            sub.append([img_id, rle])\n    else:\n        sub.append([img_id, \"0 1\"])\n\nsub_df = pd.DataFrame(sub, columns = ['id', 'predicted'])\nsub_df.head()\nsub_df.to_csv('submission.csv', index = False)","metadata":{"execution":{"iopub.status.busy":"2021-12-23T22:28:34.568951Z","iopub.execute_input":"2021-12-23T22:28:34.569216Z","iopub.status.idle":"2021-12-23T22:30:23.029918Z","shell.execute_reply.started":"2021-12-23T22:28:34.569181Z","shell.execute_reply":"2021-12-23T22:30:23.028085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"try:\n    import matplotlib.pyplot as plt\n    import albumentations as A\n\n    fig, ax = plt.subplots(2, 3, figsize = (30, 20))\n\n    for i, img_id in enumerate(sub_df.id.unique()[:3]):\n        img = cv2.imread([_ for _ in img_files if img_id in _][0])\n        ax[0][i].imshow(A.CLAHE(p = 1)(image = img)[\"image\"])\n        ax[0][i].axis(\"off\")\n        for rle in sub_df.loc[sub_df.id == img_id, \"predicted\"]:\n            mask = rle2mask(rle, img.shape[:2])\n            img[mask != 0] = img[mask != 0] // 2 + np.random.randint(0, 256, 3) // 2\n        ax[1][i].imshow(img)\n        ax[1][i].axis(\"off\")\n\n    plt.show(fig)\n    plt.close(fig)\nexcept:\n    pass","metadata":{"execution":{"iopub.status.busy":"2021-12-23T22:30:25.136896Z","iopub.execute_input":"2021-12-23T22:30:25.137443Z","iopub.status.idle":"2021-12-23T22:30:26.968922Z","shell.execute_reply.started":"2021-12-23T22:30:25.137399Z","shell.execute_reply":"2021-12-23T22:30:26.967936Z"},"trusted":true},"execution_count":null,"outputs":[]}]}