{"cells":[{"metadata":{},"cell_type":"markdown","source":"Credits:\n* https://www.kaggle.com/rdizzl3/hpa-segmentation-masks-no-internet\n* https://www.kaggle.com/frlemarchand/generate-masks-from-weak-image-level-labels/\n"},{"metadata":{},"cell_type":"markdown","source":"# Installation"},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install -q \"../input/pycocotools/pycocotools-2.0-cp37-cp37m-linux_x86_64.whl\"\n!pip install -q \"../input/hpapytorchzoozip/pytorch_zoo-master\"\n!pip install -q \"../input/hpacellsegmentatormaster/HPA-Cell-Segmentation-master\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\n# Making pretrained weights work without needing to find the default filename\nif not os.path.exists('/root/.cache/torch/hub/checkpoints/'):\n        os.makedirs('/root/.cache/torch/hub/checkpoints/')\n# !cp '../input/resnet50/resnet50.pth' '/root/.cache/torch/hub/checkpoints/resnet50-19c8e357.pth'\n!cp '../input/resnet34/resnet34.pth' '/root/.cache/torch/hub/checkpoints/resnet34-333f7ec4.pth'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from fastai.vision.all import *\nimport pandas as pd\nimport numpy as np\nfrom tqdm.autonotebook import tqdm\nimport imageio","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_image_names(image_id: str) -> list:\n    # mt is the mitchondria\n    mt = f'/kaggle/input/hpa-single-cell-image-classification/test/{image_id}_red.png'    \n    # er is the endoplasmic reticulum\n    er = f'/kaggle/input/hpa-single-cell-image-classification/test/{image_id}_yellow.png'    \n    # nu is the nuclei\n    nu = f'/kaggle/input/hpa-single-cell-image-classification/test/{image_id}_blue.png'    \n    return [[mt], [er], [nu]]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import hpacellseg.cellsegmentator as cellsegmentator\nfrom hpacellseg.utils import label_cell, label_nuclei\n\nNUC_MODEL = '../input/hpacellsegmentatormodelweights/dpn_unet_nuclei_v1.pth'\nCELL_MODEL = '../input/hpacellsegmentatormodelweights/dpn_unet_cell_3ch_v1.pth'\n\nsegmentator = cellsegmentator.CellSegmentator(\n    NUC_MODEL,\n    CELL_MODEL,\n    scale_factor=0.25,\n    device='cuda',\n    padding=True,\n    multi_channel_model=True\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"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  \"\"\"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.decode('ascii')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Inference"},{"metadata":{"trusted":true},"cell_type":"code","source":"tpath = Path('../input/hpa-single-cell-image-classification')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub = pd.read_csv(tpath/'sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# sub = sub.sample(frac=0.03)\nsub.ImageWidth.value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub_dfs = []\nfor dim in sub.ImageWidth.unique():\n    df = sub[sub['ImageWidth'] == dim].copy().reset_index(drop=True)\n    sub_dfs.append(df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bs = 8\nfor sub in sub_dfs:\n    print(f'Starting prediction for image size: {sub.ImageWidth.loc[0]}')\n    for start in range(0, len(sub), bs):\n        if start + bs > len(sub): end = len(sub)\n        else: end = start + bs\n            \n        images = []\n        for row in range(start, end):\n            image_id = sub['ID'].loc[row]\n            img = build_image_names(image_id=image_id)\n            images.append(img)\n\n        images = np.stack(images).squeeze()\n        images = np.transpose(images).tolist()\n\n        try: \n            nuc_segmentations = segmentator.pred_nuclei(images[2])\n            cell_segmentations = segmentator.pred_cells(images)\n\n            predstrings = []\n            for i in tqdm(range(len(cell_segmentations))):\n                _, cell_mask = label_cell(nuc_segmentations[i], cell_segmentations[i])\n                predstring = ''\n                for j in range(np.max(cell_mask)):\n                    bmask = (cell_mask == j)\n                    enc = encode_binary_mask(bmask)\n                    predstring += '0 1 ' + enc + ' '\n                predstrings.append(predstring)\n\n            assert len(predstrings) == len(sub.loc[start:end-1])\n            sub['PredictionString'].loc[start:end-1] = predstrings\n            \n        except: continue","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"all_subs = pd.concat(sub_dfs, ignore_index=True, sort=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"all_subs.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"all_subs.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"all_subs.tail()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}