{"cells":[{"metadata":{"_uuid":"442a47b67ca5cab74d68ad480bdb5bb2c1f530f0","_cell_guid":"f76ab20d-7828-43de-8d8d-45ad86c48695"},"cell_type":"markdown","source":"For everybody's convenient, I converted the annotated nuclei from https://nucleisegmentationbenchmark.weebly.com/ into a public dataset following the folder structure of the competition data. I hope that you find it usefull.. "},{"metadata":{"collapsed":true,"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport cv2\nimport os\nfrom matplotlib import pyplot as plt\nTRAIN_PATH = '../input/bowl2018-external/extra_data/extra_data/'\ntrain_ids = [x for x in os.listdir(TRAIN_PATH) if os.path.isdir(TRAIN_PATH+x)]","execution_count":1,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true,"collapsed":true},"cell_type":"code","source":"df = pd.DataFrame({'id':train_ids,'train_or_test':'train'})\ndf['path'] = df.apply(lambda x:TRAIN_PATH +'/{}/images/{}.tif'.format(x[0],x[0]), axis=1)\ndf['masks'] = df.apply(lambda x:TRAIN_PATH +'/{}/masks/'.format(x[0],x[0]), axis=1)\ndf.head()","execution_count":10,"outputs":[]},{"metadata":{"_uuid":"cd3029a2160f4505ab8184533eeaa493bb915bc5","_cell_guid":"09ebeb56-ab6a-4d10-97b4-419874c2d085"},"cell_type":"markdown","source":"There are 29 Images are annotated by the following ids:"},{"metadata":{"_uuid":"c7365690b0f99c0175bc9bcd1ac150a5a217edfa","_cell_guid":"77efbf26-0f82-45e7-a7a8-606df686238c","trusted":true,"collapsed":true},"cell_type":"code","source":"df['id']","execution_count":11,"outputs":[]},{"metadata":{"_uuid":"9e937b6824b663cb20575d7e847105fd1170493b","_cell_guid":"1b77eb7a-5ffc-4fa1-8acc-5415f787babf"},"cell_type":"markdown","source":"Let us load one image and its masks:"},{"metadata":{"_uuid":"adbac1456a92c82ee8bddfd1ac160359670ed0ee","_cell_guid":"7b1ef9c2-99fc-49e3-bf53-8b6e94b1a903","trusted":true,"collapsed":true},"cell_type":"code","source":"imid = 'TCGA-G9-6362-01Z-00-DX1'\nimage_path = df[df.id==imid].path.values[0]\nimage = cv2.imread(image_path)\nimage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\nplt.figure(figsize=(6, 6))\nplt.imshow(image)\nplt.show()","execution_count":12,"outputs":[]},{"metadata":{"_uuid":"702c744c2722a25f823f71f85cea25d857338f48","_cell_guid":"7632336d-d178-427f-bef5-48e82dfd6608"},"cell_type":"markdown","source":"Now we can read  the masks for the specific image. We have stored them as png files`. "},{"metadata":{"_uuid":"7df7137a052ae24e7edaacccf33b52ddb9ff4a06","_cell_guid":"acd7eda6-4fe6-4303-adce-ea1be8fe352b","trusted":true,"collapsed":true},"cell_type":"code","source":"mask_dir = df[df.id==imid].masks.values[0]\nmasks = os.listdir(mask_dir)\nmasks[:10]","execution_count":13,"outputs":[]},{"metadata":{"_uuid":"e53c5f7c207f59a00ccae99601e6892d48b90133","_cell_guid":"e9a1891a-96a9-49a0-b243-6d41dbae444b","trusted":true,"collapsed":true},"cell_type":"code","source":"mimgs = []\ni = 0\nfor mask in masks:\n    mimg = cv2.imread(mask_dir + '/' + mask)\n    mimg = cv2.cvtColor(mimg, cv2.COLOR_BGR2GRAY)\n    mimg[mimg==255] = 1\n    mimgs.append(mimg)\n    i = i + 1\nprint('Read ' + str(i) + ' masks for image ' + df[df.id==imid].id.values[0] )\nmimgs = np.array(mimgs)\nplt.figure(figsize=(8, 8))\ntotal_mask = np.sum(mimgs, axis=0)\nplt.imshow(total_mask)\nplt.show()","execution_count":14,"outputs":[]},{"metadata":{"_uuid":"cb23a42e5a37984c02f25e01cc1191b11333dc4f","_cell_guid":"465d4d9c-7cdf-4676-81df-dfe2b5a79740"},"cell_type":"markdown","source":"To make sure that masks are disconnected we can add them all into a single mask image using `np.sum` and whenever we find two or more pixels in common, assign them to background (0). In the example below we zoom into a 200x200 pixel window."},{"metadata":{"_uuid":"a1f027156385a81f30f732f140df9861060c84b4","_cell_guid":"6ba65855-99fd-4bc1-b3ec-9e020d9f572e","trusted":true,"collapsed":true},"cell_type":"code","source":"plt.figure(figsize=(8, 8))\ntotal_mask = np.sum(mimgs, axis=0)\nplt.title('Mask with overlapps: ' + str(np.max(total_mask)) + ' masks overlap' )\nplt.imshow(total_mask[400:600, 200:400])\nplt.show()\nplt.figure(figsize=(8, 8))\ntotal_mask[total_mask>1] = 0\nplt.title('Mask with NO overlapps:' + str(np.max(total_mask))  + ' masks overlap')\nplt.imshow(total_mask[400:600, 200:400])\nplt.show()","execution_count":15,"outputs":[]},{"metadata":{"collapsed":true,"_uuid":"5f3bc9856aa16bda5de5185a3c79562a01aef8cd","_cell_guid":"0775717c-db9c-4666-a259-bf7d7779b574"},"cell_type":"markdown","source":"For the same window we superimpose the masks above the image."},{"metadata":{"_uuid":"ff40bba2c2483bd19b398f4a0602e85910f0cd74","_cell_guid":"3589dd4b-34d4-44a4-89b6-7d6676311a79","trusted":true,"collapsed":true},"cell_type":"code","source":"img2 = cv2.bitwise_and(image[400:600, 200:400],image[400:600, 200:400],mask = total_mask[400:600, 200:400].astype(np.uint8))\nplt.figure(figsize=(8, 8))\ntotal_mask[total_mask>1] = 0\nplt.title('Masks over image')\nplt.imshow(img2)\nplt.show()","execution_count":16,"outputs":[]},{"metadata":{"collapsed":true,"_uuid":"146d84d5439d7140a73d964cc177859a9a1d538b","_cell_guid":"1e053114-8ecb-444f-83bb-bca497ec7350","trusted":false},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}