{"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 Offline MMDetection","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":0.005553,"end_time":"2023-07-16T08:38:50.031469","exception":false,"start_time":"2023-07-16T08:38:50.025916","status":"completed"},"tags":[]}},{"cell_type":"code","source":"!pip install -qqq /kaggle/input/mmdetv3-env/archive/addict-2.4.0-py3-none-any.whl\n!pip install -qqq /kaggle/input/mmdetv3-env/archive/mmengine-0.7.4-py3-none-any.whl\n!pip install -qqq /kaggle/input/mmdetv3-env/archive/mmcv-2.0.0-cp310-cp310-linux_x86_64.whl\n!pip install -qqq /kaggle/input/mmdetv3-env/archive/terminaltables-3.1.10-py2.py3-none-any.whl\n!pip install -qqq /kaggle/input/pycocotools-206/wheels/pycocotools-2.0.6-cp310-cp310-linux_x86_64.whl\n!pip install -qqq /kaggle/input/weighted-boxes-fusion/ensemble_boxes-1.0.9-py3-none-any.whl","metadata":{"papermill":{"duration":191.48257,"end_time":"2023-07-16T08:42:01.518982","exception":false,"start_time":"2023-07-16T08:38:50.036412","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-07-27T04:03:05.212182Z","iopub.execute_input":"2023-07-27T04:03:05.213139Z","iopub.status.idle":"2023-07-27T04:06:04.052004Z","shell.execute_reply.started":"2023-07-27T04:03:05.213076Z","shell.execute_reply":"2023-07-27T04:06:04.050654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -qqq /kaggle/input/pycocotools-206/wheels/pycocotools-2.0.6-cp310-cp310-linux_x86_64.whl","metadata":{"execution":{"iopub.status.busy":"2023-07-27T04:06:04.056014Z","iopub.execute_input":"2023-07-27T04:06:04.058147Z","iopub.status.idle":"2023-07-27T04:06:35.886141Z","shell.execute_reply.started":"2023-07-27T04:06:04.058080Z","shell.execute_reply":"2023-07-27T04:06:35.884872Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -qqq /kaggle/input/mmdetection-3-1-evn/src/mmdet-3.1.0-py3-none-any.whl","metadata":{"papermill":{"duration":33.302012,"end_time":"2023-07-16T08:42:34.826066","exception":false,"start_time":"2023-07-16T08:42:01.524054","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-07-27T04:06:35.889619Z","iopub.execute_input":"2023-07-27T04:06:35.889989Z","iopub.status.idle":"2023-07-27T04:07:07.780257Z","shell.execute_reply.started":"2023-07-27T04:06:35.889958Z","shell.execute_reply":"2023-07-27T04:07:07.778906Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from itertools import groupby\nfrom pycocotools import mask as mutils\nfrom pycocotools.coco import COCO\nimport numpy as np\nfrom tqdm.notebook import tqdm\nimport pandas as pd\nimport os\nimport cv2\nimport matplotlib.pyplot as plt\nimport wandb\nfrom PIL import Image\nimport gc\n\nfrom glob import glob\nimport matplotlib.pyplot as plt\n\n\nimport base64\nimport numpy as np\nfrom pycocotools import _mask as coco_mask\nfrom typing import Text, Dict, Tuple\nimport zlib\n\nimport mmdet, mmcv, mmengine\nfrom mmengine.config import Config\nfrom mmengine.runner import Runner\nfrom mmdet.utils import register_all_modules\nfrom mmdet.apis import init_detector, inference_detector\nfrom mmengine.visualization import Visualizer\n\n\nprint(mmdet.__version__)\nprint(mmcv.__version__)\nprint(mmengine.__version__)","metadata":{"papermill":{"duration":7.851391,"end_time":"2023-07-16T08:42:42.68279","exception":false,"start_time":"2023-07-16T08:42:34.831399","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-07-27T04:07:07.785165Z","iopub.execute_input":"2023-07-27T04:07:07.785764Z","iopub.status.idle":"2023-07-27T04:07:07.795069Z","shell.execute_reply.started":"2023-07-27T04:07:07.785731Z","shell.execute_reply":"2023-07-27T04:07:07.794154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import base64\nimport numpy as np\nfrom pycocotools import _mask as coco_mask\nimport typing as t\nimport zlib\n\ndef encode_binary_mask(mask: np.ndarray) -> 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.017769,"end_time":"2023-07-16T08:42:42.705516","exception":false,"start_time":"2023-07-16T08:42:42.687747","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-07-27T04:07:07.796673Z","iopub.execute_input":"2023-07-27T04:07:07.797058Z","iopub.status.idle":"2023-07-27T04:07:07.808814Z","shell.execute_reply.started":"2023-07-27T04:07:07.797027Z","shell.execute_reply":"2023-07-27T04:07:07.807737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_glomerulus_mask(annotations: Dict, mask_shape: Tuple = (512, 512)) -> np.ndarray:\n    \"\"\" Converts glomerulus labels into boolean mask \"\"\"\n    mask = np.ones(shape=mask_shape, dtype=np.uint8)\n    \n    for annotation in annotations: \n        if annotation['type'] == 'glomerulus':            \n            coords = np.array(annotation['coordinates'])\n            cv2.fillPoly(mask, pts=coords, color=0)\n\n    return mask.astype(bool)\n    \n","metadata":{"papermill":{"duration":0.015161,"end_time":"2023-07-16T08:42:42.725566","exception":false,"start_time":"2023-07-16T08:42:42.710405","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-07-27T04:07:07.810291Z","iopub.execute_input":"2023-07-27T04:07:07.810723Z","iopub.status.idle":"2023-07-27T04:07:07.823800Z","shell.execute_reply.started":"2023-07-27T04:07:07.810691Z","shell.execute_reply":"2023-07-27T04:07:07.822880Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def morphological_gradient(binary_mask):\n    \"\"\"Áp dụng phép toán Morphological Gradient trên binary mask.\n    binary_mask: Binary mask có giá trị 0 hoặc 255.\n\n    Returns:\n    - gradient: Kết quả Morphological Gradient.\n    \"\"\"\n    # Chuyển đổi binary mask về kiểu dữ liệu uint8 nếu cần thiết\n    if binary_mask.dtype != np.uint8:\n        binary_mask = binary_mask.astype(np.uint8)\n\n    # Áp dụng phép toán Morphological Gradient\n    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))  # Kích thước kernel\n    gradient = cv2.morphologyEx(binary_mask, cv2.MORPH_GRADIENT, kernel)\n\n    return gradient\n\n","metadata":{"execution":{"iopub.status.busy":"2023-07-27T04:07:07.825397Z","iopub.execute_input":"2023-07-27T04:07:07.826293Z","iopub.status.idle":"2023-07-27T04:07:07.834422Z","shell.execute_reply.started":"2023-07-27T04:07:07.826260Z","shell.execute_reply":"2023-07-27T04:07:07.833561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def convert_to_binary_mask(mask):\n    \"\"\"Chuyển đổi mask sang dạng binary mask True/False.\n    mask: Mask có giá trị 0/255.\n\n    Returns:\n    - binary_mask: Binary mask dạng True/False.\n    \"\"\"\n    binary_mask = (mask > 0)\n    return binary_mask","metadata":{"execution":{"iopub.status.busy":"2023-07-27T04:07:07.836082Z","iopub.execute_input":"2023-07-27T04:07:07.836832Z","iopub.status.idle":"2023-07-27T04:07:07.847263Z","shell.execute_reply.started":"2023-07-27T04:07:07.836799Z","shell.execute_reply":"2023-07-27T04:07:07.846109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def convert_to_mask(binary_mask):\n    \"\"\"Chuyển đổi binary mask sang dạng mask 0/255.\n    binary_mask: Binary mask dạng True/False.\n\n    Returns:\n    - mask: Mask có giá trị 0/255.\n    \"\"\"\n    mask = binary_mask.astype(np.uint8) * 255\n    return mask","metadata":{"execution":{"iopub.status.busy":"2023-07-27T04:07:07.848910Z","iopub.execute_input":"2023-07-27T04:07:07.849696Z","iopub.status.idle":"2023-07-27T04:07:07.857261Z","shell.execute_reply.started":"2023-07-27T04:07:07.849662Z","shell.execute_reply":"2023-07-27T04:07:07.856188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def apply_morphological_operations(mask, iterations):\n    \"\"\"Apply a combination of morphological operations to refine the mask.\n    mask: Binary mask.\n    iterations: Number of iterations for each operation.\n    Returns:\n    - refined_mask: Refined binary mask.\n    \"\"\"\n    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))  # Kích thước kernel\n\n    # Apply morphological operations\n    eroded_mask = cv2.erode(mask, kernel, iterations=iterations)\n    opened_mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=iterations)\n    closed_mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=iterations)\n\n    # Combine the results using logical OR\n    refined_mask = eroded_mask | opened_mask | closed_mask\n\n    return refined_mask","metadata":{"execution":{"iopub.status.busy":"2023-07-27T04:07:07.861238Z","iopub.execute_input":"2023-07-27T04:07:07.861863Z","iopub.status.idle":"2023-07-27T04:07:07.869054Z","shell.execute_reply.started":"2023-07-27T04:07:07.861829Z","shell.execute_reply":"2023-07-27T04:07:07.868151Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%mkdir work_dir_test","metadata":{"papermill":{"duration":0.958716,"end_time":"2023-07-16T08:42:43.689004","exception":false,"start_time":"2023-07-16T08:42:42.730288","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-07-27T04:07:07.872040Z","iopub.execute_input":"2023-07-27T04:07:07.872330Z","iopub.status.idle":"2023-07-27T04:07:08.871078Z","shell.execute_reply.started":"2023-07-27T04:07:07.872308Z","shell.execute_reply":"2023-07-27T04:07:08.869913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path_list = [\"/kaggle/input/hubmap-hacking-the-human-vasculature/test/\"+i for i in os.listdir(\"/kaggle/input/hubmap-hacking-the-human-vasculature/test/\")]","metadata":{"execution":{"iopub.status.busy":"2023-07-27T04:07:08.872915Z","iopub.execute_input":"2023-07-27T04:07:08.874401Z","iopub.status.idle":"2023-07-27T04:07:08.880364Z","shell.execute_reply.started":"2023-07-27T04:07:08.874358Z","shell.execute_reply":"2023-07-27T04:07:08.879259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# cfg = Config.fromfile(\"/kaggle/working/work_dir_test/custom_config.py\")\ncfg = Config.fromfile(\"/kaggle/input/hubmap-mmdet-fold-1/custom_config.py\")\ncfg.work_dir = \"/kaggle/working/work_dir_test\"\nvis_backends = [dict(type='LocalVisBackend')]\ncfg.visualizer = dict(type='DetLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n# runner = Runner.from_cfg(cfg)","metadata":{"papermill":{"duration":0.039572,"end_time":"2023-07-16T08:42:43.733882","exception":false,"start_time":"2023-07-16T08:42:43.69431","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-07-27T04:07:08.882427Z","iopub.execute_input":"2023-07-27T04:07:08.882864Z","iopub.status.idle":"2023-07-27T04:07:08.915280Z","shell.execute_reply.started":"2023-07-27T04:07:08.882830Z","shell.execute_reply":"2023-07-27T04:07:08.914421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img = mmcv.imread(\"/kaggle/input/hubmap-hacking-the-human-vasculature/test/72e40acccadf.tif\")\ncheckpoint_file = \"/kaggle/input/hubmap-mmdet-fold-1/best_coco_segm_mAP_epoch_16.pth\"\n\nmodel = init_detector(cfg, checkpoint=checkpoint_file, device=\"cuda:0\")\nresult = inference_detector(model, imgs=path_list)","metadata":{"papermill":{"duration":21.121697,"end_time":"2023-07-16T08:43:04.92499","exception":false,"start_time":"2023-07-16T08:42:43.803293","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-07-27T04:07:08.917282Z","iopub.execute_input":"2023-07-27T04:07:08.917539Z","iopub.status.idle":"2023-07-27T04:07:10.620593Z","shell.execute_reply.started":"2023-07-27T04:07:08.917517Z","shell.execute_reply":"2023-07-27T04:07:10.619595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ids = []\nheights = []\nwidths = []\nprediction_string = []\n\nfor res in result:\n    pr_i = res.pred_instances\n    id = res.img_path.split(\"/\")[-1][:-4]\n\n    scores = pr_i.scores.cpu().numpy()\n    bboxes = pr_i.bboxes.cpu().numpy()\n    masks = pr_i.masks.cpu().numpy()\n    labels = pr_i.labels.cpu().numpy()\n    \n    height,width = (512, 512)\n    \n    \n    pred_strings = []\n\n    for label, score, mask in zip(labels, scores, masks):\n        pred_strings_txt = \"\"\n        kernel = np.ones(shape=(3, 3), dtype=np.uint8)\n        #mask = cv2.dilate(mask.astype(np.uint8), kernel, 4)\n        refined_mask = apply_morphological_operations(mask.astype(np.uint8), iterations=4)\n        if label == 0:\n            pred_strings_txt += f\"{label} {score} {encode_binary_mask(refined_mask.astype(np.bool_)).decode('utf-8')}\"\n        else:\n            # Increase the score for glomerulus class (label 1) to give it more weight\n            pred_strings_txt += f\"{label} {score * 1.2} {encode_binary_mask(refined_mask.astype(np.bool_)).decode('utf-8')}\"\n\n        \n        pred_strings.append(pred_strings_txt)\n        \n    ids.append(id)\n    heights.append(height)\n    widths.append(width)\n    prediction_string.append(\" \".join(pred_strings))\n\nsub = pd.DataFrame({\"id\": ids, \"height\": heights, \"width\": widths, \"prediction_string\": prediction_string})\nsub = sub.set_index(\"id\")\nsub.to_csv(\"submission.csv\")","metadata":{"papermill":{"duration":0.402729,"end_time":"2023-07-16T08:43:05.363532","exception":false,"start_time":"2023-07-16T08:43:04.960803","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-07-27T04:07:10.622119Z","iopub.execute_input":"2023-07-27T04:07:10.622473Z","iopub.status.idle":"2023-07-27T04:07:10.764086Z","shell.execute_reply.started":"2023-07-27T04:07:10.622440Z","shell.execute_reply":"2023-07-27T04:07:10.761942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub","metadata":{"papermill":{"duration":0.028656,"end_time":"2023-07-16T08:43:05.402107","exception":false,"start_time":"2023-07-16T08:43:05.373451","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-07-27T04:07:10.765414Z","iopub.execute_input":"2023-07-27T04:07:10.765797Z","iopub.status.idle":"2023-07-27T04:07:10.778833Z","shell.execute_reply.started":"2023-07-27T04:07:10.765764Z","shell.execute_reply":"2023-07-27T04:07:10.777586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"papermill":{"duration":0.008576,"end_time":"2023-07-16T08:43:05.419519","exception":false,"start_time":"2023-07-16T08:43:05.410943","status":"completed"},"tags":[]},"execution_count":null,"outputs":[]}]}