{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":71698,"databundleVersionId":7906362,"sourceType":"competition"}],"dockerImageVersionId":30674,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# BugNIST challenge:\n\nThe goal of the challenge is to detect and classify objects (bugs) in volumes under domain shift, which contributes to advancing methods for the analysis of volumetric data. Based on volumes containing one bug each, the aim is to train a model that can detect and classify bugs in volumes that contain several bugs mixed with other materials.  \n\nThe training data is divided into 12 subfolders, each containing single-volume scans of a specific class of bug, as indicated by the folder name. Each volume measures 128-by-64-by-64 voxels (z-axis corresponds to the longest axis). The validation data contains 78 volumes of bug mixtures in *.tif* file format. The dimensions are (128, 92, 92) corresponding to the z,x,y-axis.  \n  \n&nbsp;  \nIn this notebook, the bug surface shapes are extracted using the marching cubes algorithm (https://scikit-image.org/docs/stable/auto_examples/edges/plot_marching_cubes.html), and the shapes are displayed as 3D interactive models. ","metadata":{}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd \nimport os\nimport tifffile\n\nimport matplotlib.pyplot as plt\nimport plotly.graph_objects as go\n\nfrom skimage import measure\nfrom skimage import io","metadata":{"execution":{"iopub.status.busy":"2024-03-27T02:45:34.115879Z","iopub.execute_input":"2024-03-27T02:45:34.116669Z","iopub.status.idle":"2024-03-27T02:45:34.121803Z","shell.execute_reply.started":"2024-03-27T02:45:34.116636Z","shell.execute_reply":"2024-03-27T02:45:34.120780Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### First, let's load and display an example volume","metadata":{}},{"cell_type":"code","source":" # display one volume in 3D\nfilepath = \"/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/AC/bcrick_10_000.tif\"\nimg = tifffile.imread(filepath)\n\nfig = plt.figure(figsize = (10, 10))\nax = fig.add_subplot(111, projection = '3d')\n\nax.voxels(img, alpha = 0.4, cmap = 'magma')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-03-27T02:47:34.261781Z","iopub.execute_input":"2024-03-27T02:47:34.262153Z","iopub.status.idle":"2024-03-27T02:48:23.800773Z","shell.execute_reply.started":"2024-03-27T02:47:34.262122Z","shell.execute_reply":"2024-03-27T02:48:23.799828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### We see the volume, but not the bug. Let's write a function to use  marching cubes algorhithm to extract the surface of the bug from the volume, and display it. ","metadata":{}},{"cell_type":"code","source":"def plot_surface(filepath):\n    \"\"\"\n    This function calculates the surfaces (using marching cubes), and displays them in 3D\n    \n    \"\"\"\n    \n    img = tifffile.imread(filepath)\n    \n    # use marching cubes to extract the surface, play around with the level value to see which level yields the best results\n    verts, faces, _, _ = measure.marching_cubes(img, level = 42)\n\n    # plot\n    fig = go.Figure(data = [go.Mesh3d(x = verts[:, 0], y = verts[:, 1], z = verts[:, 2],\n                                     i = faces[:, 0], j = faces[:, 1], k = faces[:, 2],\n                                     opacity = 0.5)])\n\n    fig.update_layout(scene = dict(xaxis = dict(title='X'),\n                                 yaxis = dict(title='Y'),\n                                 zaxis = dict(title='Z')),\n                      margin = dict(l = 0, r  =0, t = 0, b = 0),\n                      title = filepath)\n\n    fig.show()\n\n","metadata":{"execution":{"iopub.status.busy":"2024-03-27T02:50:30.777157Z","iopub.execute_input":"2024-03-27T02:50:30.777879Z","iopub.status.idle":"2024-03-27T02:50:30.785372Z","shell.execute_reply.started":"2024-03-27T02:50:30.777846Z","shell.execute_reply":"2024-03-27T02:50:30.784445Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# filepaths to the .tif files, we use one example for each category of bug. \nfilepaths = ['/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/AC/bcrick_10_000.tif',\n             '/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/BC/sfaar_10_000.tif', \n             '/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/BF/spy_10_000.tif',\n             '/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/BL/boffel_1_000.tif',\n             '/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/BP/guld_1_000.tif',\n             '/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/CF/krol_1_000.tif', \n             '/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/GH/gras_10_000.tif',\n             '/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/MA/maddi_1_000.tif',\n             '/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/ML/mel_10_000.tif',\n             '/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/PP/fluepup_1_000.tif',\n             '/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/SL/soldat_10_000.tif',\n             '/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/WO/bank_1_000.tif']\n\n\n# Plot surface for each filepath\nfor filepath in filepaths:\n    plot_surface(filepath)\n","metadata":{"execution":{"iopub.status.busy":"2024-03-27T02:50:46.284744Z","iopub.execute_input":"2024-03-27T02:50:46.285385Z","iopub.status.idle":"2024-03-27T02:50:46.755597Z","shell.execute_reply.started":"2024-03-27T02:50:46.285352Z","shell.execute_reply":"2024-03-27T02:50:46.754729Z"},"trusted":true},"execution_count":null,"outputs":[]}]}