{"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🦠 - Run Length Decoding\n\n\n#### Run Length Decoding (RLD) algorithm for [Sartorius - Cell Instance Segmentation](https://www.kaggle.com/c/sartorius-cell-instance-segmentation) challenge.","metadata":{"execution":{"iopub.status.busy":"2021-10-14T21:11:17.216516Z","iopub.execute_input":"2021-10-14T21:11:17.217509Z","iopub.status.idle":"2021-10-14T21:11:17.221472Z","shell.execute_reply.started":"2021-10-14T21:11:17.217471Z","shell.execute_reply":"2021-10-14T21:11:17.220556Z"}}},{"cell_type":"markdown","source":"![](https://storage.googleapis.com/kaggle-competitions/kaggle/30201/logos/header.png)","metadata":{}},{"cell_type":"markdown","source":"## How does the RLD algorithm work?\n\nAs you can see from the picture below, we are:\n1. Сonverting an empty mask into a long vector. \n2. On this vector, we mark the desired coordinates (in the annotation we are given the beginning of the mask fragment and the length of the fragment). \n3. Convert the vector back to a mask.","metadata":{}},{"cell_type":"markdown","source":"![](https://i.imgur.com/3FEZqQ0.png)","metadata":{}},{"cell_type":"code","source":"import os\n\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2021-10-16T22:32:34.676956Z","iopub.execute_input":"2021-10-16T22:32:34.677316Z","iopub.status.idle":"2021-10-16T22:32:34.904589Z","shell.execute_reply.started":"2021-10-16T22:32:34.677221Z","shell.execute_reply":"2021-10-16T22:32:34.903743Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv(\"../input/sartorius-cell-instance-segmentation/train.csv\")\ndf_train","metadata":{"execution":{"iopub.status.busy":"2021-10-16T22:32:34.905927Z","iopub.execute_input":"2021-10-16T22:32:34.906134Z","iopub.status.idle":"2021-10-16T22:32:35.522132Z","shell.execute_reply.started":"2021-10-16T22:32:34.906109Z","shell.execute_reply":"2021-10-16T22:32:35.521286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ref: https://www.kaggle.com/inversion/run-length-decoding-quick-start\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)","metadata":{"execution":{"iopub.status.busy":"2021-10-16T22:32:35.523499Z","iopub.execute_input":"2021-10-16T22:32:35.523735Z","iopub.status.idle":"2021-10-16T22:32:35.531092Z","shell.execute_reply.started":"2021-10-16T22:32:35.523708Z","shell.execute_reply":"2021-10-16T22:32:35.529939Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_masks(image_id, colors=True):\n    labels = df_train[df_train[\"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.axis(\"off\")\n    plt.subplot(3, 1, 2)\n    plt.imshow(image)\n    plt.imshow(mask, alpha=0.5)\n    plt.axis(\"off\")\n    plt.subplot(3, 1, 3)\n    plt.imshow(mask)\n    plt.axis(\"off\")\n    \n    plt.show();","metadata":{"execution":{"iopub.status.busy":"2021-10-16T22:32:35.532315Z","iopub.execute_input":"2021-10-16T22:32:35.532566Z","iopub.status.idle":"2021-10-16T22:32:35.542715Z","shell.execute_reply.started":"2021-10-16T22:32:35.532539Z","shell.execute_reply":"2021-10-16T22:32:35.541909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_masks(\"ffdb3cc02eef\", colors=False)","metadata":{"execution":{"iopub.status.busy":"2021-10-16T22:32:35.544514Z","iopub.execute_input":"2021-10-16T22:32:35.544779Z","iopub.status.idle":"2021-10-16T22:32:36.649921Z","shell.execute_reply.started":"2021-10-16T22:32:35.544749Z","shell.execute_reply":"2021-10-16T22:32:36.648825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_masks(\"ffdb3cc02eef\", colors=True)","metadata":{"execution":{"iopub.status.busy":"2021-10-16T22:32:36.650948Z","iopub.execute_input":"2021-10-16T22:32:36.651237Z","iopub.status.idle":"2021-10-16T22:32:37.803905Z","shell.execute_reply.started":"2021-10-16T22:32:36.651211Z","shell.execute_reply":"2021-10-16T22:32:37.803089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_masks(\"73df2962444f\", colors=True)","metadata":{"execution":{"iopub.status.busy":"2021-10-16T22:32:37.805073Z","iopub.execute_input":"2021-10-16T22:32:37.805845Z","iopub.status.idle":"2021-10-16T22:32:39.409715Z","shell.execute_reply.started":"2021-10-16T22:32:37.805812Z","shell.execute_reply":"2021-10-16T22:32:39.408654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_masks(\"13325f865bb0\", colors=True)","metadata":{"execution":{"iopub.status.busy":"2021-10-16T22:32:39.410993Z","iopub.execute_input":"2021-10-16T22:32:39.411254Z","iopub.status.idle":"2021-10-16T22:32:40.550019Z","shell.execute_reply.started":"2021-10-16T22:32:39.411200Z","shell.execute_reply":"2021-10-16T22:32:40.549271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_masks(\"08f52aa2add3\", colors=True)","metadata":{"execution":{"iopub.status.busy":"2021-10-16T22:36:17.941134Z","iopub.execute_input":"2021-10-16T22:36:17.941584Z","iopub.status.idle":"2021-10-16T22:36:18.880894Z","shell.execute_reply.started":"2021-10-16T22:36:17.941542Z","shell.execute_reply":"2021-10-16T22:36:18.880287Z"},"trusted":true},"execution_count":null,"outputs":[]}]}