{"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":"# **Ink Distributions**\n\nIn this notebook we will inspect the distributions of ink VS non-ink across all surface volumes","metadata":{}},{"cell_type":"code","source":"import os\nimport gc\nimport time\nimport shutil\nfrom tqdm import tqdm\n\nimport random\nimport numpy as np\nimport cv2\nfrom tifffile import tifffile\nimport PIL.Image as Image\n\n\nimport matplotlib.pyplot as plt\nfrom ipywidgets import interact, fixed\nfrom IPython.display import HTML, display","metadata":{"execution":{"iopub.status.busy":"2023-04-24T01:19:55.728543Z","iopub.execute_input":"2023-04-24T01:19:55.728947Z","iopub.status.idle":"2023-04-24T01:19:56.177480Z","shell.execute_reply.started":"2023-04-24T01:19:55.728913Z","shell.execute_reply":"2023-04-24T01:19:56.176134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install zarr","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import zarr","metadata":{"execution":{"iopub.status.busy":"2023-04-24T01:20:13.020126Z","iopub.execute_input":"2023-04-24T01:20:13.020523Z","iopub.status.idle":"2023-04-24T01:20:13.162457Z","shell.execute_reply.started":"2023-04-24T01:20:13.020480Z","shell.execute_reply":"2023-04-24T01:20:13.161150Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\nsys.path.insert(1, r\"/kaggle/input/fragments\")\n\nfrom fragment_loader import FragmentImageData","metadata":{"execution":{"iopub.status.busy":"2023-04-24T01:20:13.164853Z","iopub.execute_input":"2023-04-24T01:20:13.165258Z","iopub.status.idle":"2023-04-24T01:20:13.174155Z","shell.execute_reply.started":"2023-04-24T01:20:13.165212Z","shell.execute_reply":"2023-04-24T01:20:13.172690Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Config","metadata":{}},{"cell_type":"code","source":"INPUT_FOLDER = \"/kaggle/input/vesuvius-challenge-ink-detection\"\nWORKING_FOLDER = \"/kaggle/working/\"\nTEMP_FOLDER = \"kaggle/temp/\"\n\nFRAGMENT = \"1\"","metadata":{"execution":{"iopub.status.busy":"2023-04-24T01:20:13.175601Z","iopub.execute_input":"2023-04-24T01:20:13.176569Z","iopub.status.idle":"2023-04-24T01:20:13.184981Z","shell.execute_reply.started":"2023-04-24T01:20:13.176514Z","shell.execute_reply":"2023-04-24T01:20:13.183637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Get Data\n\nLoad entire surface volumes","metadata":{}},{"cell_type":"code","source":"tic = time.time()\n# FRAGMENTS = {\n#     '1' : FragmentImageData(INPUT_FOLDER, WORKING_FOLDER, \"train\", \"1\", None),\n#     '2' : FragmentImageData(INPUT_FOLDER, WORKING_FOLDER, \"train\", \"2\", None),\n#     '3' : FragmentImageData(INPUT_FOLDER, WORKING_FOLDER, \"train\", \"3\", None)\n# }\n\ndata = FragmentImageData(INPUT_FOLDER, WORKING_FOLDER, \"train\", FRAGMENT, None)\n\nprint(\"Elapsed: \", time.time() - tic)","metadata":{"execution":{"iopub.status.busy":"2023-04-24T01:20:13.186796Z","iopub.execute_input":"2023-04-24T01:20:13.187225Z","iopub.status.idle":"2023-04-24T01:22:14.103208Z","shell.execute_reply.started":"2023-04-24T01:20:13.187187Z","shell.execute_reply":"2023-04-24T01:22:14.102176Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ink_mask = np.logical_and(data.mask, data.truth)\nbackground_mask = np.logical_and(data.mask, ~np.asarray(data.truth))","metadata":{"execution":{"iopub.status.busy":"2023-04-24T01:22:14.105559Z","iopub.execute_input":"2023-04-24T01:22:14.106319Z","iopub.status.idle":"2023-04-24T01:22:14.339066Z","shell.execute_reply.started":"2023-04-24T01:22:14.106278Z","shell.execute_reply":"2023-04-24T01:22:14.337867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(1, 3, figsize=(10, 15))\nax[0].imshow(data.surface_volume[:, :, 10])\nax[0].set_title(\"Surface Volume\")\nax[1].imshow(ink_mask)\nax[1].set_title(\"Ink Mask\")\nax[2].imshow(background_mask)\nax[2].set_title(\"Background Mask\")","metadata":{"execution":{"iopub.status.busy":"2023-04-24T01:22:14.340342Z","iopub.execute_input":"2023-04-24T01:22:14.340689Z","iopub.status.idle":"2023-04-24T01:22:21.830082Z","shell.execute_reply.started":"2023-04-24T01:22:14.340653Z","shell.execute_reply":"2023-04-24T01:22:21.828790Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Inspect Surface Volume Histograms\n\nref for animation code: https://www.kaggle.com/code/leonidkulyk/eda-vc-id-volume-layers-animation","metadata":{}},{"cell_type":"code","source":"!pip install celluloid -q","metadata":{"execution":{"iopub.status.busy":"2023-04-24T01:22:21.832081Z","iopub.execute_input":"2023-04-24T01:22:21.832915Z","iopub.status.idle":"2023-04-24T01:22:35.208412Z","shell.execute_reply.started":"2023-04-24T01:22:21.832859Z","shell.execute_reply":"2023-04-24T01:22:35.206854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from celluloid import Camera","metadata":{"execution":{"iopub.status.busy":"2023-04-24T01:22:35.211007Z","iopub.execute_input":"2023-04-24T01:22:35.211938Z","iopub.status.idle":"2023-04-24T01:22:35.230382Z","shell.execute_reply.started":"2023-04-24T01:22:35.211870Z","shell.execute_reply":"2023-04-24T01:22:35.228998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax  = plt.subplots(1, 2, figsize=(15, 5))\n\ncamera = Camera(fig) # define the camera that gets the fig we'll plot\nfor i in range(data.surface_volume.shape[2]):\n    \n    ink = data.surface_volume[:, :, i][ink_mask]\n    bckgnd = data.surface_volume[:, :, i][background_mask]\n\n    fig.text(\n            1.0, 1.08, f\"Surfacer Layer: {i}\", fontweight='bold', fontsize=18,\n            transform=ax[0].transAxes, horizontalalignment='center'\n        )\n\n    ax[0].hist(np.ravel(ink)/65535.0, bins=150)\n    ax[0].set_xlabel(\"Ink Mask\")\n    ax[1].hist(np.ravel(bckgnd)/65535.0, bins=150)\n    ax[1].set_xlabel(\"Background Mask\")\n    \n    camera.snap() # the camera takes a snapshot of the plot\n    \n    \nplt.close(fig) # close figure\n\nanimation = camera.animate() # get plt animation\n\nfix_video_adjust = '<style> video {margin: 0px; padding: 0px; width:100%; height:auto;} </style>'\ndisplay(\n    HTML(fix_video_adjust + animation.to_html5_video())\n) # displaying the animation","metadata":{"execution":{"iopub.status.busy":"2023-04-24T01:22:35.232501Z","iopub.execute_input":"2023-04-24T01:22:35.233370Z","iopub.status.idle":"2023-04-24T01:24:46.159775Z","shell.execute_reply.started":"2023-04-24T01:22:35.233323Z","shell.execute_reply":"2023-04-24T01:24:46.158250Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Again with modified ink masks","metadata":{}},{"cell_type":"code","source":"# make a copy of the truth\ntruth = np.array(data.truth).astype(np.uint8)\n\n# apply morphological opening\nkernel = np.ones((35,35),np.uint8)\ntruth_open = cv2.morphologyEx(truth, cv2.MORPH_OPEN, kernel, iterations=1)\ntruth_open_close = cv2.morphologyEx(truth_open, cv2.MORPH_CLOSE, kernel, iterations=1)","metadata":{"execution":{"iopub.status.busy":"2023-04-24T01:45:12.524685Z","iopub.execute_input":"2023-04-24T01:45:12.525141Z","iopub.status.idle":"2023-04-24T01:45:12.904247Z","shell.execute_reply.started":"2023-04-24T01:45:12.525076Z","shell.execute_reply":"2023-04-24T01:45:12.902908Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"_, ax = plt.subplots(1, 2, figsize=(20, 15))\nax[0].imshow(truth)\nax[0].set_title(\"Original Truth\")\nax[1].imshow(truth_open_close)\nax[1].set_title(\"Opened and Closed Truth\")","metadata":{"execution":{"iopub.status.busy":"2023-04-24T01:45:12.906183Z","iopub.execute_input":"2023-04-24T01:45:12.906524Z","iopub.status.idle":"2023-04-24T01:45:24.079282Z","shell.execute_reply.started":"2023-04-24T01:45:12.906492Z","shell.execute_reply":"2023-04-24T01:45:24.078147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cv2.imwrite(os.path.join(WORKING_FOLDER, \"truth_open_close.png\"), truth_open_close)","metadata":{"execution":{"iopub.status.busy":"2023-04-24T01:45:52.620216Z","iopub.execute_input":"2023-04-24T01:45:52.621256Z","iopub.status.idle":"2023-04-24T01:45:52.841075Z","shell.execute_reply.started":"2023-04-24T01:45:52.621210Z","shell.execute_reply":"2023-04-24T01:45:52.839951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now we also want to reduce the mask so we don't include ink along the edges of the papyrus. To do this we can just perform an eroding operation.","metadata":{}},{"cell_type":"code","source":"eroded_mask = cv2.erode(np.array(data.mask).astype(np.uint8), \n                        kernel, \n                        iterations=10).astype(bool)\nplt.imshow(eroded_mask)","metadata":{"execution":{"iopub.status.busy":"2023-04-24T02:06:19.331617Z","iopub.execute_input":"2023-04-24T02:06:19.332525Z","iopub.status.idle":"2023-04-24T02:06:22.577653Z","shell.execute_reply.started":"2023-04-24T02:06:19.332479Z","shell.execute_reply":"2023-04-24T02:06:22.576302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"truth_mask_2 = truth_open_close.astype(bool)\nink_mask_2 = np.logical_and(eroded_mask, truth_mask_2)\nbackground_mask_2 = np.logical_and(eroded_mask, ~truth_mask_2)","metadata":{"execution":{"iopub.status.busy":"2023-04-24T02:06:30.071075Z","iopub.execute_input":"2023-04-24T02:06:30.071737Z","iopub.status.idle":"2023-04-24T02:06:30.178015Z","shell.execute_reply.started":"2023-04-24T02:06:30.071670Z","shell.execute_reply":"2023-04-24T02:06:30.176738Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(1, 3, figsize=(10, 15))\nax[0].imshow(data.surface_volume[:, :, 10])\nax[0].set_title(\"Surface Volume\")\nax[1].imshow(ink_mask_2)\nax[1].set_title(\"Ink Mask Open Close\")\nax[2].imshow(background_mask_2)\nax[2].set_title(\"Background Open Close\");","metadata":{"execution":{"iopub.status.busy":"2023-04-24T02:18:43.518164Z","iopub.execute_input":"2023-04-24T02:18:43.519546Z","iopub.status.idle":"2023-04-24T02:18:52.285463Z","shell.execute_reply.started":"2023-04-24T02:18:43.519490Z","shell.execute_reply":"2023-04-24T02:18:52.283883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax  = plt.subplots(1, 2, figsize=(15, 5))\n\ncamera = Camera(fig) # define the camera that gets the fig we'll plot\n\nfor i in range(data.surface_volume.shape[2]):\n    \n    ink = data.surface_volume[:, :, i][ink_mask_2]\n    bckgnd = data.surface_volume[:, :, i][background_mask_2]\n\n    fig.text(\n            1.0, 1.08, f\"Surfacer Layer: {i}\", fontweight='bold', fontsize=18,\n            transform=ax[0].transAxes, horizontalalignment='center'\n        )\n\n    ax[0].hist(np.ravel(ink)/65535.0, bins=150)\n    ax[0].set_xlabel(\"Ink Mask\")\n    ax[1].hist(np.ravel(bckgnd)/65535.0, bins=150)\n    ax[1].set_xlabel(\"Background Mask\")\n    \n    camera.snap() # the camera takes a snapshot of the plot\n    \n    \nplt.close(fig) # close figure\n\nanimation = camera.animate() # get plt animation\n\nfix_video_adjust = '<style> video {margin: 0px; padding: 0px; width:100%; height:auto;} </style>'\ndisplay(\n    HTML(fix_video_adjust + animation.to_html5_video())\n) # displaying the animation","metadata":{"execution":{"iopub.status.busy":"2023-04-24T02:06:36.771953Z","iopub.execute_input":"2023-04-24T02:06:36.772854Z","iopub.status.idle":"2023-04-24T02:08:48.492754Z","shell.execute_reply.started":"2023-04-24T02:06:36.772803Z","shell.execute_reply":"2023-04-24T02:08:48.491397Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Morphological operations on the letters alone, see, to have no impact. However, reducing the size of the papyrus actually seems to remove the mode around 0.3 in the background.","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}