{"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 Requirements","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-08-14T16:22:42.779554Z","iopub.execute_input":"2023-08-14T16:22:42.780244Z","iopub.status.idle":"2023-08-14T16:23:03.856563Z","shell.execute_reply.started":"2023-08-14T16:22:42.780212Z","shell.execute_reply":"2023-08-14T16:23:03.855271Z"}}},{"cell_type":"code","source":"!pip install --no-index /kaggle/input/detectron2-download-code-for-offline-install-ii/detectron2/detectron2-0.6-cp310-cp310-linux_x86_64.whl --find-links=/kaggle/input/detectron2-download-code-for-offline-install-ii/detectron2","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:23:22.825989Z","iopub.execute_input":"2023-08-17T13:23:22.826303Z","iopub.status.idle":"2023-08-17T13:23:38.962171Z","shell.execute_reply.started":"2023-08-17T13:23:22.826277Z","shell.execute_reply":"2023-08-17T13:23:38.961008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip show detectron2","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:23:38.965229Z","iopub.execute_input":"2023-08-17T13:23:38.965636Z","iopub.status.idle":"2023-08-17T13:23:50.055487Z","shell.execute_reply.started":"2023-08-17T13:23:38.965600Z","shell.execute_reply":"2023-08-17T13:23:50.054323Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Import Library","metadata":{}},{"cell_type":"code","source":"import os\nimport cv2\nfrom PIL import Image\nfrom datetime import datetime\nimport glob\nimport pandas as pd\nfrom pathlib import Path\n\nfrom detectron2.data.datasets import register_coco_instances\nfrom detectron2.data import DatasetCatalog, MetadataCatalog\nfrom detectron2.utils.visualizer import Visualizer\nfrom detectron2.utils.visualizer import ColorMode\nfrom detectron2 import model_zoo\nfrom detectron2.config import get_cfg\nfrom detectron2.engine import DefaultPredictor\nfrom detectron2.engine import DefaultTrainer\n","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:23:50.060393Z","iopub.execute_input":"2023-08-17T13:23:50.061279Z","iopub.status.idle":"2023-08-17T13:23:53.761894Z","shell.execute_reply.started":"2023-08-17T13:23:50.061243Z","shell.execute_reply":"2023-08-17T13:23:53.760916Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Dataset","metadata":{}},{"cell_type":"code","source":"ROOT_DATASET = '/kaggle/input/hubmap-hacking-the-human-vasculature'\nROOT_COCO = '/kaggle/input/coco-dataset-hubmap-2023'","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:23:53.763194Z","iopub.execute_input":"2023-08-17T13:23:53.764902Z","iopub.status.idle":"2023-08-17T13:23:53.769364Z","shell.execute_reply.started":"2023-08-17T13:23:53.764866Z","shell.execute_reply":"2023-08-17T13:23:53.768469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_name = 'hubmap-hacking-the-human-vasculature'\ntrain_dataset_name = f'{dataset_name}-train'\ntest_dataset_name = f'{dataset_name}-valid'","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:23:53.772563Z","iopub.execute_input":"2023-08-17T13:23:53.773426Z","iopub.status.idle":"2023-08-17T13:23:53.782543Z","shell.execute_reply.started":"2023-08-17T13:23:53.773393Z","shell.execute_reply":"2023-08-17T13:23:53.781665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train\nregister_coco_instances(\n    name=train_dataset_name, \n    metadata={}, \n    json_file= f'{ROOT_COCO}/coco_annotations_train_class_1_folds5_fold1.json',\n    image_root=f'{ROOT_DATASET}/train/'\n)\n\n","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:23:53.783867Z","iopub.execute_input":"2023-08-17T13:23:53.784232Z","iopub.status.idle":"2023-08-17T13:23:53.793162Z","shell.execute_reply.started":"2023-08-17T13:23:53.784199Z","shell.execute_reply":"2023-08-17T13:23:53.792267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# valid\nregister_coco_instances(\n    name=test_dataset_name, \n    metadata={}, \n    json_file= f'{ROOT_COCO}/coco_annotations_valid_class_1_folds5_fold1.json',\n    image_root=f'{ROOT_DATASET}/train/'\n)","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:23:53.794725Z","iopub.execute_input":"2023-08-17T13:23:53.795120Z","iopub.status.idle":"2023-08-17T13:23:53.804623Z","shell.execute_reply.started":"2023-08-17T13:23:53.795080Z","shell.execute_reply":"2023-08-17T13:23:53.803586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualize","metadata":{}},{"cell_type":"code","source":"# get data dataset train\nmetadata = MetadataCatalog.get(train_dataset_name)\ndataset_train = DatasetCatalog.get(train_dataset_name)","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:23:53.807479Z","iopub.execute_input":"2023-08-17T13:23:53.807896Z","iopub.status.idle":"2023-08-17T13:23:54.868933Z","shell.execute_reply.started":"2023-08-17T13:23:53.807865Z","shell.execute_reply":"2023-08-17T13:23:54.867931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_entry = dataset_train[0]\nimage = cv2.imread(dataset_entry[\"file_name\"])\n\nvisualizer = Visualizer(\n    image[:, :, ::-1],\n    metadata=metadata, \n    scale=0.8, \n    instance_mode=ColorMode.IMAGE_BW\n)\n\nout = visualizer.draw_dataset_dict(dataset_entry)\nImage.fromarray((out.get_image()[:, :, ::-1]))","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:23:54.870413Z","iopub.execute_input":"2023-08-17T13:23:54.870745Z","iopub.status.idle":"2023-08-17T13:23:55.228127Z","shell.execute_reply.started":"2023-08-17T13:23:54.870710Z","shell.execute_reply":"2023-08-17T13:23:55.227091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Config","metadata":{}},{"cell_type":"code","source":"# HYPERPARAMETERS\nmodel_arch = \"mask_rcnn_R_101_FPN_3x\"\nconfig_file = f\"COCO-InstanceSegmentation/{model_arch}.yaml\"\nmax_itter = 5000\neval_period = 200\nbase_lr = 0.001\nnum_classes = 1\n\n# OUTPUT DIR\nouput_dir = os.path.join(\n    '/kaggle/working/', \n    model_arch, \n    datetime.now().strftime('%Y-%m-%d-%H-%M-%S')\n)\n\nos.makedirs(ouput_dir, exist_ok=True)\n","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:23:55.229207Z","iopub.execute_input":"2023-08-17T13:23:55.229543Z","iopub.status.idle":"2023-08-17T13:23:55.243025Z","shell.execute_reply.started":"2023-08-17T13:23:55.229513Z","shell.execute_reply":"2023-08-17T13:23:55.241853Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg = get_cfg()\ncfg.merge_from_file(model_zoo.get_config_file(config_file))\ncfg.MODEL.WEIGHTS = \"/kaggle/input/mask-rcnn-r-101-fpn-3x/model_final_a3ec72.pkl\"\ncfg.DATASETS.TRAIN = (train_dataset_name,)\ncfg.DATASETS.TEST = (test_dataset_name,)\ncfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 32\ncfg.TEST.EVAL_PERIOD = eval_period\ncfg.DATALOADER.NUM_WORKERS = 2\ncfg.SOLVER.IMS_PER_BATCH = 2\ncfg.INPUT.MASK_FORMAT='bitmask'\ncfg.SOLVER.BASE_LR = base_lr\ncfg.SOLVER.MAX_ITER = max_itter\ncfg.MODEL.ROI_HEADS.NUM_CLASSES = num_classes\ncfg.OUTPUT_DIR = ouput_dir","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:23:55.244587Z","iopub.execute_input":"2023-08-17T13:23:55.245197Z","iopub.status.idle":"2023-08-17T13:23:55.277472Z","shell.execute_reply.started":"2023-08-17T13:23:55.245164Z","shell.execute_reply":"2023-08-17T13:23:55.276498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainer = DefaultTrainer(cfg) \ntrainer.resume_or_load(resume=False)\ntrainer.train()","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:23:55.279741Z","iopub.execute_input":"2023-08-17T13:23:55.280070Z","iopub.status.idle":"2023-08-17T13:49:12.994016Z","shell.execute_reply.started":"2023-08-17T13:23:55.280020Z","shell.execute_reply":"2023-08-17T13:49:12.992855Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Test","metadata":{}},{"cell_type":"code","source":"cfg.MODEL.WEIGHTS = os.path.join(cfg.OUTPUT_DIR, \"model_final.pth\")\ncfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5\npredictor = DefaultPredictor(cfg)","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:49:12.996275Z","iopub.execute_input":"2023-08-17T13:49:12.997188Z","iopub.status.idle":"2023-08-17T13:49:14.692894Z","shell.execute_reply.started":"2023-08-17T13:49:12.997145Z","shell.execute_reply":"2023-08-17T13:49:14.691263Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_valid = DatasetCatalog.get(train_dataset_name)[0]\n\nimg = cv2.imread(dataset_valid[\"file_name\"])\noutputs = predictor(img)\n\nvisualizer = Visualizer(\n    img[:, :, ::-1],\n    metadata=metadata, \n    scale=0.8, \n    instance_mode=ColorMode.IMAGE_BW\n)\nout = visualizer.draw_instance_predictions(outputs[\"instances\"].to(\"cpu\"))\nImage.fromarray(out.get_image()[:, :, ::-1])","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:49:14.698736Z","iopub.execute_input":"2023-08-17T13:49:14.699553Z","iopub.status.idle":"2023-08-17T13:49:16.159789Z","shell.execute_reply.started":"2023-08-17T13:49:14.699506Z","shell.execute_reply":"2023-08-17T13:49:16.158885Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Submission","metadata":{}},{"cell_type":"code","source":"import base64\nimport numpy as np\nfrom pycocotools import _mask as coco_mask\nimport typing as t\nimport zlib\n\n\ndef 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\n","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2023-08-17T13:49:16.161262Z","iopub.execute_input":"2023-08-17T13:49:16.161957Z","iopub.status.idle":"2023-08-17T13:49:16.172089Z","shell.execute_reply.started":"2023-08-17T13:49:16.161922Z","shell.execute_reply":"2023-08-17T13:49:16.171162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images_list = glob.glob('/kaggle/input/hubmap-hacking-the-human-vasculature/test/*tif')\n\nid_list = []\nheights_list = []\nwidths_list = []\nresults_encode_list = []\n\nfor image_path in images_list:\n    image_id = Path(image_path).name\n    image_id = image_id.replace('.tif', '')\n    image = cv2.imread(image_path)\n    h, w = image.shape[:2]\n    # segmentation\n    results = predictor(image)\n    # extract ouput\n    pred_masks = results['instances'].pred_masks.cpu().numpy()\n    pred_classes = results['instances'].pred_classes.cpu().numpy()\n    pred_scores = results['instances'].scores.cpu().numpy()\n    \n    results_list = []\n    for mask, score, label in zip(pred_masks,pred_scores, pred_classes):\n        encoded = encode_binary_mask(mask)\n        results_list.append(f\"{int(label)} {score} {encoded.decode('utf-8')}\")\n    results_string = ' '.join(i for i in results_list)\n        \n    id_list.append(image_id)\n    heights_list.append(h)\n    widths_list.append(w)\n    results_encode_list.append(results_string)","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:49:16.173488Z","iopub.execute_input":"2023-08-17T13:49:16.174291Z","iopub.status.idle":"2023-08-17T13:49:16.800073Z","shell.execute_reply.started":"2023-08-17T13:49:16.174250Z","shell.execute_reply":"2023-08-17T13:49:16.799064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.DataFrame()\nsubmission['id'] = id_list\nsubmission['height'] = heights_list\nsubmission['width'] = widths_list\nsubmission['prediction_string'] = results_encode_list\nsubmission = submission.set_index('id')\nsubmission.to_csv(\"submission.csv\")\nsubmission","metadata":{"execution":{"iopub.status.busy":"2023-08-17T13:49:16.801554Z","iopub.execute_input":"2023-08-17T13:49:16.802123Z","iopub.status.idle":"2023-08-17T13:49:16.844217Z","shell.execute_reply.started":"2023-08-17T13:49:16.802089Z","shell.execute_reply":"2023-08-17T13:49:16.843216Z"},"trusted":true},"execution_count":null,"outputs":[]}]}