{"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":"# Remove Overlap\n* It will take max pixels from overlapping mask instances hence there will be less chance of pixel loss\n* You can try it with as many as possible mask instances. \n* You can also run it with **GPU** with `cupy`\n\n## Notebook\n* Train: [Sartorius: MMDetection [Train]](https://www.kaggle.com/awsaf49/sartorius-mmdetection-train)\n* Infer: [Sartorius: MMDetection [Infer]](https://www.kaggle.com/awsaf49/sartorius-mmdetection-infer) `LB: 0.265`\n\n\nPlease **do upvote** if you find this useful.","metadata":{}},{"cell_type":"markdown","source":"# Install Libraries","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport tensorflow as tf\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2021-10-21T06:17:29.286156Z","iopub.execute_input":"2021-10-21T06:17:29.286648Z","iopub.status.idle":"2021-10-21T06:17:34.890553Z","shell.execute_reply.started":"2021-10-21T06:17:29.286493Z","shell.execute_reply":"2021-10-21T06:17:34.889853Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Helper Function","metadata":{}},{"cell_type":"code","source":"def check_overlap(msk):\n    msk = msk.astype(np.bool).astype(np.uint8)\n    return np.any(np.sum(msk, axis=-1)>1)\n\ndef fix_overlap(msk):\n    \"\"\"\n    Args:\n        mask: multi-channel mask, each channel is an instance of cell, shape:(520,704,None)\n    Returns:\n        multi-channel mask with non-overlapping values, shape:(520,704,None)\n    \"\"\"\n    msk = np.array(msk)\n    msk = np.pad(msk, [[0,0],[0,0],[1,0]])\n    ins_len = msk.shape[-1]\n    msk = np.argmax(msk,axis=-1)\n    msk = tf.keras.utils.to_categorical(msk, num_classes=ins_len)\n    msk = msk[...,1:]\n    msk = msk[...,np.any(msk, axis=(0,1))]\n    return msk","metadata":{"execution":{"iopub.status.busy":"2021-10-21T06:17:34.892305Z","iopub.execute_input":"2021-10-21T06:17:34.892836Z","iopub.status.idle":"2021-10-21T06:17:34.903798Z","shell.execute_reply.started":"2021-10-21T06:17:34.892788Z","shell.execute_reply":"2021-10-21T06:17:34.902782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Example","metadata":{}},{"cell_type":"code","source":"mask = np.zeros((520, 704, 5))\n\n# Before Fix\nplt.figure(figsize=(5*5, 5))\nfor idx in range(5):\n    mask[idx*50+50:(idx*50+200), idx*50+50:(idx*50+200), idx] = idx+1 # probabilistic mask isntead of binary mask\n    plt.subplot(1, 5, idx+1)\n    plt.imshow(mask[...,idx]);\n    plt.axis('OFF')\n    plt.title(f'instance: {idx}', fontsize=15)\nplt.tight_layout()\nplt.show()\n\n## After Fix\nplt.figure(figsize=(5*5, 5))\nfixed_mask = fix_overlap(mask)\nfor idx in range(5):\n    plt.subplot(1, 5, idx+1)\n    plt.imshow(fixed_mask[...,idx]);\n    plt.axis('OFF')\n    plt.title(f'instance: {idx}', fontsize=15)\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-10-21T06:19:22.190695Z","iopub.execute_input":"2021-10-21T06:19:22.191040Z","iopub.status.idle":"2021-10-21T06:19:23.327641Z","shell.execute_reply.started":"2021-10-21T06:19:22.191006Z","shell.execute_reply":"2021-10-21T06:19:23.326723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Fix Mask","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(2*10, 10))\noverlap_mask = np.sum(mask, axis=-1)\nplt.subplot(1, 2, 1); \nplt.imshow(overlap_mask); plt.title('Overlapping Mask', fontsize=20); plt.axis('OFF')\n\nplt.subplot(1, 2, 2); \nfixed_mask = fix_overlap(mask)\nfixed_mask = np.pad(fixed_mask, [[0,0],[0,0],[1,0]]) # to plot first channel, otherwise it'll mix with background(0)\nfixed_mask = np.argmax(fixed_mask, axis=-1)[...,1:]\nplt.imshow(fixed_mask); plt.title('Fixed Mask', fontsize=20); plt.axis('OFF')\nplt.tight_layout()\nplt.savefig('remove-mask.png',dpi=600);\nplt.show();","metadata":{"execution":{"iopub.status.busy":"2021-10-21T06:17:35.596671Z","iopub.execute_input":"2021-10-21T06:17:35.597017Z","iopub.status.idle":"2021-10-21T06:17:44.214306Z","shell.execute_reply.started":"2021-10-21T06:17:35.596986Z","shell.execute_reply":"2021-10-21T06:17:44.213328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Check Overlap","metadata":{}},{"cell_type":"code","source":"print(f'Mask       - Overlap: {check_overlap(mask)}')\nprint(f'Fixed_Mask - Overlap: {check_overlap(fix_overlap(mask))}')","metadata":{"execution":{"iopub.status.busy":"2021-10-20T11:41:04.778431Z","iopub.execute_input":"2021-10-20T11:41:04.779435Z","iopub.status.idle":"2021-10-20T11:41:04.829058Z","shell.execute_reply.started":"2021-10-20T11:41:04.779382Z","shell.execute_reply":"2021-10-20T11:41:04.828104Z"},"trusted":true},"execution_count":null,"outputs":[]}]}