{"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":"%%capture\n# Install pycocotools package\nimport os\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\n!pip install . --no-index --find-links /kaggle/working/packages/\nos.chdir(\"/kaggle/working\")","metadata":{"execution":{"iopub.status.busy":"2023-05-31T07:50:00.100636Z","iopub.execute_input":"2023-05-31T07:50:00.101014Z","iopub.status.idle":"2023-05-31T07:50:50.186189Z","shell.execute_reply.started":"2023-05-31T07:50:00.100962Z","shell.execute_reply":"2023-05-31T07:50:50.184956Z"},"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\n\nfrom skimage.measure import label, regionprops, regionprops_table\nfrom skimage import morphology\n\ndef encode_binary_mask(mask: np.ndarray) -> t.Text:\n    \"\"\"Converts a binary mask into OID challenge encoding ascii text.\"\"\"\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\n\ndef get_vessels(mask):\n    mask = mask.astype(bool)\n    label_img = label(mask)\n    regions = regionprops(label_img)\n\n    # get items/vessels\n    label_items = []\n    for region in regions:\n        minr, minc, maxr, maxc = region.bbox\n        zero = np.zeros(mask.shape)\n        zero[minr:maxr, minc:maxc] = 1\n        label_item = (mask*zero).astype(bool)\n        label_items.append(label_item)\n    return  label_items","metadata":{"papermill":{"duration":0.031022,"end_time":"2022-09-17T05:33:32.057553","exception":false,"start_time":"2022-09-17T05:33:32.026531","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-05-31T07:50:50.188656Z","iopub.execute_input":"2023-05-31T07:50:50.189244Z","iopub.status.idle":"2023-05-31T07:50:50.934576Z","shell.execute_reply.started":"2023-05-31T07:50:50.189202Z","shell.execute_reply":"2023-05-31T07:50:50.933570Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\nsys.path.append('/kaggle/input/timm-pytorch-image-models/pytorch-image-models-master/')\n!pip install -qq /kaggle/input/mmdetection/einops-0.4.1-py3-none-any.whl","metadata":{"papermill":{"duration":32.93989,"end_time":"2022-09-17T05:34:05.002074","exception":false,"start_time":"2022-09-17T05:33:32.062184","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-05-31T07:50:50.936125Z","iopub.execute_input":"2023-05-31T07:50:50.937161Z","iopub.status.idle":"2023-05-31T07:51:12.820883Z","shell.execute_reply.started":"2023-05-31T07:50:50.937126Z","shell.execute_reply":"2023-05-31T07:51:12.819667Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ! pip install segmentation-models-pytorch\n\nfrom skimage import io, filters, transform \nimport tifffile as tiff\nimport albumentations as A\n \nimport os\nimport cv2\nimport numpy as np\nimport pandas as pd\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n","metadata":{"papermill":{"duration":5.026658,"end_time":"2022-09-17T05:34:10.048535","exception":false,"start_time":"2022-09-17T05:34:05.021877","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-05-31T07:51:12.823850Z","iopub.execute_input":"2023-05-31T07:51:12.824184Z","iopub.status.idle":"2023-05-31T07:51:16.748321Z","shell.execute_reply.started":"2023-05-31T07:51:12.824153Z","shell.execute_reply":"2023-05-31T07:51:16.747252Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class config:\n    IMAGE_SIZE = 512\n    TRAIN_BATCH_SIZE = 2\n    VALID_BATCH_SIZE = 2*TRAIN_BATCH_SIZE\n    EPOCHS = 15\n    DEVICE = \"cuda\"\n    OUTPUT = \"/hubmap/\"\n    MODEL_PATH = \"/kaggle/input/all-segformers/all-segformers/segformer-b2-finetuned-cityscapes-1024-1024\"\n    FOLDS = 5\n    LR = 1e-3\n    ","metadata":{"papermill":{"duration":0.019934,"end_time":"2022-09-17T05:34:10.076694","exception":false,"start_time":"2022-09-17T05:34:10.056760","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-05-31T07:51:16.749720Z","iopub.execute_input":"2023-05-31T07:51:16.752681Z","iopub.status.idle":"2023-05-31T07:51:16.758132Z","shell.execute_reply.started":"2023-05-31T07:51:16.752642Z","shell.execute_reply":"2023-05-31T07:51:16.757207Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image, ImageFile\nfrom skimage import io\nfrom tqdm import tqdm\nfrom collections import defaultdict\nfrom torchvision import transforms\nfrom albumentations import (\n Compose,\n OneOf,\n RandomBrightnessContrast,\n RandomGamma,\n ShiftScaleRotate,\n)\nimport albumentations as A\nImageFile.LOAD_TRUNCATED_IMAGES = True\n\nclass HubDataset(torch.utils.data.Dataset):\n    def __init__(self, image_path, transform=False):\n        \n        self.image_path = image_path\n        \n        # for augmentations\n        self.transform = transform\n\n\n    def __len__(self):\n        return len(self.image_path)\n    \n    def Normalize(self, ct):\n        \n        for i in range(ct.shape[0]):\n            if np.max(ct[i])!=0:\n                ct[i] = ct[i]/np.max(ct[i])\n        \n        ct[ct<0] = 0\n        return ct\n\n    def __getitem__(self, item):\n        \n        img = tiff.imread(self.image_path[item])  ## H x W x C \n        \n        img = self.Normalize(img)  ## C x H X W\n        \n        \"\"\"    \n             - Under the hood, Albumentations supports two data types that describe the intensity of pixels:\n            np.uint8, an unsigned 8-bit integer that can define values between 0 and 255.\n             - np.float32, a floating-point number with single precision. For np.float32 input, \n            Albumentations expects that value will lie in the range between 0.0 and 1.0.\n        \"\"\"\n        return {\n            \"image\": transforms.ToTensor()(img),\n        }","metadata":{"execution":{"iopub.status.busy":"2023-05-31T07:54:11.196126Z","iopub.execute_input":"2023-05-31T07:54:11.196722Z","iopub.status.idle":"2023-05-31T07:54:11.209233Z","shell.execute_reply.started":"2023-05-31T07:54:11.196686Z","shell.execute_reply":"2023-05-31T07:54:11.208124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\n\n@torch.no_grad()    \ndef infer(model,valid_loader,device):\n    model.eval()\n    \n    masks = []\n    for data in valid_loader:\n        inputs = data['image']\n        \n        inputs = inputs.to(device, dtype=torch.float)\n\n        output = model(inputs,)\n        output = torch.sigmoid(output)\n        \n        output = output.detach().cpu().numpy()\n        masks.append(output)\n    return masks","metadata":{"papermill":{"duration":0.01759,"end_time":"2022-09-17T05:34:10.121744","exception":false,"start_time":"2022-09-17T05:34:10.104154","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-05-31T07:51:16.975556Z","iopub.execute_input":"2023-05-31T07:51:16.975924Z","iopub.status.idle":"2023-05-31T07:51:16.984419Z","shell.execute_reply.started":"2023-05-31T07:51:16.975893Z","shell.execute_reply":"2023-05-31T07:51:16.983200Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\n\nfrom transformers import SegformerForSemanticSegmentation\n\n\nclass MixUpSample(nn.Module):\n    def __init__(self, scale_factor=4):\n        super().__init__()\n        self.mixing = nn.Parameter(torch.tensor(0.5))\n        self.scale_factor = scale_factor\n\n    def forward(self, x):\n        x = self.mixing * F.interpolate(\n            x, scale_factor=self.scale_factor, mode=\"bilinear\", align_corners=False\n        ) + (1 - self.mixing) * F.interpolate(\n            x, scale_factor=self.scale_factor, mode=\"nearest\"\n        )\n        return x\n    \nclass HubmapModel(nn.Module):\n    def __init__(self):\n        super(HubmapModel, self).__init__()\n\n        self.model = SegformerForSemanticSegmentation.from_pretrained(\n            config.MODEL_PATH, num_labels=1, ignore_mismatched_sizes=True\n        )\n        self.mixup = MixUpSample()\n\n    def forward(self, image):\n        img_segs = self.model(image)\n\n        upsampled_logits = self.mixup(img_segs.logits)\n        return upsampled_logits","metadata":{"papermill":{"duration":0.017635,"end_time":"2022-09-17T05:34:12.702768","exception":false,"start_time":"2022-09-17T05:34:12.685133","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-05-31T07:51:16.986585Z","iopub.execute_input":"2023-05-31T07:51:16.987120Z","iopub.status.idle":"2023-05-31T07:51:24.993417Z","shell.execute_reply.started":"2023-05-31T07:51:16.987087Z","shell.execute_reply":"2023-05-31T07:51:24.992425Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## MAIN","metadata":{"papermill":{"duration":0.004849,"end_time":"2022-09-17T05:34:12.712439","exception":false,"start_time":"2022-09-17T05:34:12.707590","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import os\ntest_image_id = os.listdir(\"/kaggle/input/hubmap-hacking-the-human-vasculature/test\")\ntest_image_id = [i[:-4] for i in test_image_id]\n","metadata":{"papermill":{"duration":0.02922,"end_time":"2022-09-17T05:34:12.746510","exception":false,"start_time":"2022-09-17T05:34:12.717290","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-05-31T07:51:24.994741Z","iopub.execute_input":"2023-05-31T07:51:24.996884Z","iopub.status.idle":"2023-05-31T07:51:25.003609Z","shell.execute_reply.started":"2023-05-31T07:51:24.996848Z","shell.execute_reply":"2023-05-31T07:51:25.002760Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_paths = [\n              \"/kaggle/input/train-hubmap-hacking-vasculature/fold_0best_model_epoch2_0.013107199703807039.pth\",\n#               \"../input/hubmap-coat-lite-medium/model-1.pth\",\n#               \"../input/hubmap-coat-lite-medium/model-2.pth\",\n#               \"../input/hubmap-coat-lite-medium/model-3.pth\",\n#               \"../input/hubmap-coat-lite-medium/model-4.pth\", \n              ]","metadata":{"papermill":{"duration":0.015016,"end_time":"2022-09-17T05:34:12.766114","exception":false,"start_time":"2022-09-17T05:34:12.751098","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-05-31T07:53:11.561046Z","iopub.execute_input":"2023-05-31T07:53:11.561449Z","iopub.status.idle":"2023-05-31T07:53:11.566967Z","shell.execute_reply.started":"2023-05-31T07:53:11.561417Z","shell.execute_reply":"2023-05-31T07:53:11.565563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rle_list = []\nheight = []\nfor image_id in test_image_id:\n\n    ###\n    model = HubmapModel()\n    model.to(\"cuda\")\n    \n\n    valid_images = [os.path.join(\"/kaggle/input/hubmap-hacking-the-human-vasculature/test\",str(image_id) + \".tif\")]\n\n    valid_dataset = HubDataset(valid_images)\n    valid_loader = torch.utils.data.DataLoader(valid_dataset,batch_size=config.VALID_BATCH_SIZE,shuffle=False,pin_memory=True) \n    \n    mask = np.zeros((config.IMAGE_SIZE, config.IMAGE_SIZE))\n    \n    for path in model_paths:\n        \n        model.load_state_dict(torch.load(path))\n        masks_output = infer(model=model,valid_loader=valid_loader,device=config.DEVICE)\n\n        mask += masks_output[0][0].reshape(masks_output[0][0].shape[1],masks_output[0][0].shape[2])\n        \n    mask = mask/len(model_paths)\n\n    threshold = filters.threshold_mean(mask) ##  isodata, otsu, li, mean, yen, minimum\n    mask = mask > 0.395\n#     mask = mask.astype(np.int8)\n    \n    seg_instances = get_vessels(mask)\n    \n    pred_string = \"\"\n    for i, binmask in enumerate(seg_instances):\n        encoded = encode_binary_mask(binmask)\n\n        if i == 0:\n            pred_string += f\"0 1.0 {encoded.decode('utf-8')}\"\n        else:\n            pred_string += f\" 0 1.0 {encoded.decode('utf-8')}\"\n            \n    print(mask.shape)\n    io.imshow(mask)\n    ###\n    rle_list.append(pred_string)\n    height.append(512)","metadata":{"papermill":{"duration":22.620229,"end_time":"2022-09-17T05:34:35.391175","exception":false,"start_time":"2022-09-17T05:34:12.770946","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-05-31T07:56:04.445689Z","iopub.execute_input":"2023-05-31T07:56:04.446075Z","iopub.status.idle":"2023-05-31T07:56:05.502895Z","shell.execute_reply.started":"2023-05-31T07:56:04.446043Z","shell.execute_reply":"2023-05-31T07:56:05.501914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# upsampled_logits = nn.functional.interpolate(\n#             img_segs.logits, image.shape[2:], mode=\"bilinear\"\n#         )","metadata":{"execution":{"iopub.status.busy":"2023-05-31T07:56:11.056954Z","iopub.execute_input":"2023-05-31T07:56:11.058152Z","iopub.status.idle":"2023-05-31T07:56:11.063578Z","shell.execute_reply.started":"2023-05-31T07:56:11.058097Z","shell.execute_reply":"2023-05-31T07:56:11.062059Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(threshold)","metadata":{"papermill":{"duration":0.018268,"end_time":"2022-09-17T05:34:35.414868","exception":false,"start_time":"2022-09-17T05:34:35.396600","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-05-31T07:56:11.884934Z","iopub.execute_input":"2023-05-31T07:56:11.887662Z","iopub.status.idle":"2023-05-31T07:56:11.893301Z","shell.execute_reply.started":"2023-05-31T07:56:11.887625Z","shell.execute_reply":"2023-05-31T07:56:11.892098Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# submission = pd.read_csv(\"/kaggle/input/hubmap-hacking-the-human-vasculature/sample_submission.csv\")","metadata":{"papermill":{"duration":0.022703,"end_time":"2022-09-17T05:34:35.442942","exception":false,"start_time":"2022-09-17T05:34:35.420239","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-05-31T07:56:13.545062Z","iopub.execute_input":"2023-05-31T07:56:13.545428Z","iopub.status.idle":"2023-05-31T07:56:13.550037Z","shell.execute_reply.started":"2023-05-31T07:56:13.545398Z","shell.execute_reply":"2023-05-31T07:56:13.548901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.DataFrame()\nsubmission['id'] = test_image_id\nsubmission['height'] = height\nsubmission['width'] = height\nsubmission['prediction_string'] = rle_list\n\n\nsubmission = submission.set_index('id')\nsubmission.to_csv(\"submission.csv\")","metadata":{"papermill":{"duration":0.019959,"end_time":"2022-09-17T05:34:35.468376","exception":false,"start_time":"2022-09-17T05:34:35.448417","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-05-31T07:56:15.380133Z","iopub.execute_input":"2023-05-31T07:56:15.380504Z","iopub.status.idle":"2023-05-31T07:56:15.391781Z","shell.execute_reply.started":"2023-05-31T07:56:15.380474Z","shell.execute_reply":"2023-05-31T07:56:15.390530Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.head()","metadata":{"papermill":{"duration":0.024079,"end_time":"2022-09-17T05:34:35.497713","exception":false,"start_time":"2022-09-17T05:34:35.473634","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-05-31T07:56:17.005056Z","iopub.execute_input":"2023-05-31T07:56:17.005426Z","iopub.status.idle":"2023-05-31T07:56:17.015646Z","shell.execute_reply.started":"2023-05-31T07:56:17.005395Z","shell.execute_reply":"2023-05-31T07:56:17.014469Z"},"trusted":true},"execution_count":null,"outputs":[]}]}