{"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 -q \"/kaggle/input/pycocotools/pycocotools-2.0-cp37-cp37m-linux_x86_64.whl\"\n!pip install -q \"/kaggle/input/hpapytorchzoozip/pytorch_zoo-master\"\n!pip install -q \"/kaggle/input/hpacellsegmentatormaster/HPA-Cell-Segmentation-master\"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\nsys.path.insert(0, \"../input/hpa-script\")\nsys.path.insert(0, \"../input/timm-pytorch-image-models/pytorch-image-models-master\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import base64\nimport glob\nimport typing as t\nimport zlib\n\nimport albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\nfrom pycocotools import _mask as coco_mask\nimport pytorch_lightning as pl\n\nimport torch\nfrom torch.utils.data import Dataset, DataLoader\n\nfrom models import HPAClassifier\nfrom dataset import HPA_RGB_MEAN, HPA_RGB_STD","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import hpacellseg.cellsegmentator as cellsegmentator","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"Utility functions for the HPA Cell Segmentation package.\"\"\"\nimport scipy.ndimage as ndi\nfrom skimage import filters, measure, segmentation\nfrom skimage.morphology import (binary_erosion, closing, disk,\n                                remove_small_holes, remove_small_objects)\n\nHIGH_THRESHOLD = 0.4\nLOW_THRESHOLD = HIGH_THRESHOLD - 0.25\n\ndef __fill_holes(image):\n    \"\"\"Fill_holes for labelled image, with a unique number.\"\"\"\n    boundaries = segmentation.find_boundaries(image)\n    image = np.multiply(image, np.invert(boundaries))\n    image = ndi.binary_fill_holes(image > 0)\n    image = ndi.label(image)[0]\n    return image\n\ndef label_cell(nuclei_pred, cell_pred):\n    \"\"\"Label the cells and the nuclei.\n    Keyword arguments:\n    nuclei_pred -- a 3D numpy array of a prediction from a nuclei image.\n    cell_pred -- a 3D numpy array of a prediction from a cell image.\n    Returns:\n    A tuple containing:\n    nuclei-label -- A nuclei mask data array.\n    cell-label  -- A cell mask data array.\n    0's in the data arrays indicate background while a continous\n    strech of a specific number indicates the area for a specific\n    cell.\n    The same value in cell mask and nuclei mask refers to the identical cell.\n    NOTE: The nuclei labeling from this function will be sligthly\n    different from the values in :func:`label_nuclei` as this version\n    will use information from the cell-predictions to make better\n    estimates.\n    \"\"\"\n    def __wsh(\n        mask_img,\n        threshold,\n        border_img,\n        seeds,\n        threshold_adjustment=0.35,\n        small_object_size_cutoff=10,\n    ):\n        img_copy = np.copy(mask_img)\n        m = seeds * border_img  # * dt\n        img_copy[m <= threshold + threshold_adjustment] = 0\n        img_copy[m > threshold + threshold_adjustment] = 1\n        img_copy = img_copy.astype(np.bool)\n        img_copy = remove_small_objects(img_copy, small_object_size_cutoff).astype(\n            np.uint8\n        )\n\n        mask_img[mask_img <= threshold] = 0\n        mask_img[mask_img > threshold] = 1\n        mask_img = mask_img.astype(np.bool)\n        mask_img = remove_small_holes(mask_img, 63) # CHECK 1/8 ORIGINAL VALUE: 1000\n        mask_img = remove_small_objects(mask_img, 1).astype(np.uint8) # CHECK 2/8 ORIGINAL VALUE: 8\n        markers = ndi.label(img_copy, output=np.uint32)[0]\n        labeled_array = segmentation.watershed(\n            mask_img, markers, mask=mask_img, watershed_line=True\n        )\n        return labeled_array\n\n    nuclei_label = __wsh(\n        nuclei_pred[..., 2] / 255.0,\n        0.4,\n        1 - (nuclei_pred[..., 1] + cell_pred[..., 1]) / 255.0 > 0.05,\n        nuclei_pred[..., 2] / 255,\n        threshold_adjustment=-0.25,\n        small_object_size_cutoff=32, # CHECK 3/8 ORIGINAL VALUE: 500\n    )\n\n    # for hpa_image, to remove the small pseduo nuclei\n    nuclei_label = remove_small_objects(nuclei_label, 157) # CHECK 4/8 ORIGINAL VALUE: 2500\n    nuclei_label = measure.label(nuclei_label)\n    # this is to remove the cell borders' signal from cell mask.\n    # could use np.logical_and with some revision, to replace this func.\n    # Tuned for segmentation hpa images\n    threshold_value = max(0.22, filters.threshold_otsu(cell_pred[..., 2] / 255) * 0.5)\n    # exclude the green area first\n    cell_region = np.multiply(\n        cell_pred[..., 2] / 255 > threshold_value,\n        np.invert(np.asarray(cell_pred[..., 1] / 255 > 0.05, dtype=np.int8)),\n    )\n    sk = np.asarray(cell_region, dtype=np.int8)\n    distance = np.clip(cell_pred[..., 2], 255 * threshold_value, cell_pred[..., 2])\n    cell_label = segmentation.watershed(-distance, nuclei_label, mask=sk)\n    cell_label = remove_small_objects(cell_label, 344).astype(np.uint8) # CHECK 5/8 ORIGINAL VALUE: 5500\n    selem = disk(2) # CHECK 6/8 ORIGINAL VALUE: 6\n    cell_label = closing(cell_label, selem)\n    cell_label = __fill_holes(cell_label)\n    # this part is to use green channel, and extend cell label to green channel\n    # benefit is to exclude cells clear on border but without nucleus\n    sk = np.asarray(\n        np.add(\n            np.asarray(cell_label > 0, dtype=np.int8),\n            np.asarray(cell_pred[..., 1] / 255 > 0.05, dtype=np.int8),\n        )\n        > 0,\n        dtype=np.int8,\n    )\n    cell_label = segmentation.watershed(-distance, cell_label, mask=sk)\n    cell_label = __fill_holes(cell_label)\n    cell_label = np.asarray(cell_label > 0, dtype=np.uint8)\n    cell_label = measure.label(cell_label)\n    cell_label = remove_small_objects(cell_label, 344) # CHECK 7/8 ORIGINAL VALUE: 5500\n    cell_label = measure.label(cell_label)\n    cell_label = np.asarray(cell_label, dtype=np.uint16)\n    nuclei_label = np.multiply(cell_label > 0, nuclei_label) > 0\n    nuclei_label = measure.label(nuclei_label)\n    nuclei_label = remove_small_objects(nuclei_label, 157) # CHECK 8/8 ORIGINAL VALUE: 2500\n    nuclei_label = np.multiply(cell_label, nuclei_label > 0)\n\n    return nuclei_label, cell_label","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class HPATestDataset(Dataset):\n    def __init__(self, dataset_dir):\n        super().__init__()\n        self.dataset_dir = dataset_dir\n        self.make_file_list()\n    \n    def __getitem__(self, index):\n        red = cv2.imread(self.red[index], cv2.IMREAD_GRAYSCALE)\n        green = cv2.imread(self.green[index], cv2.IMREAD_GRAYSCALE)\n        blue = cv2.imread(self.blue[index], cv2.IMREAD_GRAYSCALE)\n        yellow = cv2.imread(self.yellow[index], cv2.IMREAD_GRAYSCALE)\n        \n        sample = {\n            \"red\": red,\n            \"green\": green,\n            \"blue\": blue,\n            \"yellow\": yellow,\n        }\n        return sample\n    \n    def __len__(self):\n        return len(self.red)\n    \n    def make_file_list(self):\n        self.red = glob.glob(self.dataset_dir + \"/\" + \"*_red.png\")\n        self.green = [f.replace(\"red\", \"green\") for f in self.red]\n        self.blue = [f.replace(\"red\", \"blue\") for f in self.red]\n        self.yellow = [f.replace(\"red\", \"yellow\") for f in self.red]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class HPACellTestDataset(HPATestDataset):\n    def __getitem__(self, index):\n        red = cv2.imread(self.red[index], cv2.IMREAD_GRAYSCALE)\n        green = cv2.imread(self.green[index], cv2.IMREAD_GRAYSCALE)\n        blue = cv2.imread(self.blue[index], cv2.IMREAD_GRAYSCALE)\n        yellow = cv2.imread(self.yellow[index], cv2.IMREAD_GRAYSCALE)\n\n        sample = {\n            \"nuc\": [blue],\n            \"cell\": [\n                [red], [yellow], [blue]\n            ],\n            \"rgb\": np.dstack((red, green, blue)),\n            \"image_id\": self.red[index].split(\"/\")[-1].split(\"_\")[0],\n        }\n        \n        return sample","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_batch(samples):\n    nuc = [sample[\"nuc\"][0] for sample in samples]\n    mt = [sample[\"cell\"][0][0] for sample in samples]\n    er = [sample[\"cell\"][1][0] for sample in samples]\n    nu = [sample[\"cell\"][2][0] for sample in samples]\n    cell = [mt, er, nu]\n    \n    rgb = [sample[\"rgb\"] for sample in samples]\n    image_id = [sample[\"image_id\"] for sample in samples]\n    return {\"nuc\":nuc, \"cell\":cell, \"rgb\": rgb, \"image_id\": image_id}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def 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","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_bbox_from_mask(mask):\n    \"\"\"get bbox from single boolean mask\"\"\"\n    coords = np.argwhere(mask)\n    x_min = coords[:, 1].min()\n    x_max = coords[:, 1].max()\n    y_min = coords[:, 0].min()\n    y_max = coords[:, 0].max()\n    \n    bbox = [x_min, x_max, y_min, y_max]\n    return bbox","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_cell_mask_bbox(mask, mask_id):\n    fig, ax = plt.subplots()\n    mask = mask==mask_id\n    bbox = get_bbox_from_mask(mask)\n    bbox_mask = np.zeros(mask.shape)\n    bbox_mask[bbox[2]:bbox[3], bbox[0]:bbox[1]] = 1\n    ax.imshow(mask, alpha=0.5)\n    ax.imshow(bbox_mask, alpha=0.3)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_single_cell(single_cell_mask, rgb_image):\n    fig, (ax1, ax2) = plt.subplots(2, figsize=(10, 20))\n    \n    bbox = get_bbox_from_mask(single_cell_mask)\n    bbox_mask = np.zeros(single_cell_mask.shape)\n    bbox_mask[bbox[2]:bbox[3], bbox[0]:bbox[1]] = 1\n    \n    pad_rgb_image = rgb_image[bbox[2]:bbox[3], bbox[0]:bbox[1], :]\n\n    ax1.imshow(rgb_image, alpha=1.0)\n    ax1.imshow(single_cell_mask, alpha=0.5)\n    ax1.imshow(bbox_mask, alpha=0.3)\n    \n    ax2.imshow(pad_rgb_image)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def inference(image, model, device, height, width):\n    transform = A.Compose(\n        [\n            A.Resize(height=height, width=width),\n            A.Normalize(mean=HPA_RGB_MEAN, std=HPA_RGB_STD),\n            ToTensorV2(),\n        ]\n    )\n    \n    image = transform(image=image)[\"image\"]\n    image = torch.unsqueeze(image, 0)\n\n    if DEBUG:\n        print(f\"clf inference resized image.size(): {image.size()}\")\n\n    if isinstance(model, list):\n        pred_list = []\n        for m in model:\n            pred = m(image.to(device))\n            pred_list.append(pred)\n            \n        pred = torch.stack(pred_list, dim=0)\n        if DEBUG: print(f\"clf inference pred.size(): {pred.size()}\")\n        pred = torch.mean(pred, 0)\n        if DEBUG: print(f\"clf inference pred.size(): {pred.size()}\")\n    else:\n        pred = model(image.to(device))\n        if DEBUG: print(f\"clf inference pred.size(): {pred.size()}\")\n\n    pred = torch.squeeze(pred, 0)\n    if DEBUG: print(f\"clf inference pred.size(): {pred.size()}\")\n    \n    return pred","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def inference_tta(image, model, device, height, width):\n    transform = A.Compose(\n        [\n            A.Resize(height=height, width=width),\n            A.Normalize(mean=HPA_RGB_MEAN, std=HPA_RGB_STD),\n            ToTensorV2(),\n        ]\n    )\n\n    transform_hflip = A.Compose(\n        [\n            A.Resize(height=height, width=width),\n            A.HorizontalFlip(p=1.0),\n            A.Normalize(mean=HPA_RGB_MEAN, std=HPA_RGB_STD),\n            ToTensorV2(),\n        ]\n    )\n\n    transform_vflip = A.Compose(\n        [\n            A.Resize(height=height, width=width),\n            A.VerticalFlip(p=1.0),\n            A.Normalize(mean=HPA_RGB_MEAN, std=HPA_RGB_STD),\n            ToTensorV2(),\n        ]\n    )\n\n#     transform_rot90f = A.Compose(\n#         [\n#             A.Resize(height=height, width=width),\n#             A.Rotate((90, 90), border_mode=cv2.BORDER_CONSTANT, value=0, p=0.5),\n#             A.Normalize(mean=HPA_RGB_MEAN, std=HPA_RGB_STD),\n#             ToTensorV2(),\n#         ]\n#     )\n\n#     transform_rot90r = A.Compose(\n#         [\n#             A.Resize(height=height, width=width),\n#             A.Rotate((-90, -90), border_mode=cv2.BORDER_CONSTANT, value=0, p=0.5),\n#             A.Normalize(mean=HPA_RGB_MEAN, std=HPA_RGB_STD),\n#             ToTensorV2(),\n#         ]\n#     )\n\n    \n    transform_small = A.Compose(\n        [\n            A.Resize(height=int(height*0.8), width=int(width*0.8)),\n            A.PadIfNeeded(min_height=height, min_width=width, border_mode=cv2.BORDER_CONSTANT, value=0),\n            A.Normalize(mean=HPA_RGB_MEAN, std=HPA_RGB_STD),\n            ToTensorV2(),\n        ]\n    )\n    \n    transform_large = A.Compose(\n        [\n            A.Resize(height=int(height*1.2), width=int(width*1.2)),\n            A.CenterCrop(height=height, width=width, p=1.0),\n            A.Normalize(mean=HPA_RGB_MEAN, std=HPA_RGB_STD),\n            ToTensorV2(),\n        ]\n    )\n\n    image_org = transform(image=image)[\"image\"]\n    image_hflip = transform_hflip(image=image)[\"image\"]\n    image_vflip = transform_vflip(image=image)[\"image\"]\n#     image_rot90f = transform_rot90f(image=image)[\"image\"]\n#     image_rot90r = transform_rot90r(image=image)[\"image\"]\n    image_small = transform_small(image=image)[\"image\"]\n    image_large = transform_large(image=image)[\"image\"]\n\n    image = torch.stack(\n        [\n            image_org,\n            image_hflip,\n            image_vflip,\n#             image_rot90f,\n#             image_rot90r,\n            image_small,\n            image_large,\n        ],\n        axis=0\n    )\n\n    if DEBUG:\n        print(f\"clf inference resized image.size(): {image.size()}\")\n    \n    if isinstance(model, list):\n        pred_list = []\n        for m in model:\n            pred = m(image.to(device))\n            if DEBUG: print(f\"clf inference pred.size(): {pred.size()}\")\n            pred = torch.mean(pred, 0)\n            if DEBUG: print(f\"clf inference pred.size(): {pred.size()}\")\n            pred_list.append(pred)\n\n        pred = torch.stack(pred_list, dim=0)\n        if DEBUG: print(f\"clf inference pred.size(): {pred.size()}\")\n    else:\n        pred = model(image.to(device))\n        if DEBUG: print(f\"clf inference pred.size(): {pred.size()}\")\n\n    pred = torch.mean(pred, 0)\n    if DEBUG: print(f\"clf inference pred.size(): {pred.size()}\")\n\n    return pred","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def test_inference(test):\n    pred = [x * 0.01 for x in range(19)]\n    return pred","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_pred_string(cell_mask, image, clf, CHECK_PLOT=False, clf_image_height=1024, clf_image_width=1024):\n    num_mask = cell_mask.max()\n    pred_string = []\n    pred_string_check = []\n\n    for mask_id in range(1, num_mask):\n        # single cell mask\n        single_cell_mask = cell_mask==mask_id\n        bbox = get_bbox_from_mask(single_cell_mask)\n\n        # single cell rgb image\n        cell_image = image[bbox[2]:bbox[3], bbox[0]:bbox[1], :]\n\n        # pad cell rgb image\n        transform = A.PadIfNeeded(\n            min_height=image_height,\n            min_width=image_width,\n            border_mode=cv2.BORDER_CONSTANT,\n            value=0)\n        pad_cell_image = transform(image=cell_image)[\"image\"]\n\n        # check single cell\n        if CHECK_PLOT:\n            plot_single_cell(single_cell_mask, image)\n            CHECK_PLOT = False\n\n        # inference\n        if TTA:\n            pred = inference_tta(pad_cell_image, clf, device, height=clf_image_height, width=clf_image_width)\n        else:\n            pred = inference(pad_cell_image, clf, device, height=clf_image_height, width=clf_image_width)\n\n        if DEBUG:\n            print(f\"single_cell_mask.shape: {single_cell_mask.shape}\")\n\n        encoded_mask = encode_binary_mask(single_cell_mask)\n        encoded_mask = encoded_mask.decode(\"utf-8\")\n    \n        for label in range(19):\n            conf = pred[label]\n            if conf > PROB_THR:\n                pred_string.append(f\"{label} {conf} {encoded_mask}\")\n                pred_string_check.append(f\"{label} {conf:.2f} /\")\n        pred_string_check.append(f\"[{mask_id}]\\n\")\n        \n    pred_string = \" \".join(pred_string)\n    pred_string_check = \" \".join(pred_string_check).replace(\"\\n \", \"\\n\")\n    return pred_string, pred_string_check","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ----------\n# debug mode\n# ----------\nDEBUG = False","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ----------\n# settings\n# ----------\npl.seed_everything(0)\nseg_batch_size = 16 if not DEBUG else 4\nTEST_DIR = \"../input/hpa-single-cell-image-classification/test\"\nPROB_THR = 0.001\nCLF_IMAGE_SIZE = 1024\n\nTTA = True","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ----------\n# checkpoint\n# ----------\ncheckpoints = []\ncheckpoints.append(\"../input/hpa-checkpoint-final/b0-gce-full-base-aug-bce-fold-2_HPA-279_checkpoints_hpa-clf-epoch004-valid_loss0.036291.ckpt\")\ncheckpoints.append(\"../input/hpa-checkpoint-final/b0-gce-full-base-aug-bce-fold-0_HPA-281_checkpoints_hpa-clf-epoch004-valid_loss0.036503.ckpt\")\ncheckpoints.append(\"../input/hpa-checkpoint-final/b0-extra-rare-aug-bce-loss_HPA-267_checkpoints_hpa-clf-epoch009-valid_loss0.030838.ckpt\")\ncheckpoints.append(\"../input/hpa-checkpoint-final/seresnext26d_32x4d-full-base-aug-focal-fold-1_HPA-282_checkpoints_last.ckpt\")\n\nmodel_names = []\nmodel_names.append(\"tf_efficientnet_b0\")\nmodel_names.append(\"tf_efficientnet_b0\")\nmodel_names.append(\"tf_efficientnet_b0\")\nmodel_names.append(\"seresnext26d_32x4d\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ----------\n# device\n# ----------\ndevice = (\n    torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\n)\nprint(f\"device {device}\")\n\ntorch.set_grad_enabled(False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ----------\n# TestDataset\n# ----------\nds_cell = HPACellTestDataset(TEST_DIR)\n\nloader = DataLoader(\n    ds_cell,\n    batch_size=seg_batch_size,\n    shuffle=False,\n    num_workers=0,\n    collate_fn=make_batch,\n    pin_memory=False,\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ----------\n# Model SEG\n# ----------\nNUC_MODEL = \"../input/hpacellsegmentatormodelweights/dpn_unet_nuclei_v1.pth\"\nCELL_MODEL = \"../input/hpacellsegmentatormodelweights/dpn_unet_cell_3ch_v1.pth\"\nsegmentator = cellsegmentator.CellSegmentator(\n    NUC_MODEL,\n    CELL_MODEL,\n    scale_factor=1.0,\n    device=\"cuda\",\n    padding=True,\n    multi_channel_model=True,\n)\n\nsegmentator.nuclei_model = segmentator.nuclei_model.eval()\nsegmentator.cell_model = segmentator.cell_model.eval()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ----------\n# Model CLF\n# ----------\nclf_list = []\n\nfor checkpoint, model_name in zip(checkpoints, model_names):\n    clf = HPAClassifier.load_from_checkpoint(checkpoint, pretrained=False, model_name=model_name)\n    clf.to(device)\n    clf.eval();\n    clf_list.append(clf)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_id_list = []\nimage_width_list = []\nimage_height_list = []\npred_string_list = []\npred_string_check_list = []\n\nfor index, batch in enumerate(loader):\n    \n    batch_nuc = batch[\"nuc\"]\n    batch_mt, batch_er, batch_nu = batch[\"cell\"]\n\n    # get original image size\n    batch_image_size = [x.shape for x in batch_nuc]\n    \n    # resize to 1/4\n    batch_nuc = [cv2.resize(x, (int(x.shape[0]/4), int(x.shape[0]/4)), interpolation=cv2.INTER_AREA) for x in batch_nuc]\n    batch_mt = [cv2.resize(x, (int(x.shape[0]/4), int(x.shape[0]/4)), interpolation=cv2.INTER_AREA) for x in batch_mt]\n    batch_er = [cv2.resize(x, (int(x.shape[0]/4), int(x.shape[0]/4)), interpolation=cv2.INTER_AREA) for x in batch_er]\n    batch_nu = [cv2.resize(x, (int(x.shape[0]/4), int(x.shape[0]/4)), interpolation=cv2.INTER_AREA) for x in batch_nu]\n    batch_cell = [batch_mt, batch_er, batch_nu]\n    \n    # run segmentation\n    nuc_segmentations = segmentator.pred_nuclei(batch_nuc)\n    cell_segmentations = segmentator.pred_cells(batch_cell)\n    \n    batch_cell_mask = [\n        label_cell(nuc_seg, cell_seg)[1]\n        for nuc_seg, cell_seg in zip(nuc_segmentations, cell_segmentations)\n    ]\n    \n    if DEBUG:\n        for cell_mask in batch_cell_mask:\n            print(f\"cell_mask.shape: {cell_mask.shape}\")\n    \n    # resize cell_mask to original image size\n    batch_cell_mask = [\n        cv2.resize(cell_mask, image_size, interpolation=cv2.INTER_NEAREST)\n        for (cell_mask, image_size)\n        in zip(batch_cell_mask, batch_image_size)\n    ]\n    if DEBUG:\n        for cell_mask in batch_cell_mask:\n            print(f\"cell_mask.shape: {cell_mask.shape}\")\n    \n    # single sample from batch\n    for cell_mask, image, image_id in zip(batch_cell_mask, batch[\"rgb\"], batch[\"image_id\"]):\n\n        image_height = image.shape[0]\n        image_width = image.shape[1]\n        \n        if DEBUG:\n            print(f\"image.shape: {image.shape}, cell_mask.shape: {cell_mask.shape}\")\n    \n        CHECK_PLOT = False if not DEBUG else True\n        pred_string, pred_string_check = get_pred_string(\n            cell_mask,\n            image,\n            clf_list,\n            clf_image_height=CLF_IMAGE_SIZE,\n            clf_image_width=CLF_IMAGE_SIZE,\n            CHECK_PLOT=CHECK_PLOT\n        )\n    \n        image_id_list.append(image_id)\n        image_width_list.append(image_width)\n        image_height_list.append(image_height)\n        pred_string_list.append(pred_string)\n        pred_string_check_list.append(pred_string_check)\n\n    if DEBUG:\n        break","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.DataFrame(\n    data=zip(\n        image_id_list,\n        image_width_list,\n        image_height_list,\n        pred_string_list,\n        pred_string_check_list),\n    columns=[\n        \"ID\",\n        \"ImageWidth\",\n        \"ImageHeight\",\n        \"PredictionString\",\n        \"PredictionStringCheck\"\n    ]\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(df.PredictionStringCheck[0])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(df.PredictionStringCheck[1])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df = df[[\"ID\", \"ImageWidth\", \"ImageHeight\", \"PredictionString\"]]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"check_df = df[[\"ID\", \"ImageWidth\", \"ImageHeight\", \"PredictionStringCheck\"]]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"check_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"check_df.to_csv(\"check.csv\", index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}