{"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":"# This notebook hypothesizes that broken masks found in the dataset are caused by incorrect polygon->bitmask conversion\n\nThis was originally found by @bakeryproducts \nI hadn't seen his notebook before it was removed, but I imagine it went something like this","metadata":{}},{"cell_type":"code","source":"import cv2\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-11-20T20:04:43.535473Z","iopub.execute_input":"2021-11-20T20:04:43.535754Z","iopub.status.idle":"2021-11-20T20:04:43.540236Z","shell.execute_reply.started":"2021-11-20T20:04:43.535726Z","shell.execute_reply":"2021-11-20T20:04:43.539306Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Here is a sample cell","metadata":{}},{"cell_type":"code","source":"img = cv2.imread('../input/sartorius-cell-instance-segmentation/train/13325f865bb0.png')\n_=plt.imshow(img[50:150, 160:310])\n","metadata":{"execution":{"iopub.status.busy":"2021-11-20T19:59:22.60508Z","iopub.execute_input":"2021-11-20T19:59:22.605586Z","iopub.status.idle":"2021-11-20T19:59:22.795893Z","shell.execute_reply.started":"2021-11-20T19:59:22.605539Z","shell.execute_reply":"2021-11-20T19:59:22.795067Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Here is a hypotetical polygon annotation of that cell","metadata":{}},{"cell_type":"code","source":"mask = np.load('../input/sample-mask/mask.npy')\ncont, hier = cv2.findContours(mask,cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)\n_=plt.imshow(cv2.drawContours(np.zeros_like(mask), cont, -1, 1, 1))","metadata":{"execution":{"iopub.status.busy":"2021-11-20T20:22:19.390128Z","iopub.execute_input":"2021-11-20T20:22:19.390816Z","iopub.status.idle":"2021-11-20T20:22:19.588713Z","shell.execute_reply.started":"2021-11-20T20:22:19.390765Z","shell.execute_reply":"2021-11-20T20:22:19.587879Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Here is the polygon above converted to bitmask with `cv2.fillConvexPoly` - leading to a clearly broken mask","metadata":{}},{"cell_type":"code","source":"convex_mask = cv2.fillConvexPoly(np.zeros_like(mask),points=cont[0], color=1)\n_=plt.imshow(convex_mask)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-11-20T20:31:04.61287Z","iopub.execute_input":"2021-11-20T20:31:04.613184Z","iopub.status.idle":"2021-11-20T20:31:04.846276Z","shell.execute_reply.started":"2021-11-20T20:31:04.613153Z","shell.execute_reply":"2021-11-20T20:31:04.84538Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle_decode(mask_rle, shape):\n    s = mask_rle.split()    \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    img = np.zeros((shape[0] * shape[1]), dtype=np.uint8)\n    for start, end in zip(starts, ends):\n        img[start : end] = 1\n    return img.reshape(shape)","metadata":{"execution":{"iopub.status.busy":"2021-11-20T20:20:39.569554Z","iopub.execute_input":"2021-11-20T20:20:39.570195Z","iopub.status.idle":"2021-11-20T20:20:39.576804Z","shell.execute_reply.started":"2021-11-20T20:20:39.570146Z","shell.execute_reply":"2021-11-20T20:20:39.575789Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## And here is the actual mask found in the competition training data","metadata":{}},{"cell_type":"code","source":"df_train = pd.read_csv('../input/sartorius-cell-instance-segmentation/train.csv')\nlabel = df_train.iloc[4899][\"annotation\"]\nmask = rle_decode(label, shape=(520, 704))\n_=plt.imshow(mask[50:150, 160:310])","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-11-20T20:31:57.482152Z","iopub.execute_input":"2021-11-20T20:31:57.482462Z","iopub.status.idle":"2021-11-20T20:31:58.143537Z","shell.execute_reply.started":"2021-11-20T20:31:57.482422Z","shell.execute_reply":"2021-11-20T20:31:58.142734Z"},"trusted":true},"execution_count":null,"outputs":[]}]}