{"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":"# Sartorius - Cell Instance Segmentation Image\n![](https://storage.googleapis.com/kaggle-competitions/kaggle/30201/logos/header.png?t=2021-09-03-15-27-46)","metadata":{}},{"cell_type":"markdown","source":"#### Import Necessary Library","metadata":{"execution":{"iopub.status.busy":"2021-10-21T06:26:39.595239Z","iopub.execute_input":"2021-10-21T06:26:39.595514Z","iopub.status.idle":"2021-10-21T06:26:39.599161Z","shell.execute_reply.started":"2021-10-21T06:26:39.595477Z","shell.execute_reply":"2021-10-21T06:26:39.598399Z"}}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport imageio\nimport matplotlib.pyplot as plt\nimport cv2\nfrom skimage.io import imread, imshow, imread_collection, concatenate_images\nfrom skimage.transform import resize\nfrom tqdm import tqdm\nfrom keras.models import Model, load_model\nfrom keras.layers import Input\nfrom keras.layers.core import Dropout, Lambda\nfrom keras.layers.convolutional import Conv2D, Conv2DTranspose\nfrom keras.layers.pooling import MaxPooling2D\nfrom keras.layers.merge import concatenate\nfrom keras.callbacks import EarlyStopping, ModelCheckpoint\nfrom keras import backend as K\nimport tensorflow as tf\nfrom skimage.morphology import label\nimport random","metadata":{"execution":{"iopub.status.busy":"2021-10-21T06:35:14.432336Z","iopub.execute_input":"2021-10-21T06:35:14.433139Z","iopub.status.idle":"2021-10-21T06:35:14.441902Z","shell.execute_reply.started":"2021-10-21T06:35:14.433095Z","shell.execute_reply":"2021-10-21T06:35:14.440675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#####  Load Sample Submission Data","metadata":{}},{"cell_type":"code","source":"sample_submission = pd.read_csv('../input/sartorius-cell-instance-segmentation/sample_submission.csv')","metadata":{"execution":{"iopub.status.busy":"2021-10-21T06:35:14.444102Z","iopub.execute_input":"2021-10-21T06:35:14.444678Z","iopub.status.idle":"2021-10-21T06:35:14.458225Z","shell.execute_reply.started":"2021-10-21T06:35:14.444632Z","shell.execute_reply":"2021-10-21T06:35:14.457477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Reference: https://www.kaggle.com/ihelon/cell-segmentation-run-length-decoding","metadata":{}},{"cell_type":"markdown","source":"**Decode and Plotting**","metadata":{}},{"cell_type":"code","source":"# Reference: https://www.kaggle.com/ihelon/cell-segmentation-run-length-decoding\n        \ndef rle_decode(mask_rle, shape, color=1):\n    '''\n    mask_rle: run-length as string formated (start length)\n    shape: (height, width, channels) of array to return \n    color: color for the mask\n    Returns numpy array (mask)\n\n    '''\n    s = mask_rle.split()\n    \n    starts = list(map(lambda x: int(x) - 1, s[0::2]))\n    lengths = list(map(int, s[1::2]))\n    ends = [x + y for x, y in zip(starts, lengths)]\n    \n    img = np.zeros((shape[0] * shape[1], shape[2]), dtype=np.float32)\n            \n    for start, end in zip(starts, ends):\n        img[start : end] = color\n    \n    return img.reshape(shape)\n\ndef plot_masks(image_id, colors=True):\n    labels = train_data[train_data[\"id\"] == image_id][\"annotation\"].tolist()\n\n    if colors:\n        mask = np.zeros((520, 704, 3))\n        for label in labels:\n            mask += rle_decode(label, shape=(520, 704, 3), color=np.random.rand(3))\n    else:\n        mask = np.zeros((520, 704, 1))\n        for label in labels:\n            mask += rle_decode(label, shape=(520, 704, 1))\n    mask = mask.clip(0, 1)\n\n    image = cv2.imread(f\"../input/sartorius-cell-instance-segmentation/train/{image_id}.png\")\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\n    plt.figure(figsize=(16, 32))\n    plt.subplot(3, 1, 1)\n    plt.imshow(image)\n    plt.title('Input image')\n    plt.axis(\"off\")\n    plt.subplot(3, 1, 2)\n    plt.imshow(image)\n    plt.imshow(mask, alpha=0.5)\n    plt.title('Input image with mask')\n    plt.axis(\"off\")\n    plt.subplot(3, 1, 3)\n    plt.imshow(mask)\n    plt.title('Only mask')\n    plt.axis(\"off\")\n    \n    plt.show();","metadata":{"execution":{"iopub.status.busy":"2021-10-21T06:35:14.459458Z","iopub.execute_input":"2021-10-21T06:35:14.459987Z","iopub.status.idle":"2021-10-21T06:35:14.473718Z","shell.execute_reply.started":"2021-10-21T06:35:14.459949Z","shell.execute_reply":"2021-10-21T06:35:14.473016Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Train Data**","metadata":{}},{"cell_type":"code","source":"IMG_HEIGHT = 256\nIMG_WIDTH = 256\nIMG_CHANNELS = 1\n\nTRAIN_PATH = '../input/sartorius-cell-instance-segmentation/train/'\ntest_ids = sample_submission['id'].unique().tolist()\n\n# Get and resize test images\nX_test = np.zeros((sample_submission['id'].nunique(), IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), dtype=np.uint8)\nprint('Getting and resizing test images ... ')\n\nfor n, id_ in tqdm(enumerate(test_ids), total=len(test_ids)):\n    path = TRAIN_PATH.replace('train', 'test') + id_\n    img = imread(path + '.png')[:,:]\n    img = resize(img, (IMG_HEIGHT, IMG_WIDTH), mode='constant', preserve_range=True)\n    img = np.expand_dims(img, axis = 2)\n    X_test[n] = img\n\nprint('Done!')","metadata":{"execution":{"iopub.status.busy":"2021-10-21T06:35:14.475781Z","iopub.execute_input":"2021-10-21T06:35:14.476899Z","iopub.status.idle":"2021-10-21T06:35:14.566364Z","shell.execute_reply.started":"2021-10-21T06:35:14.47683Z","shell.execute_reply":"2021-10-21T06:35:14.565656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### Finding Co-efficient","metadata":{}},{"cell_type":"code","source":"def dice_coefficient(y_true, y_pred):\n    numerator = 2 * tf.reduce_sum(y_true * y_pred)\n    denominator = tf.reduce_sum(y_true + y_pred)\n    return numerator / (denominator + tf.keras.backend.epsilon())","metadata":{"execution":{"iopub.status.busy":"2021-10-21T06:35:14.568583Z","iopub.execute_input":"2021-10-21T06:35:14.569085Z","iopub.status.idle":"2021-10-21T06:35:14.574738Z","shell.execute_reply.started":"2021-10-21T06:35:14.569046Z","shell.execute_reply":"2021-10-21T06:35:14.573712Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Predict from Train and Test data**","metadata":{}},{"cell_type":"code","source":"# Predict on train, val and test\nmodel = load_model('../input/cell-instance-segmentation-model/best_model.h5', custom_objects={'dice_coefficient': dice_coefficient})\npreds_test = model.predict(X_test, verbose=1)\n\n# Threshold predictions\npreds_test_t = (preds_test > 0.5).astype(np.uint8)\n\n# Create list of upsampled test masks\npreds_test_upsampled = []\nfor i in range(len(preds_test)):\n    preds_test_upsampled.append(resize(np.squeeze(preds_test[i]), \n                                       (IMG_HEIGHT, IMG_WIDTH), \n                                       mode='constant', preserve_range=True))","metadata":{"execution":{"iopub.status.busy":"2021-10-21T06:35:14.576369Z","iopub.execute_input":"2021-10-21T06:35:14.577214Z","iopub.status.idle":"2021-10-21T06:35:14.622646Z","shell.execute_reply.started":"2021-10-21T06:35:14.577172Z","shell.execute_reply":"2021-10-21T06:35:14.621603Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Run-length encoding stolen from https://www.kaggle.com/rakhlin/fast-run-length-encoding-python**","metadata":{}},{"cell_type":"code","source":"# Run-length encoding stolen from https://www.kaggle.com/rakhlin/fast-run-length-encoding-python\n    \ndef rle_encoding(x):\n    dots = np.where(x.flatten() == 1)[0]\n    run_lengths = []\n    prev = -2\n    for b in dots:\n        if (b>prev+1): run_lengths.extend((b + 1, 0))\n        run_lengths[-1] += 1\n        prev = b\n    return run_lengths\n\ndef prob_to_rles(x, cutoff=0.5):\n    lab_img = (x > cutoff).astype(int)\n    for i in range(1, lab_img.max() + 1):\n        yield rle_encoding(lab_img == i)","metadata":{"execution":{"iopub.status.busy":"2021-10-21T06:35:14.624018Z","iopub.status.idle":"2021-10-21T06:35:14.624682Z","shell.execute_reply.started":"2021-10-21T06:35:14.62442Z","shell.execute_reply":"2021-10-21T06:35:14.624446Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def post_process(probability, threshold=0.5, min_size=300):\n    mask = cv2.threshold(probability, threshold, 1, cv2.THRESH_BINARY)[1]\n    num_component, component = cv2.connectedComponents(mask.astype(np.uint8))\n    predictions = []\n    for c in range(1, num_component):\n        p = (component == c)\n        if p.sum() > min_size:\n            a_prediction = np.zeros((520, 704), np.float32)\n            a_prediction[p] = 1\n            predictions.append(a_prediction)\n    return predictions","metadata":{"execution":{"iopub.status.busy":"2021-10-21T06:35:14.626002Z","iopub.status.idle":"2021-10-21T06:35:14.626721Z","shell.execute_reply.started":"2021-10-21T06:35:14.626442Z","shell.execute_reply":"2021-10-21T06:35:14.626469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Submission File**","metadata":{}},{"cell_type":"code","source":"output_df = pd.DataFrame(data = None, columns = sample_submission.columns)\ncount = 0\n\nfor n, id_ in enumerate(test_ids):\n    probability_mask = cv2.resize(preds_test_upsampled[n], dsize=(704, 520), interpolation=cv2.INTER_LINEAR)\n    predictions = post_process(probability_mask)\n    rle = [list(prob_to_rles(predictions[i]))[0] for i in range(0, len(predictions))]\n    for i in range(0, len(rle)):\n        cell_annotations = ' '.join([str(x) for x in rle[i]])\n        output_df.loc[count] = id_,cell_annotations\n        count +=1\n        \noutput_df.to_csv('submission.csv', index = False)","metadata":{"execution":{"iopub.status.busy":"2021-10-21T06:35:14.628029Z","iopub.status.idle":"2021-10-21T06:35:14.628732Z","shell.execute_reply.started":"2021-10-21T06:35:14.628459Z","shell.execute_reply":"2021-10-21T06:35:14.628486Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"output_df","metadata":{"execution":{"iopub.status.busy":"2021-10-21T06:35:14.63008Z","iopub.status.idle":"2021-10-21T06:35:14.630784Z","shell.execute_reply.started":"2021-10-21T06:35:14.630476Z","shell.execute_reply":"2021-10-21T06:35:14.630506Z"},"trusted":true},"execution_count":null,"outputs":[]}]}