{"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":"# Vesuvius Challenge GIF Animation\n\nIn this notebook, I will convert 3d x-ray surface volume files of ancient papyrus scrolls to gif files. In this way, by observing gif animations we can better understand this dataset and find more insights to help us create a better Model for this competiton. To make it easy to show gif animations, I will resize surface volume files to 1 / 10 of their origin width and height. What's more, I did some analysis and found that for each TIFF files, RGB channels are identical, alpha channels are not transparent with maximized value 255, I can take only first channel of tiff files. GIF file will also do data compression. Finally these gif files only need about 1 / 300 memory size compared to origin surface volume files with high resolution. With all the improvement I made it still needs nearly 200 MB memory to show all gif animations, I will only show 2 gif animations that has small size.","metadata":{}},{"cell_type":"code","source":"import tensorflow_io as tfio\nimport tensorflow as tf\nimport imageio\nimport numpy as np\nfrom tqdm.notebook import tqdm\nimport os\nfrom IPython.display import Image","metadata":{"execution":{"iopub.status.busy":"2023-04-05T16:26:32.725737Z","iopub.execute_input":"2023-04-05T16:26:32.726374Z","iopub.status.idle":"2023-04-05T16:26:32.820372Z","shell.execute_reply.started":"2023-04-05T16:26:32.726337Z","shell.execute_reply":"2023-04-05T16:26:32.818871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def convert_to_gif(base_path, gif_path=\"animation.gif\", show_animation=False):\n    tensor = []\n    for i in tqdm(range(65)):\n        image_path = f\"{base_path}/surface_volume/{i:02d}.tif\"\n        tif_contents = tf.io.read_file(image_path)\n        tif_tensor = tfio.experimental.image.decode_tiff(tif_contents)[:, :, 0:1]\n        tif_tensor = tf.image.resize(tif_tensor, size=(tif_tensor.shape[0] // 10, tif_tensor.shape[1] // 10))\n        tensor.append(tif_tensor.numpy())\n        \n    ## Add Origin image\n    ir_path = f\"{base_path}/ir.png\"\n    if os.path.exists(ir_path):\n        ir_contents = tf.io.read_file(ir_path)\n        ir = tf.image.decode_png(ir_contents)[:, :, 0:1]\n        ir = tf.image.resize(ir, size=(ir.shape[0] // 10, ir.shape[1] // 10)).numpy()\n        for i in range(10):\n            tensor.append(ir)\n         \n    ## Add Label image\n    label_path = f\"{base_path}/inklabels.png\"\n    if os.path.exists(label_path):\n        inklabels_contents = tf.io.read_file(label_path)\n        inklabels = tf.image.decode_png(inklabels_contents)[:, :, 0:1]\n        inklabels = tf.image.resize(inklabels, size=(inklabels.shape[0] // 10, inklabels.shape[1] // 10)).numpy()\n        for i in range(10):\n            tensor.append(inklabels)\n    tensor = np.array(tensor)\n    estimated_size = (tensor.shape[0] * tensor.shape[1] * tensor.shape[2]) / (1024 ** 2)\n    print(f\"Image size:{estimated_size:.2f} MB\")   \n    print(f\"Image shape:{tensor.shape}\")\n    imageio.mimsave(gif_path, tensor, fps=10)\n    if show_animation:\n        return Image(url=gif_path)  ","metadata":{"execution":{"iopub.status.busy":"2023-04-05T16:27:01.223991Z","iopub.execute_input":"2023-04-05T16:27:01.224412Z","iopub.status.idle":"2023-04-05T16:27:01.237532Z","shell.execute_reply.started":"2023-04-05T16:27:01.224362Z","shell.execute_reply":"2023-04-05T16:27:01.236221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"convert_to_gif(\"/kaggle/input/vesuvius-challenge-ink-detection/train/1\", \"./animation1.gif\")","metadata":{"execution":{"iopub.status.busy":"2023-03-25T09:49:45.798209Z","iopub.execute_input":"2023-03-25T09:49:45.798647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"convert_to_gif(\"/kaggle/input/vesuvius-challenge-ink-detection/train/2\", \"./animation2.gif\")","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"convert_to_gif(\"/kaggle/input/vesuvius-challenge-ink-detection/train/3\", \"./animation3.gif\", show_animation=True)","metadata":{"execution":{"iopub.status.busy":"2023-04-05T16:27:06.575904Z","iopub.execute_input":"2023-04-05T16:27:06.576314Z","iopub.status.idle":"2023-04-05T16:28:23.985847Z","shell.execute_reply.started":"2023-04-05T16:27:06.576277Z","shell.execute_reply":"2023-04-05T16:28:23.984362Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"convert_to_gif(\"/kaggle/input/vesuvius-challenge-ink-detection/test/a\", \"./animationa.gif\", show_animation=True)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"convert_to_gif(\"/kaggle/input/vesuvius-challenge-ink-detection/test/b\", \"./animationb.gif\")","metadata":{},"execution_count":null,"outputs":[]}]}