{"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":"# <center style=\"font-family: consolas; font-size: 32px; font-weight: bold;\"> 🌋 Vesuvius Challenge - 📜 Ink Detection - Exploratory Data Analysis</center>\n<p><center style=\"color:#949494; font-family: consolas; font-size: 20px;\">Resurrect an ancient library from the ashes of a volcano</center></p>\n\n***","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"markdown","source":"VERY WELL ARRRANGED NOTEBOOK ","metadata":{}},{"cell_type":"markdown","source":"# <center style=\"font-family: consolas; font-size: 32px; font-weight: bold;\">(ಠಿ⁠_⁠ಠ) Overview</center>\n\n<p style=\"font-family: consolas; font-size: 16px;\">⚪ The goal of this competition is to <b>detect ink from 3D X-ray scans of ancient scrolls</b> from a library buried by the eruption of Vesuvius nearly 2000 years ago. The scrolls were carbonized due to the heat of the volcano and are now <b>impossible to open without breaking them</b>.</p>\n\n<p style=\"font-family: consolas; font-size: 16px;\">⚪ The competition offers a <b>grand prize of 150,000 USD to the first team that can read these scrolls from a 3D X-ray scan</b>. The competition hosts the Ink Detection progress prize, which is about the sub-problem of detecting ink from 3D X-ray scans of fragments of papyrus that became detached from some of the excavated scrolls.</p>\n\n<p style=\"font-family: consolas; font-size: 16px;\">⚪ The ink used in the Herculaneum scrolls does not show up readily in X-ray scans, but machine learning models can detect it. The dataset contains 3D X-ray scans of four fragments at 4µm resolution, made using a particle accelerator, as well as infrared photographs of the surface of the fragments showing visible ink.</p>\n\n<p style=\"font-family: consolas; font-size: 16px;\">⚪ Hand-labeled binary masks indicating the presence of ink in the photographs are also provided.</p>","metadata":{}},{"cell_type":"markdown","source":"#### <a id=\"top\"></a>\n# <div style=\"box-shadow: rgb(60, 121, 245) 0px 0px 0px 3px inset, rgb(255, 255, 255) 10px -10px 0px -3px, rgb(31, 193, 27) 10px -10px, rgb(255, 255, 255) 20px -20px 0px -3px, rgb(255, 217, 19) 20px -20px, rgb(255, 255, 255) 30px -30px 0px -3px, rgb(255, 156, 85) 30px -30px, rgb(255, 255, 255) 40px -40px 0px -3px, rgb(255, 85, 85) 40px -40px; padding:20px; margin-right: 40px; font-size:30px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(60, 121, 245);\"><b>Table of contents</b></div>\n\n<div style=\"background-color: rgba(60, 121, 245, 0.03); padding:30px; font-size:15px; font-family: consolas;\">\n\n* [0. Import all dependencies](#0)\n* [1. Overview directories](#1)\n* [2. Overview the 1st volume of the train/ directory](#2)\n    * [2.1 Consider mask.png image](#2.1)\n    * [2.2 Consider ir.png image](#2.2)\n    * [2.3 Consider inklabels.png image](#2.3)\n    * [2.4 Consider inklabels_rle.csv file](#2.4)\n    * [2.5 Consider surface_volumes/ directory](#2.5)\n* [3. Overview the 2nd volume of the train/ directory](#3)\n    * [3.1 Consider mask.png image](#3.1)\n    * [3.2 Consider ir.png image](#3.2)\n    * [3.3 Consider inklabels.png image](#3.3)\n    * [3.4 Consider inklabels_rle.csv file](#3.4)\n    * [3.5 Consider surface_volumes/ directory](#3.5)\n* [4. Overview the 3rd volume of the train/ directory](#4)\n    * [4.1 Consider mask.png image](#4.1)\n    * [4.2 Consider ir.png image](#4.2)\n    * [3.3 Consider inklabels.png image](#4.3)\n    * [4.4 Consider inklabels_rle.csv file](#4.4)\n    * [4.5 Consider surface_volumes/ directory](#4.5)\n* [5. Overview volumes of the test/ directory](#5)\n    * [5.1 Consider mask.png images](#5.1)","metadata":{}},{"cell_type":"markdown","source":"<a id=\"0\"></a>\n# <div style=\"box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px inset, rgb(51, 51, 51) 0px 0px 0px 3px inset; padding:20px; font-size:32px; font-family: consolas; text-align:center; display:fill; border-radius:15px;  color:rgb(34, 34, 34);\"> <b> 0. Install & Import all dependencies </b></div>","metadata":{}},{"cell_type":"code","source":"!pip install celluloid -q","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:19:37.631324Z","iopub.execute_input":"2023-03-20T21:19:37.63175Z","iopub.status.idle":"2023-03-20T21:19:50.844748Z","shell.execute_reply.started":"2023-03-20T21:19:37.631712Z","shell.execute_reply":"2023-03-20T21:19:50.843353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport gc\nimport matplotlib.pyplot as plt\nfrom typing import Union, Optional\nfrom PIL import Image\nfrom IPython.display import HTML, display\n\nimport numpy as np\nimport pandas as pd\nimport plotly.express as px\nfrom tqdm import tqdm\nfrom celluloid import Camera","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:19:52.395962Z","iopub.execute_input":"2023-03-20T21:19:52.396447Z","iopub.status.idle":"2023-03-20T21:19:54.385799Z","shell.execute_reply.started":"2023-03-20T21:19:52.396402Z","shell.execute_reply":"2023-03-20T21:19:54.384428Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class color:\n   PURPLE = '\\03[95m'\n   CYAN = '\\03[96m'\n   DARKCYAN = '\\033[36m'\n   BLUE = '\\03[94m'\n   GREEN = '\\03[92m'\n   YELLOW = '\\03[93m'\n   RED = '\\03[91m'\n   BOLD = '\\03[1m'\n   UNDERLINE = '\\033[4m'\n   END = '\\033[0m'","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:19:54.387815Z","iopub.execute_input":"2023-03-20T21:19:54.388237Z","iopub.status.idle":"2023-03-20T21:19:54.395051Z","shell.execute_reply.started":"2023-03-20T21:19:54.388194Z","shell.execute_reply":"2023-03-20T21:19:54.393081Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.rcParams['figure.dpi'] = 350\nplt.style.use('dark_background')","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:19:54.396727Z","iopub.execute_input":"2023-03-20T21:19:54.397528Z","iopub.status.idle":"2023-03-20T21:19:54.411359Z","shell.execute_reply.started":"2023-03-20T21:19:54.39748Z","shell.execute_reply":"2023-03-20T21:19:54.41014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:\n    layers_count: int = 65\n    train_volumes_path_template: str = \"/kaggle/input/vesuvius-challenge-ink-detection/train/{}/surface_volume\"\n    test_volumes_path_template: str = \"/kaggle/input/vesuvius-challenge-ink-detection/test/{}/surface_volume\"\n    tif_template: str = \"{:02d}.tif\"","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:19:54.413895Z","iopub.execute_input":"2023-03-20T21:19:54.414263Z","iopub.status.idle":"2023-03-20T21:19:54.424691Z","shell.execute_reply.started":"2023-03-20T21:19:54.414228Z","shell.execute_reply":"2023-03-20T21:19:54.423488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_volume(volume_path: str, disable_tqdm: bool = False) -> np.ndarray:\n    volume = []\n    for i in tqdm(range(CFG.layers_count), disable=disable_tqdm):\n        img = Image.open(f\"{volume_path}/{CFG.tif_template.format(i)}\")\n        arr = np.array(img)\n        volume.append(arr)\n    \n    return volume","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:19:54.426204Z","iopub.execute_input":"2023-03-20T21:19:54.426991Z","iopub.status.idle":"2023-03-20T21:19:54.436707Z","shell.execute_reply.started":"2023-03-20T21:19:54.426943Z","shell.execute_reply":"2023-03-20T21:19:54.43558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def animate_volume(\n    volume: Union[np.ndarray, str], \n    ir_photo: Optional[np.ndarray] = None,\n    inklabels: Optional[np.ndarray] = None,\n) -> None:\n    \n    plt.rcParams['figure.dpi'] = 350\n    plt.style.use('dark_background')\n    \n    if isinstance(volume, str):\n        volume = load_volume(volume, disable_tqdm=True)\n\n    # creating figure subplot\n    if ir_photo and inklabels:\n        fig, (ax_ir, ax, ax_il) = plt.subplots(1, 3)\n    elif ir_photo:\n        fig, (ax, ax_ir) = plt.subplots(1, 2)\n    elif inklabels:\n        fig, (ax, ax_il) = plt.subplots(1, 2)\n    else:\n        fig, ax = plt.subplots()\n    \n    camera = Camera(fig) # define the camera that gets the fig we'll plot\n    for i in range(CFG.layers_count):\n        ax.axis('off')\n        ax.text(\n            0.5, 1.08, f\"Layer {i+1}/{CFG.layers_count}\", fontweight='bold', fontsize=18,\n            transform=ax.transAxes, horizontalalignment='center'\n        )\n        ax.imshow(volume[0], cmap='gray') # plot volume layer\n        \n        if ir_photo:\n            ax_ir.imshow(ir_photo, cmap='gray')\n            ax_ir.axis('off')\n            ax_ir.text(\n                0.5, -0.13, \"Infrared photo\", style='italic', fontsize=15,\n                transform=ax_ir.transAxes, horizontalalignment='center'\n            )\n        \n        if inklabels:\n            ax_il.imshow(inklabels, cmap='gray')\n            ax_il.axis('off')\n            ax_il.text(\n                0.5, -0.13, \"Ink labels\", style='italic', fontsize=15,\n                transform=ax_il.transAxes, horizontalalignment='center'\n            )\n        \n        \n        camera.snap() # the camera takes a snapshot of the plot\n        \n        del volume[0]\n        gc.collect()\n\n    plt.close(fig) # close figure\n\n    animation = camera.animate() # get plt animation\n    \n    fix_video_adjust = '<style> video {margin: 0px; padding: 0px; width:100%; height:auto;} </style>'\n    display(\n        HTML(fix_video_adjust + animation.to_html5_video())\n    ) # displaying the animation\n    \n    del camera\n    del animation\n    gc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:19:54.438339Z","iopub.execute_input":"2023-03-20T21:19:54.43878Z","iopub.status.idle":"2023-03-20T21:19:54.452786Z","shell.execute_reply.started":"2023-03-20T21:19:54.438746Z","shell.execute_reply":"2023-03-20T21:19:54.451704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_concat_v(im1: Image, im2: Image) -> Image:\n    dst = Image.new('RGB', (im1.width, im1.height + im2.height))\n    dst.paste(im1, (0, 0))\n    dst.paste(im2, (0, im1.height))\n    return dst","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:19:54.454115Z","iopub.execute_input":"2023-03-20T21:19:54.45462Z","iopub.status.idle":"2023-03-20T21:19:54.469427Z","shell.execute_reply.started":"2023-03-20T21:19:54.454574Z","shell.execute_reply":"2023-03-20T21:19:54.468512Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"1\"></a>\n# <div style=\"box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px inset, rgb(51, 51, 51) 0px 0px 0px 3px inset; padding:20px; font-size:32px; font-family: consolas; text-align:center; display:fill; border-radius:15px;  color:rgb(34, 34, 34);\"> <b> 1. Overview directories</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ <code>[train/test]/[fragment_id]/surface_volume/[image_id].tif</code> slices from the 3d x-ray surface volume. Each file contains a greyscale slice in the z-direction. Each fragment contains <b>65 slices</b>. Combined this image stack gives us <code>width * height * 65</code> number of voxels per fragment. You can expect two fragments in the hidden test set, which together are roughly the same as the first training fragment. The sample slices available to download in the test folders are simply copied from training fragment one.</p>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ <code>train/</code> directory has <b>3</b> 3d x-ray surface volumes.</p>","metadata":{}},{"cell_type":"code","source":"sorted(os.listdir(\"/kaggle/input/vesuvius-challenge-ink-detection/train\"))","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:19:54.69315Z","iopub.execute_input":"2023-03-20T21:19:54.693932Z","iopub.status.idle":"2023-03-20T21:19:54.706415Z","shell.execute_reply.started":"2023-03-20T21:19:54.693888Z","shell.execute_reply":"2023-03-20T21:19:54.705351Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ <code>test/</code> directory has <b>3</b> 3d x-ray surface volumes. Which together are roughly the same as the <b>1st training fragment</b></p>","metadata":{}},{"cell_type":"code","source":"sorted(os.listdir(\"/kaggle/input/vesuvius-challenge-ink-detection/test\"))","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:19:55.469869Z","iopub.execute_input":"2023-03-20T21:19:55.470536Z","iopub.status.idle":"2023-03-20T21:19:55.480232Z","shell.execute_reply.started":"2023-03-20T21:19:55.470493Z","shell.execute_reply":"2023-03-20T21:19:55.479025Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"2\"></a>\n# <div style=\"box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px inset, rgb(51, 51, 51) 0px 0px 0px 3px inset; padding:20px; font-size:32px; font-family: consolas; text-align:center; display:fill; border-radius:15px;  color:rgb(34, 34, 34);\"> <b> 2. Overview the 1st volume of the <i>train/</i> directory</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Each of train volumes has next files: </p>\n\n* <p style=\"font-family: consolas; font-size: 16px;\"><code>mask.png</code> — a binary mask of which pixels contain data.</p>\n* <p style=\"font-family: consolas; font-size: 16px;\"><code>ir.png</code> — the infrared photo on which the binary mask is based.</p>\n* <p style=\"font-family: consolas; font-size: 16px;\"><code>inklabels.png</code> — a binary mask of the ink vs no-ink labels.</p>\n* <p style=\"font-family: consolas; font-size: 16px;\"><code>inklabels_rle.csv</code> — a run-length-encoded version of the labels, generated using this script. This is the same format as you should make your submission in.</p>","metadata":{}},{"cell_type":"code","source":"os.listdir(\"/kaggle/input/vesuvius-challenge-ink-detection/train/1\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:19:57.26902Z","iopub.execute_input":"2023-03-20T21:19:57.26942Z","iopub.status.idle":"2023-03-20T21:19:57.278902Z","shell.execute_reply.started":"2023-03-20T21:19:57.269387Z","shell.execute_reply":"2023-03-20T21:19:57.277721Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"2.1\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 2.1 Consider <i>mask.png</i> image</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Let's load the mask</p>","metadata":{}},{"cell_type":"code","source":"train_1_mask = Image.open(\"/kaggle/input/vesuvius-challenge-ink-detection/train/1/mask.png\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:19:58.005091Z","iopub.execute_input":"2023-03-20T21:19:58.006246Z","iopub.status.idle":"2023-03-20T21:19:58.027896Z","shell.execute_reply.started":"2023-03-20T21:19:58.00619Z","shell.execute_reply":"2023-03-20T21:19:58.026698Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Mask image size: {color.BOLD}{color.CYAN}{train_1_mask.size}{color.END}\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:19:58.219322Z","iopub.execute_input":"2023-03-20T21:19:58.219732Z","iopub.status.idle":"2023-03-20T21:19:58.225334Z","shell.execute_reply.started":"2023-03-20T21:19:58.219694Z","shell.execute_reply":"2023-03-20T21:19:58.223969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ And plot it</p>","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(dpi=160)\nax.axis('off')\nax.imshow(train_1_mask);","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:33:51.820665Z","iopub.execute_input":"2023-03-20T19:33:51.821078Z","iopub.status.idle":"2023-03-20T19:33:58.451272Z","shell.execute_reply.started":"2023-03-20T19:33:51.821041Z","shell.execute_reply":"2023-03-20T19:33:58.449513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ OK there is nothing interesting in the mask, so let's take a look at <code>ir.png</code> image.</p>","metadata":{}},{"cell_type":"markdown","source":"<a id=\"2.2\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 2.2 Consider <i>ir.png</i> image</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Load the infrared image</p>","metadata":{}},{"cell_type":"code","source":"train_1_ir = Image.open(\"/kaggle/input/vesuvius-challenge-ink-detection/train/1/ir.png\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:33:58.453771Z","iopub.execute_input":"2023-03-20T19:33:58.45423Z","iopub.status.idle":"2023-03-20T19:33:58.492229Z","shell.execute_reply.started":"2023-03-20T19:33:58.454164Z","shell.execute_reply":"2023-03-20T19:33:58.491388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Infrared image size: {color.BOLD}{color.CYAN}{train_1_ir.size}{color.END}\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:33:58.493363Z","iopub.execute_input":"2023-03-20T19:33:58.493818Z","iopub.status.idle":"2023-03-20T19:33:58.498299Z","shell.execute_reply.started":"2023-03-20T19:33:58.493786Z","shell.execute_reply":"2023-03-20T19:33:58.497525Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ As you can see in the image there are some fragments of words. The approximate number of letters on the fragment is about 20.</p>\n\n<p style=\"font-family: consolas; font-size: 16px;\">🔴 It is important to note that there is no infrared image in the test dataset, only a mask and 65 volume layers from a 3d x-ray.</p>","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(dpi=160)\nax.axis('off')\nax.imshow(train_1_ir, cmap='gray');","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:33:58.501031Z","iopub.execute_input":"2023-03-20T19:33:58.50147Z","iopub.status.idle":"2023-03-20T19:34:02.121262Z","shell.execute_reply.started":"2023-03-20T19:33:58.501437Z","shell.execute_reply":"2023-03-20T19:34:02.120214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"2.3\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 2.3 Consider <i>inklabels.png</i> image</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Load <code>inklabels.png</code> image.</p>","metadata":{}},{"cell_type":"code","source":"train_1_inklabels = Image.open(\"/kaggle/input/vesuvius-challenge-ink-detection/train/1/inklabels.png\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:34:02.122377Z","iopub.execute_input":"2023-03-20T19:34:02.123092Z","iopub.status.idle":"2023-03-20T19:34:02.136676Z","shell.execute_reply.started":"2023-03-20T19:34:02.123056Z","shell.execute_reply":"2023-03-20T19:34:02.135352Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Inklabels image size: {color.BOLD}{color.CYAN}{train_1_inklabels.size}{color.END}\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:34:02.138524Z","iopub.execute_input":"2023-03-20T19:34:02.139202Z","iopub.status.idle":"2023-03-20T19:34:02.144911Z","shell.execute_reply.started":"2023-03-20T19:34:02.13913Z","shell.execute_reply":"2023-03-20T19:34:02.143958Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ You are supposed to use it as a prediction reference. Thus, you predict a binary semantic mask from 3D X-ray 65 volume layers and check its intersection with the inklabels mask.</p>","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(dpi=160)\nax.axis('off')\nax.imshow(train_1_inklabels, cmap='gray');","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:34:02.146718Z","iopub.execute_input":"2023-03-20T19:34:02.14748Z","iopub.status.idle":"2023-03-20T19:34:08.605923Z","shell.execute_reply.started":"2023-03-20T19:34:02.147424Z","shell.execute_reply":"2023-03-20T19:34:08.604888Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Let's see the distribution of ink on the first training instance. To calculate the distribution, I consider it optimal to first take a mask, and only after that calculate the distribution, since it is in this way that it is assumed that training and inference will take place.</p>","metadata":{}},{"cell_type":"code","source":"# conver to np.ndarray\ntrain_1_inklabels_np = np.array(train_1_inklabels)\ntrain_1_mask_np = np.array(train_1_mask, dtype=np.bool8)\n\n# reassign new value for empty space \ntrain_1_inklabels_np[np.logical_not(train_1_mask_np)] = 2\n\n# get counts for each label\ntrain_1_pix_counts = np.unique(\n    train_1_inklabels_np, \n    return_counts=True\n)[1]","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:34:08.607621Z","iopub.execute_input":"2023-03-20T19:34:08.607998Z","iopub.status.idle":"2023-03-20T19:34:09.823496Z","shell.execute_reply.started":"2023-03-20T19:34:08.607962Z","shell.execute_reply":"2023-03-20T19:34:09.821289Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ On visualization you will see next 3 labels: </p>\n\n* <p style=\"font-family: consolas; font-size: 16px;\"><code>No ink</code> — is inside the mask, but is not ink.</p>\n* <p style=\"font-family: consolas; font-size: 16px;\"><code>Ink</code> — is inside the mask and is ink.</p>\n* <p style=\"font-family: consolas; font-size: 16px;\"><code>Empty space</code> — is outside the mask.</p>","metadata":{}},{"cell_type":"code","source":"fig = px.bar(\n    x=[\"No ink\", \"Ink\", \"Empty space\"], y=train_1_pix_counts,\n    color_discrete_sequence=['darkgoldenrod']\n)\n\nfig.update_layout(\n    xaxis_title=\"Label\", yaxis_title=\"Pixel count\",\n    title={\n        'text': \"Distribution of Ink on the 1st train instance\",\n        'y':0.95,\n        'x':0.5,\n        'xanchor': 'center',\n        'yanchor': 'top'\n    }\n)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:34:09.826291Z","iopub.execute_input":"2023-03-20T19:34:09.826978Z","iopub.status.idle":"2023-03-20T19:34:11.578945Z","shell.execute_reply.started":"2023-03-20T19:34:09.826902Z","shell.execute_reply":"2023-03-20T19:34:11.577994Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"2.4\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 2.4 Consider <i>inklabels_rle.csv</i> file</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ There is nothing interesting in this file. It's just a run-length-encoded version of the <code>inklabels.png</code> image, generated using <a href=\"https://gist.github.com/janpaul123/ca3477c1db6de4346affca37e0e3d5b0\"><strong>this script</strong></a>.</p>\n\n<p style=\"font-family: consolas; font-size: 16px;\">⚪ It's important to note that this is in the same format as you should make your <a href=\"https://www.kaggle.com/competitions/vesuvius-challenge-ink-detection/overview/evaluation\"><strong>submission in</strong></a>.</p>","metadata":{}},{"cell_type":"code","source":"pd.read_csv(\"/kaggle/input/vesuvius-challenge-ink-detection/train/1/inklabels_rle.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:34:11.582021Z","iopub.execute_input":"2023-03-20T19:34:11.58235Z","iopub.status.idle":"2023-03-20T19:34:11.624556Z","shell.execute_reply.started":"2023-03-20T19:34:11.582323Z","shell.execute_reply":"2023-03-20T19:34:11.623517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"2.5\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 2.5 Consider <i>surface_volumes/</i> directory</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ As mentioned above these are slices from the 3d x-ray surface volume. Each file contains a <b>greyscale slice in the z-direction</b>. Each fragment contains <b>65 slices</b>. Combined this image stack gives us <code>65 * height * width</code> number of voxels per fragment.</p>","metadata":{}},{"cell_type":"code","source":"first_train_volume = CFG.train_volumes_path_template.format(1)","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:34:11.625803Z","iopub.execute_input":"2023-03-20T19:34:11.626141Z","iopub.status.idle":"2023-03-20T19:34:11.63177Z","shell.execute_reply.started":"2023-03-20T19:34:11.626108Z","shell.execute_reply":"2023-03-20T19:34:11.630494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_volume_1 = load_volume(first_train_volume)","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:34:11.633772Z","iopub.execute_input":"2023-03-20T19:34:11.634161Z","iopub.status.idle":"2023-03-20T19:35:50.998544Z","shell.execute_reply.started":"2023-03-20T19:34:11.634133Z","shell.execute_reply":"2023-03-20T19:35:50.996965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"1st train volume size: {color.BOLD}{color.CYAN}{train_volume_1[0].shape}{color.END}\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:35:50.999921Z","iopub.execute_input":"2023-03-20T19:35:51.000347Z","iopub.status.idle":"2023-03-20T19:35:51.007142Z","shell.execute_reply.started":"2023-03-20T19:35:51.000304Z","shell.execute_reply":"2023-03-20T19:35:51.005035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ The whole volume is huge, let's see exactly how.</p>","metadata":{}},{"cell_type":"code","source":"bytes_size = CFG.layers_count * train_volume_1[0].size * train_volume_1[0].itemsize\nprint(f\"Memory size of 1st train volume in bytes: {color.BOLD}{color.PURPLE}{bytes_size}{color.END} B\")\nprint(f\"Memory size of 1st train volume in gigabytes: {color.BOLD}{color.PURPLE}{bytes_size / 1024**3}{color.END} GB\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:35:51.009022Z","iopub.execute_input":"2023-03-20T19:35:51.009956Z","iopub.status.idle":"2023-03-20T19:35:51.023055Z","shell.execute_reply.started":"2023-03-20T19:35:51.009889Z","shell.execute_reply":"2023-03-20T19:35:51.021592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ For a better understanding of how the layers relate to each other, I made an <b>animation with the transition from one layer to another</b>. And so for all 65 layers.</p>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ As noted in the description of this competition, it is visually almost impossible to notice any ink on these images. But together they form a coherent picture, which, I hope, can be picked up very easily by a neural network.</p>","metadata":{}},{"cell_type":"code","source":"animate_volume(train_volume_1)","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:35:51.025142Z","iopub.execute_input":"2023-03-20T19:35:51.025642Z","iopub.status.idle":"2023-03-20T19:38:28.911846Z","shell.execute_reply.started":"2023-03-20T19:35:51.025597Z","shell.execute_reply":"2023-03-20T19:38:28.909931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Let's animate volume right next to its infrared image. So you can look at some features on the fly!</p>","metadata":{}},{"cell_type":"code","source":"animate_volume(first_train_volume, ir_photo=train_1_ir)","metadata":{"execution":{"iopub.status.busy":"2023-03-20T19:38:28.914768Z","iopub.execute_input":"2023-03-20T19:38:28.915308Z","iopub.status.idle":"2023-03-20T19:43:50.833759Z","shell.execute_reply.started":"2023-03-20T19:38:28.915255Z","shell.execute_reply":"2023-03-20T19:43:50.831334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ And let's animate volume next to its ink labels mask.</p>","metadata":{}},{"cell_type":"code","source":"# animate_volume(first_train_volume, inklabels=train_1_inklabels)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# animate_volume(first_train_volume, train_1_ir, train_1_inklabels)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"3\"></a>\n# <div style=\"box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px inset, rgb(51, 51, 51) 0px 0px 0px 3px inset; padding:20px; font-size:32px; font-family: consolas; text-align:center; display:fill; border-radius:15px;  color:rgb(34, 34, 34);\"> <b> 3. Overview the 2nd volume of the <i>train/</i> directory</b></div>","metadata":{}},{"cell_type":"markdown","source":"<a id=\"3.1\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 3.1 Consider <i>mask.png</i> image</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Let's load the mask</p>","metadata":{}},{"cell_type":"code","source":"train_2_mask = Image.open(\"/kaggle/input/vesuvius-challenge-ink-detection/train/2/mask.png\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:50:21.107865Z","iopub.execute_input":"2023-03-20T20:50:21.108633Z","iopub.status.idle":"2023-03-20T20:50:21.133232Z","shell.execute_reply.started":"2023-03-20T20:50:21.108572Z","shell.execute_reply":"2023-03-20T20:50:21.130137Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Mask image size: {color.BOLD}{color.CYAN}{train_2_mask.size}{color.END}\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:50:21.633728Z","iopub.execute_input":"2023-03-20T20:50:21.63509Z","iopub.status.idle":"2023-03-20T20:50:21.643064Z","shell.execute_reply.started":"2023-03-20T20:50:21.63503Z","shell.execute_reply":"2023-03-20T20:50:21.641276Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ And plot it</p>","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(dpi=160)\nax.axis('off')\nax.imshow(train_2_mask);","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:50:22.023558Z","iopub.execute_input":"2023-03-20T20:50:22.024097Z","iopub.status.idle":"2023-03-20T20:50:36.356886Z","shell.execute_reply.started":"2023-03-20T20:50:22.024048Z","shell.execute_reply":"2023-03-20T20:50:36.354555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ OK there is nothing interesting in the mask, so let's take a look at <code>ir.png</code> image.</p>","metadata":{}},{"cell_type":"markdown","source":"<a id=\"3.2\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 3.2 Consider <i>ir.png</i> image</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Load the infrared image</p>","metadata":{}},{"cell_type":"code","source":"train_2_ir = Image.open(\"/kaggle/input/vesuvius-challenge-ink-detection/train/2/ir.png\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:50:36.359428Z","iopub.execute_input":"2023-03-20T20:50:36.359861Z","iopub.status.idle":"2023-03-20T20:50:36.366261Z","shell.execute_reply.started":"2023-03-20T20:50:36.359819Z","shell.execute_reply":"2023-03-20T20:50:36.364872Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Infrared image size: {color.BOLD}{color.CYAN}{train_2_ir.size}{color.END}\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:50:36.367963Z","iopub.execute_input":"2023-03-20T20:50:36.369104Z","iopub.status.idle":"2023-03-20T20:50:36.380125Z","shell.execute_reply.started":"2023-03-20T20:50:36.369052Z","shell.execute_reply":"2023-03-20T20:50:36.3787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ As you can see in the image there are some fragments of words. The approximate number of letters on the fragment is about 65.</p>\n\n<p style=\"font-family: consolas; font-size: 16px;\">🔴 It is important to note that there is no infrared image in the test dataset, only a mask and 65 volume layers from a 3d x-ray.</p>","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(dpi=160)\nax.axis('off')\nax.imshow(train_2_ir, cmap='gray');","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:50:36.383168Z","iopub.execute_input":"2023-03-20T20:50:36.383625Z","iopub.status.idle":"2023-03-20T20:50:43.471502Z","shell.execute_reply.started":"2023-03-20T20:50:36.383579Z","shell.execute_reply":"2023-03-20T20:50:43.469645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"3.3\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 3.3 Consider <i>inklabels.png</i> image</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Load <code>inklabels.png</code> image.</p>","metadata":{}},{"cell_type":"code","source":"train_2_inklabels = Image.open(\"/kaggle/input/vesuvius-challenge-ink-detection/train/2/inklabels.png\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:50:43.473497Z","iopub.execute_input":"2023-03-20T20:50:43.475303Z","iopub.status.idle":"2023-03-20T20:50:43.483204Z","shell.execute_reply.started":"2023-03-20T20:50:43.475208Z","shell.execute_reply":"2023-03-20T20:50:43.481967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Inklabels image size: {color.BOLD}{color.CYAN}{train_2_inklabels.size}{color.END}\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:50:43.485571Z","iopub.execute_input":"2023-03-20T20:50:43.486371Z","iopub.status.idle":"2023-03-20T20:50:43.497154Z","shell.execute_reply.started":"2023-03-20T20:50:43.486321Z","shell.execute_reply":"2023-03-20T20:50:43.495472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(dpi=160)\nax.axis('off')\nax.imshow(train_2_inklabels, cmap='gray');","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:50:43.499092Z","iopub.execute_input":"2023-03-20T20:50:43.500025Z","iopub.status.idle":"2023-03-20T20:50:57.211139Z","shell.execute_reply.started":"2023-03-20T20:50:43.499958Z","shell.execute_reply":"2023-03-20T20:50:57.209443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Let's see the distribution of ink on the second training instance. To calculate the distribution, I consider it optimal to first take a mask, and only after that calculate the distribution, since it is in this way that it is assumed that training and inference will take place.</p>","metadata":{}},{"cell_type":"code","source":"# conver to np.ndarray\ntrain_2_inklabels_np = np.array(train_2_inklabels)\ntrain_2_mask_np = np.array(train_2_mask, dtype=np.bool8)\n\n# reassign new value for empty space \ntrain_2_inklabels_np[np.logical_not(train_2_mask_np)] = 2\n\n# get counts for each label\ntrain_2_pix_counts = np.unique(\n    train_2_inklabels_np, \n    return_counts=True\n)[1]","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:50:57.213283Z","iopub.execute_input":"2023-03-20T20:50:57.213818Z","iopub.status.idle":"2023-03-20T20:51:00.465858Z","shell.execute_reply.started":"2023-03-20T20:50:57.213762Z","shell.execute_reply":"2023-03-20T20:51:00.464279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ On visualization you will see next 3 labels: </p>\n\n* <p style=\"font-family: consolas; font-size: 16px;\"><code>No ink</code> — is inside the mask, but is not ink.</p>\n* <p style=\"font-family: consolas; font-size: 16px;\"><code>Ink</code> — is inside the mask and is ink.</p>\n* <p style=\"font-family: consolas; font-size: 16px;\"><code>Empty space</code> — is outside the mask.</p>","metadata":{}},{"cell_type":"code","source":"fig = px.bar(\n    x=[\"No ink\", \"Ink\", \"Empty space\"], y=train_2_pix_counts,\n    color_discrete_sequence=['cadetblue']\n)\n\nfig.update_layout(\n    xaxis_title=\"Label\", yaxis_title=\"Pixel count\",\n    title={\n        'text': \"Distribution of Ink on the 2nd train instance\",\n        'y':0.95,\n        'x':0.5,\n        'xanchor': 'center',\n        'yanchor': 'top'\n    }\n)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:51:00.467305Z","iopub.execute_input":"2023-03-20T20:51:00.46764Z","iopub.status.idle":"2023-03-20T20:51:00.53006Z","shell.execute_reply.started":"2023-03-20T20:51:00.467607Z","shell.execute_reply":"2023-03-20T20:51:00.528529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"3.4\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 3.4 Consider <i>inklabels_rle.csv</i> file</b></div>","metadata":{}},{"cell_type":"code","source":"pd.read_csv(\"/kaggle/input/vesuvius-challenge-ink-detection/train/2/inklabels_rle.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:51:00.533331Z","iopub.execute_input":"2023-03-20T20:51:00.533758Z","iopub.status.idle":"2023-03-20T20:51:00.585689Z","shell.execute_reply.started":"2023-03-20T20:51:00.533717Z","shell.execute_reply":"2023-03-20T20:51:00.584069Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"3.5\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 3.5 Consider <i>surface_volumes/</i> directory</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ As mentioned above these are slices from the 3d x-ray surface volume. Each file contains a <b>greyscale slice in the z-direction</b>. Each fragment contains <b>65 slices</b>. Combined this image stack gives us <code>65 * height * width</code> number of voxels per fragment.</p>","metadata":{}},{"cell_type":"code","source":"second_train_volume = CFG.train_volumes_path_template.format(2)","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:51:00.587045Z","iopub.execute_input":"2023-03-20T20:51:00.587602Z","iopub.status.idle":"2023-03-20T20:51:00.594369Z","shell.execute_reply.started":"2023-03-20T20:51:00.587561Z","shell.execute_reply":"2023-03-20T20:51:00.592517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_volume_2 = load_volume(second_train_volume)","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:27:03.830862Z","iopub.execute_input":"2023-03-20T20:27:03.831261Z","iopub.status.idle":"2023-03-20T20:32:59.544273Z","shell.execute_reply.started":"2023-03-20T20:27:03.83122Z","shell.execute_reply":"2023-03-20T20:32:59.542599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"2st train volume size: {color.BOLD}{color.CYAN}{train_volume_2[0].shape}{color.END}\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:32:59.546348Z","iopub.execute_input":"2023-03-20T20:32:59.546749Z","iopub.status.idle":"2023-03-20T20:32:59.554099Z","shell.execute_reply.started":"2023-03-20T20:32:59.546714Z","shell.execute_reply":"2023-03-20T20:32:59.552869Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ The whole volume is huge, let's see exactly how.</p>","metadata":{}},{"cell_type":"code","source":"bytes_size = CFG.layers_count * train_volume_2[0].size * train_volume_2[0].itemsize\nprint(f\"Memory size of 2st train volume in bytes: {color.BOLD}{color.PURPLE}{bytes_size}{color.END} B\")\nprint(f\"Memory size of 2st train volume in gigabytes: {color.BOLD}{color.PURPLE}{bytes_size / 1024**3}{color.END} GB\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:32:59.5557Z","iopub.execute_input":"2023-03-20T20:32:59.556047Z","iopub.status.idle":"2023-03-20T20:32:59.570469Z","shell.execute_reply.started":"2023-03-20T20:32:59.556013Z","shell.execute_reply":"2023-03-20T20:32:59.568359Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ For a better understanding of how the layers relate to each other, I made an <b>animation with the transition from one layer to another</b>. And so for all 65 layers.</p>","metadata":{}},{"cell_type":"code","source":"animate_volume(train_volume_2)","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:32:59.572042Z","iopub.execute_input":"2023-03-20T20:32:59.572444Z","iopub.status.idle":"2023-03-20T20:39:48.548784Z","shell.execute_reply.started":"2023-03-20T20:32:59.572407Z","shell.execute_reply":"2023-03-20T20:39:48.54743Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Let's animate volume right next to its infrared image. So you can look at some features on the fly!</p>","metadata":{}},{"cell_type":"code","source":"animate_volume(second_train_volume, ir_photo=train_2_ir)","metadata":{"execution":{"iopub.status.busy":"2023-03-20T20:51:34.081148Z","iopub.execute_input":"2023-03-20T20:51:34.083856Z","iopub.status.idle":"2023-03-20T21:11:25.815478Z","shell.execute_reply.started":"2023-03-20T20:51:34.083748Z","shell.execute_reply":"2023-03-20T21:11:25.812814Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ And let's animate volume next to its ink labels mask.</p>","metadata":{}},{"cell_type":"code","source":"# animate_volume(second_train_volume, inklabels=train_2_inklabels)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"4\"></a>\n# <div style=\"box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px inset, rgb(51, 51, 51) 0px 0px 0px 3px inset; padding:20px; font-size:32px; font-family: consolas; text-align:center; display:fill; border-radius:15px;  color:rgb(34, 34, 34);\"> <b> 4. Overview the 3rd volume of the <i>train/</i> directory</b></div>","metadata":{}},{"cell_type":"markdown","source":"<a id=\"4.1\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 4.1 Consider <i>mask.png</i> image</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Let's load the mask</p>","metadata":{}},{"cell_type":"code","source":"train_3_mask = Image.open(\"/kaggle/input/vesuvius-challenge-ink-detection/train/3/mask.png\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:20:45.390245Z","iopub.execute_input":"2023-03-20T21:20:45.390674Z","iopub.status.idle":"2023-03-20T21:20:45.397781Z","shell.execute_reply.started":"2023-03-20T21:20:45.390637Z","shell.execute_reply":"2023-03-20T21:20:45.395959Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Mask image size: {color.BOLD}{color.CYAN}{train_3_mask.size}{color.END}\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:20:46.317949Z","iopub.execute_input":"2023-03-20T21:20:46.318355Z","iopub.status.idle":"2023-03-20T21:20:46.324719Z","shell.execute_reply.started":"2023-03-20T21:20:46.318311Z","shell.execute_reply":"2023-03-20T21:20:46.323358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ And plot it</p>","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(dpi=160)\nax.axis('off')\nax.imshow(train_3_mask);","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:20:47.155599Z","iopub.execute_input":"2023-03-20T21:20:47.156495Z","iopub.status.idle":"2023-03-20T21:20:53.932037Z","shell.execute_reply.started":"2023-03-20T21:20:47.156444Z","shell.execute_reply":"2023-03-20T21:20:53.930634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ OK there is nothing interesting in the mask, so let's take a look at <code>ir.png</code> image.</p>","metadata":{}},{"cell_type":"markdown","source":"<a id=\"4.2\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 4.2 Consider <i>ir.png</i> image</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Load the infrared image</p>","metadata":{}},{"cell_type":"code","source":"train_3_ir = Image.open(\"/kaggle/input/vesuvius-challenge-ink-detection/train/3/ir.png\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:20:53.933864Z","iopub.execute_input":"2023-03-20T21:20:53.934224Z","iopub.status.idle":"2023-03-20T21:20:53.99297Z","shell.execute_reply.started":"2023-03-20T21:20:53.93419Z","shell.execute_reply":"2023-03-20T21:20:53.992044Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Infrared image size: {color.BOLD}{color.CYAN}{train_3_ir.size}{color.END}\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:20:53.994561Z","iopub.execute_input":"2023-03-20T21:20:53.994923Z","iopub.status.idle":"2023-03-20T21:20:54.00231Z","shell.execute_reply.started":"2023-03-20T21:20:53.994887Z","shell.execute_reply":"2023-03-20T21:20:54.000766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ As you can see in the image there are some fragments of words. The approximate number of letters on the fragment is about 15.</p>\n\n<p style=\"font-family: consolas; font-size: 16px;\">🔴 It is important to note that there is no infrared image in the test dataset, only a mask and 65 volume layers from a 3d x-ray.</p>","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(dpi=160)\nax.axis('off')\nax.imshow(train_3_ir, cmap='gray');","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:20:54.005939Z","iopub.execute_input":"2023-03-20T21:20:54.006423Z","iopub.status.idle":"2023-03-20T21:20:58.588722Z","shell.execute_reply.started":"2023-03-20T21:20:54.006372Z","shell.execute_reply":"2023-03-20T21:20:58.587487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"4.3\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 4.3 Consider <i>inklabels.png</i> image</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Load <code>inklabels.png</code> image.</p>","metadata":{}},{"cell_type":"code","source":"train_3_inklabels = Image.open(\"/kaggle/input/vesuvius-challenge-ink-detection/train/3/inklabels.png\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:20:58.590197Z","iopub.execute_input":"2023-03-20T21:20:58.59065Z","iopub.status.idle":"2023-03-20T21:20:58.601968Z","shell.execute_reply.started":"2023-03-20T21:20:58.590608Z","shell.execute_reply":"2023-03-20T21:20:58.60115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Inklabels image size: {color.BOLD}{color.CYAN}{train_3_inklabels.size}{color.END}\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:20:58.603183Z","iopub.execute_input":"2023-03-20T21:20:58.604161Z","iopub.status.idle":"2023-03-20T21:20:58.610476Z","shell.execute_reply.started":"2023-03-20T21:20:58.604116Z","shell.execute_reply":"2023-03-20T21:20:58.609316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(dpi=160)\nax.axis('off')\nax.imshow(train_3_inklabels, cmap='gray');","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:20:58.61188Z","iopub.execute_input":"2023-03-20T21:20:58.612198Z","iopub.status.idle":"2023-03-20T21:21:05.308714Z","shell.execute_reply.started":"2023-03-20T21:20:58.612167Z","shell.execute_reply":"2023-03-20T21:21:05.307738Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Let's see the distribution of ink on the third training instance. To calculate the distribution, I consider it optimal to first take a mask, and only after that calculate the distribution, since it is in this way that it is assumed that training and inference will take place.</p>","metadata":{}},{"cell_type":"code","source":"# conver to np.ndarray\ntrain_3_inklabels_np = np.array(train_3_inklabels)\ntrain_3_mask_np = np.array(train_3_mask, dtype=np.bool8)\n\n# reassign new value for empty space \ntrain_3_inklabels_np[np.logical_not(train_3_mask_np)] = 2\n\n# get counts for each label\ntrain_3_pix_counts = np.unique(\n    train_3_inklabels_np, \n    return_counts=True\n)[1]","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:21:05.309855Z","iopub.execute_input":"2023-03-20T21:21:05.31101Z","iopub.status.idle":"2023-03-20T21:21:06.318033Z","shell.execute_reply.started":"2023-03-20T21:21:05.310961Z","shell.execute_reply":"2023-03-20T21:21:06.317052Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ On visualization you will see next 3 labels: </p>\n\n* <p style=\"font-family: consolas; font-size: 16px;\"><code>No ink</code> — is inside the mask, but is not ink.</p>\n* <p style=\"font-family: consolas; font-size: 16px;\"><code>Ink</code> — is inside the mask and is ink.</p>\n* <p style=\"font-family: consolas; font-size: 16px;\"><code>Empty space</code> — is outside the mask.</p>","metadata":{}},{"cell_type":"code","source":"fig = px.bar(\n    x=[\"No ink\", \"Ink\", \"Empty space\"], y=train_3_pix_counts,\n    color_discrete_sequence=['darkslateblue']\n)\n\nfig.update_layout(\n    xaxis_title=\"Label\", yaxis_title=\"Pixel count\",\n    title={\n        'text': \"Distribution of Ink on the 3rd train instance\",\n        'y':0.95,\n        'x':0.5,\n        'xanchor': 'center',\n        'yanchor': 'top'\n    }\n)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:21:06.319352Z","iopub.execute_input":"2023-03-20T21:21:06.320149Z","iopub.status.idle":"2023-03-20T21:21:07.84966Z","shell.execute_reply.started":"2023-03-20T21:21:06.320104Z","shell.execute_reply":"2023-03-20T21:21:07.848679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"4.4\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 4.4 Consider <i>inklabels_rle.csv</i> file</b></div>","metadata":{}},{"cell_type":"code","source":"pd.read_csv(\"/kaggle/input/vesuvius-challenge-ink-detection/train/3/inklabels_rle.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:21:07.853265Z","iopub.execute_input":"2023-03-20T21:21:07.854196Z","iopub.status.idle":"2023-03-20T21:21:07.895731Z","shell.execute_reply.started":"2023-03-20T21:21:07.854157Z","shell.execute_reply":"2023-03-20T21:21:07.894227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"4.5\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 4.5 Consider <i>surface_volumes/</i> directory</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ As mentioned above these are slices from the 3d x-ray surface volume. Each file contains a <b>greyscale slice in the z-direction</b>. Each fragment contains <b>65 slices</b>. Combined this image stack gives us <code>65 * height * width</code> number of voxels per fragment.</p>","metadata":{}},{"cell_type":"code","source":"third_train_volume = CFG.train_volumes_path_template.format(3)","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:21:07.897018Z","iopub.execute_input":"2023-03-20T21:21:07.897343Z","iopub.status.idle":"2023-03-20T21:21:07.90314Z","shell.execute_reply.started":"2023-03-20T21:21:07.897311Z","shell.execute_reply":"2023-03-20T21:21:07.90191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_volume_3 = load_volume(third_train_volume)","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:21:07.904924Z","iopub.execute_input":"2023-03-20T21:21:07.905383Z","iopub.status.idle":"2023-03-20T21:22:13.280809Z","shell.execute_reply.started":"2023-03-20T21:21:07.905336Z","shell.execute_reply":"2023-03-20T21:22:13.279369Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"3st train volume size: {color.BOLD}{color.CYAN}{train_volume_3[0].shape}{color.END}\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:22:13.282481Z","iopub.execute_input":"2023-03-20T21:22:13.28324Z","iopub.status.idle":"2023-03-20T21:22:13.289665Z","shell.execute_reply.started":"2023-03-20T21:22:13.283189Z","shell.execute_reply":"2023-03-20T21:22:13.288334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ The whole volume is huge, let's see exactly how much.</p>","metadata":{}},{"cell_type":"code","source":"bytes_size = CFG.layers_count * train_volume_3[0].size * train_volume_3[0].itemsize\nprint(f\"Memory size of 3st train volume in bytes: {color.BOLD}{color.PURPLE}{bytes_size}{color.END} B\")\nprint(f\"Memory size of 3st train volume in gigabytes: {color.BOLD}{color.PURPLE}{bytes_size / 1024**3}{color.END} GB\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:22:13.291112Z","iopub.execute_input":"2023-03-20T21:22:13.291516Z","iopub.status.idle":"2023-03-20T21:22:13.308087Z","shell.execute_reply.started":"2023-03-20T21:22:13.291483Z","shell.execute_reply":"2023-03-20T21:22:13.306981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ For a better understanding of how the layers relate to each other, I made an <b>animation with the transition from one layer to another</b>. And so for all 65 layers.</p>","metadata":{}},{"cell_type":"code","source":"animate_volume(train_volume_3)","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:22:13.31012Z","iopub.execute_input":"2023-03-20T21:22:13.310483Z","iopub.status.idle":"2023-03-20T21:25:30.080765Z","shell.execute_reply.started":"2023-03-20T21:22:13.310448Z","shell.execute_reply":"2023-03-20T21:25:30.078486Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Let's animate volume right next to its infrared image. So you can look at some features on the fly!</p>","metadata":{}},{"cell_type":"code","source":"animate_volume(third_train_volume, ir_photo=train_3_ir)","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:25:30.08279Z","iopub.execute_input":"2023-03-20T21:25:30.083199Z","iopub.status.idle":"2023-03-20T21:31:52.187632Z","shell.execute_reply.started":"2023-03-20T21:25:30.08312Z","shell.execute_reply":"2023-03-20T21:31:52.186366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ And let's animate volume next to its ink labels mask.</p>","metadata":{}},{"cell_type":"code","source":"# animate_volume(third_train_volume, inklabels=train_3_inklabels)","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:31:52.189219Z","iopub.execute_input":"2023-03-20T21:31:52.189788Z","iopub.status.idle":"2023-03-20T21:31:52.196178Z","shell.execute_reply.started":"2023-03-20T21:31:52.18975Z","shell.execute_reply":"2023-03-20T21:31:52.194366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"5\"></a>\n# <div style=\"box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px inset, rgb(51, 51, 51) 0px 0px 0px 3px inset; padding:20px; font-size:32px; font-family: consolas; text-align:center; display:fill; border-radius:15px;  color:rgb(34, 34, 34);\"> <b> 5. Overview volumes of the <i>test/</i> directory</b></div>","metadata":{}},{"cell_type":"markdown","source":"<a id=\"5.1\"></a>\n## <div style=\"box-shadow: rgba(0, 0, 0, 0.18) 0px 2px 4px inset; padding:20px; font-size:24px; font-family: consolas; text-align:center; display:fill; border-radius:15px; color:rgb(67, 66, 66)\"> <b> 5.1 Consider <i>mask.png</i> images</b></div>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Let's load masks</p>","metadata":{}},{"cell_type":"code","source":"test_a_mask = Image.open(\"/kaggle/input/vesuvius-challenge-ink-detection/test/a/mask.png\")\ntest_b_mask = Image.open(\"/kaggle/input/vesuvius-challenge-ink-detection/test/b/mask.png\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:31:52.197623Z","iopub.execute_input":"2023-03-20T21:31:52.197938Z","iopub.status.idle":"2023-03-20T21:31:52.235459Z","shell.execute_reply.started":"2023-03-20T21:31:52.197907Z","shell.execute_reply":"2023-03-20T21:31:52.234048Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Mask a image size: {color.BOLD}{color.CYAN}{test_a_mask.size}{color.END}\")\nprint(f\"Mask b image size: {color.BOLD}{color.CYAN}{test_b_mask.size}{color.END}\")","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:31:52.237406Z","iopub.execute_input":"2023-03-20T21:31:52.237764Z","iopub.status.idle":"2023-03-20T21:31:52.245138Z","shell.execute_reply.started":"2023-03-20T21:31:52.237731Z","shell.execute_reply":"2023-03-20T21:31:52.243729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ And plot them</p>","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(dpi=160)\nax.axis('off')\nax.imshow(test_a_mask);","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:31:52.246663Z","iopub.execute_input":"2023-03-20T21:31:52.247579Z","iopub.status.idle":"2023-03-20T21:31:55.331597Z","shell.execute_reply.started":"2023-03-20T21:31:52.247531Z","shell.execute_reply":"2023-03-20T21:31:55.330337Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(dpi=160)\nax.axis('off')\nax.imshow(test_b_mask);","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:31:55.333163Z","iopub.execute_input":"2023-03-20T21:31:55.333537Z","iopub.status.idle":"2023-03-20T21:32:01.293827Z","shell.execute_reply.started":"2023-03-20T21:31:55.333502Z","shell.execute_reply":"2023-03-20T21:32:01.292584Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-family: consolas; font-size: 16px;\">⚪ Let's combine them and you'll see that it's just divided 1st train volume.</p>","metadata":{}},{"cell_type":"code","source":"concatenated_test_mask = get_concat_v(test_a_mask, test_b_mask)","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:32:01.295446Z","iopub.execute_input":"2023-03-20T21:32:01.295785Z","iopub.status.idle":"2023-03-20T21:32:01.773459Z","shell.execute_reply.started":"2023-03-20T21:32:01.295751Z","shell.execute_reply":"2023-03-20T21:32:01.772259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axarr = plt.subplots(2, dpi=160)\n\naxarr[0].imshow(concatenated_test_mask)\naxarr[0].axis('off')\naxarr[0].set_title(\"Concatenated test mask\")\n\naxarr[1].imshow(train_1_mask)\naxarr[1].set_title(\"1st train volume mask\")\naxarr[1].axis('off');","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:32:01.775178Z","iopub.execute_input":"2023-03-20T21:32:01.775788Z","iopub.status.idle":"2023-03-20T21:32:15.255179Z","shell.execute_reply.started":"2023-03-20T21:32:01.775727Z","shell.execute_reply":"2023-03-20T21:32:15.254341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# (⁠ ⁠ꈍ⁠ᴗ⁠ꈍ⁠) WORK STILL IN PROGRESS","metadata":{"execution":{"iopub.status.busy":"2023-03-20T21:32:15.258896Z","iopub.execute_input":"2023-03-20T21:32:15.259768Z","iopub.status.idle":"2023-03-20T21:32:15.264433Z","shell.execute_reply.started":"2023-03-20T21:32:15.25973Z","shell.execute_reply":"2023-03-20T21:32:15.263354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <div style=\"box-shadow: rgba(240, 46, 170, 0.4) -5px 5px inset, rgba(240, 46, 170, 0.3) -10px 10px inset, rgba(240, 46, 170, 0.2) -15px 15px inset, rgba(240, 46, 170, 0.1) -20px 20px inset, rgba(240, 46, 170, 0.05) -25px 25px inset; padding:20px; font-size:30px; font-family: consolas; display:fill; border-radius:15px; color: rgba(240, 46, 170, 0.7)\"> <b> ༼⁠ ⁠つ⁠ ⁠◕⁠‿⁠◕⁠ ⁠༽⁠つ Thank You!</b></div>\n\n<p style=\"font-family:verdana; color:rgb(34, 34, 34); font-family: consolas; font-size: 16px;\"> 💌 Thank you for taking the time to read through my notebook. I hope you found it interesting and informative. If you have any feedback or suggestions for improvement, please don't hesitate to let me know in the comments. <br><br> 🚀 If you liked this notebook, please consider upvoting it so that others can discover it too. Your support means a lot to me, and it helps to motivate me to create more content in the future. <br><br> ❤️ Once again, thank you for your support, and I hope to see you again soon!</p>","metadata":{}}]}