{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Purpose\nThis notebook works out a solution for cell segmination\n\nReferences:\n    https://github.com/CellProfiling/HPA-Cell-Segmentation"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"\nimport pandas as pd \nimport numpy as np\n\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\n\nfrom PIL import Image  \nfrom IPython.display import display \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"!pip install 'git+https://github.com/haoxusci/pytorch_zoo@master#egg=pytorch_zoo'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"!pip install https://github.com/CellProfiling/HPA-Cell-Segmentation/archive/master.zip","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import hpacellseg.cellsegmentator as cellsegmentator\nfrom hpacellseg.utils import label_cell, label_nuclei","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Parameters"},{"metadata":{"trusted":true},"cell_type":"code","source":"ROOT_PATH = '/kaggle/input/hpa-single-cell-image-classification/'\n\nCHANNELS = np.array(['red', 'green', 'blue', 'yellow'])\n\nCHANNEL_RED = 0    # microtubule channels\nCHANNEL_GREEN = 1  # protein of interest\nCHANNEL_BLUE = 2   # nuclei channels\nCHANNEL_YELLOW = 3 # endoplasmic reticulum \n\nCHANNEL_SIZE = len(CHANNELS)\nSAMPLE_SIZE = 5","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Functions"},{"metadata":{"trusted":true},"cell_type":"code","source":"#\n# Get array of all images for given sample id\n#\ndef get_images(id):\n    images = list()\n    for channel in CHANNELS:\n        path = ROOT_PATH + 'train/{}_{}.png'.format(id, channel)\n        image = Image.open(path) \n        images.append(image)\n    return images","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#\n# Get single image that blends all RGBY into RGB\n#\ndef get_blended_image(id): \n    # get rgby images for sample\n    images = get_images(id)\n\n    # blend rgby images into single array\n    blended_array = np.stack((\n            np.maximum(images[0], images[3]),\n            np.maximum(images[1], images[3]),\n            images[2]\n        ), 2)\n\n    # Create PIL Image\n    blended_image = Image.fromarray( np.uint8(blended_array) )\n    return blended_image","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Read Trainning Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train = pd.read_csv(ROOT_PATH + 'train.csv')\nprint(\"Trainning data length: {}\".format(len(df_train)))\ndf_train.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# if sample size is set then reduce trainning set accordingly\nif SAMPLE_SIZE > -1:\n    df_train = df_train.sample(SAMPLE_SIZE)\n    df_train.reset_index(inplace=True);","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"NUC_MODEL = \"./nuclei-model.pth\"\nCELL_MODEL = \"./cell-model.pth\"\nsegmentator = cellsegmentator.CellSegmentator(\n    NUC_MODEL,\n    CELL_MODEL,\n    scale_factor=0.25,\n    device=\"cuda\",\n    padding=False,\n    multi_channel_model=True,\n)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Explore Using HPA-Cell-Segmentation\n\nTake the first image from the samples and walk through steps to segment cells."},{"metadata":{"trusted":true},"cell_type":"code","source":"# id to use while exploring\nsample_id = df_train['ID'].iloc[0]\n\nimages = get_images(sample_id)\n\nnuc_segmentations = segmentator.pred_nuclei([np.asarray( images[CHANNEL_BLUE] )])\nprint(np.shape(nuc_segmentations))\n\n# For full cells\ncell_segmentations = cell_segmentations = segmentator.pred_cells([\n        [np.asarray( images[CHANNEL_RED] )],\n        [np.asarray( images[CHANNEL_YELLOW] )],\n        [np.asarray( images[CHANNEL_BLUE] )]\n    ])\nprint(np.shape(cell_segmentations))\n   ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"np.shape(nuc_segmentations)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"nuclei_mask = label_nuclei(nuc_segmentations[0])\nprint(np.shape(nuclei_mask))\n\ncell_nuclei_mask, cell_mask = label_cell(nuc_segmentations[0], cell_segmentations[0])\nprint(np.shape(nuclei_mask))\nprint(np.shape(cell_mask))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize=(25,25))\n\n# Nuclei mask\nnuclei_image = Image.fromarray( np.uint8(nuclei_mask) )\n\nax = fig.add_subplot(1, 4, 1)\nax.set_title(\"Nuclei Mask\")\nplt.imshow(np.asarray(nuclei_image))\n\n# Cell nuclei mask\ncell_nuclei_image = Image.fromarray( np.uint8(cell_nuclei_mask) )\n\nax = fig.add_subplot(1, 4, 2)\nax.set_title(\"Cell Nuclei Mask\")\nplt.imshow(np.asarray(cell_nuclei_image))\n\n# Cell mask\ncell_image = Image.fromarray( np.uint8(cell_mask) )\n\nax = fig.add_subplot(1, 4, 3)\nax.set_title(\"Cell Mask\")\nplt.imshow(np.asarray(cell_image))\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Isolate Each Segment\n\nIsolate and separate each cell's mask into separate images"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Get unique vector of segment numbers\nnumbers = set( np.ravel(cell_mask) )\nnumbers.remove(0)\n\nfig = plt.figure(figsize=(25,6*len(numbers)/4))\nindex = 1\n\n# plot original cell mask from above\nax = fig.add_subplot((len(numbers)//4)+1, 4, index)\nax.set_title(\"Complete Cell Mask\")\nplt.imshow(np.asarray(cell_image))\nindex = index + 1\n\nfor number in numbers:\n    # set all other 'numbers' to zero in cell mask\n    isolated = np.where(cell_mask == number, cell_mask, 0)\n\n    # plot isolated image\n    ax = fig.add_subplot((len(numbers)//4)+1, 4, index)\n    ax.set_title(\"Segment: {}\".format(number))\n\n    plt.imshow(isolated)\n    index = index + 1","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Crop Cells\n\nUse the mask to cut cells out of the original blended image"},{"metadata":{"trusted":true},"cell_type":"code","source":"blended_image = get_blended_image(sample_id)\nblended_array = np.asarray(blended_image)\n\n# Get unique vector of segment numbers\nnumbers = np.unique(cell_mask)\nnumbers = np.delete(numbers, [0])\n\n# build figure\nfig = plt.figure(figsize=(25,6*len(numbers)/4))\nindex = 1\n\n# plot original cell mask from above\nax = fig.add_subplot((len(numbers)//4)+1, 4, index)\nax.set_title(\"Blended Cell Image\")\nplt.imshow(np.asarray(blended_image))\nindex = index + 1\n\n# plot original cell mask from above\nax = fig.add_subplot((len(numbers)//4)+1, 4, index)\nax.set_title(\"Complete Cell Mask\")\nplt.imshow(np.asarray(cell_image))\nindex = index + 1\n\nfor number in numbers:\n    # set all other 'numbers' to 255 in cell mask\n    isolated_mask = np.where(cell_mask == number, True, False)\n    \n    # match shape for RGB\n    isolated_mask = np.stack((isolated_mask, isolated_mask, isolated_mask), axis=2)\n    \n    # crop across all channels\n    isolated_image = np.where(isolated_mask == True, blended_array, 0)\n    \n    # plot isolated image\n    ax = fig.add_subplot((len(numbers)//4)+2, 4, index)\n    ax.set_title(\"Segment: {}\".format(number))\n\n    plt.imshow(isolated_image)\n    index = index + 1","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Segment All Samples\n\nUse what was learned above and loop through all samples printing the blended image and the cell mask."},{"metadata":{"trusted":true},"cell_type":"code","source":"masks = {}\n\nsample_count = 1\nfor sample_index, df_sample in df_train.iterrows():\n    images = get_images(df_sample['ID'])\n    \n    print(\"\\rSegmentation started (count={}, current_id={})  \".format(sample_count, df_sample['ID']), end=\"\")\n    \n    # Segment nuclie\n    nuc_segmentations = segmentator.pred_nuclei([np.asarray( images[CHANNEL_BLUE] )])\n\n    # For full cells\n    cell_segmentations = cell_segmentations = segmentator.pred_cells([\n        [np.asarray( images[CHANNEL_RED] )],\n        [np.asarray( images[CHANNEL_YELLOW] )],\n        [np.asarray( images[CHANNEL_BLUE] )]\n    ])\n\n    nuclei_mask, cell_mask = label_cell(nuc_segmentations[0], cell_segmentations[0])\n    \n    masks[df_sample['ID']] = [nuclei_mask, cell_mask]\n\n    print(\"\\rSegmentation completed (count={}, last_id={})   \".format(sample_count, df_sample['ID']), end=\"\")\n    sample_count = sample_count + 1\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nCOLUMN_COUNT = 5\nROW_COUNT = 50\nindex = 1\n\nfig = plt.figure(figsize=(30,5*ROW_COUNT))\n\nfor sample_index, df_sample in df_train.iterrows():\n    \n    images = get_images(df_sample['ID'])\n    [nuclei_mask, cell_mask] = masks[df_sample['ID']]\n\n    # Blended image\n    blended_image = get_blended_image(df_sample['ID'])\n    blended_array = np.asarray(blended_image)\n\n    ax = fig.add_subplot(ROW_COUNT, COLUMN_COUNT, index)\n    ax.set_title(\"Blended Image\")\n    plt.imshow(np.asarray(blended_image))\n    index = index + 1\n    if index > (ROW_COUNT*5):\n        break\n\n    # Get unique vector of segment numbers\n    numbers = np.unique(cell_mask)\n    numbers = np.delete(numbers, [0])\n    \n    for number in numbers:\n        # Isolate and crop cell from blended image\n        isolated_mask = np.where(cell_mask == number, True, False)\n        isolated_mask = np.stack((isolated_mask, isolated_mask, isolated_mask), axis=2)\n        isolated_image = np.where(isolated_mask == True, blended_array, 0)\n\n        ax = fig.add_subplot(ROW_COUNT, COLUMN_COUNT, index)\n        ax.set_title(\"Blended Cell\")\n        plt.imshow(np.asarray(isolated_image))\n\n        index = index + 1\n        if index >= (ROW_COUNT*5):\n            break\n\n\n","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}