{"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":"none","dataSources":[{"sourceId":71698,"databundleVersionId":7906362,"sourceType":"competition"}],"dockerImageVersionId":30698,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import cv2\nimport numpy as np\nimport tifffile\nimport SimpleITK as sitk","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-05-27T18:34:07.688368Z","iopub.execute_input":"2024-05-27T18:34:07.688792Z","iopub.status.idle":"2024-05-27T18:34:08.706447Z","shell.execute_reply.started":"2024-05-27T18:34:07.688734Z","shell.execute_reply":"2024-05-27T18:34:08.705192Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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-05-27T17:52:32.334460Z","iopub.execute_input":"2024-05-27T17:52:32.334916Z","iopub.status.idle":"2024-05-27T17:52:32.343940Z","shell.execute_reply.started":"2024-05-27T17:52:32.334869Z","shell.execute_reply":"2024-05-27T17:52:32.342474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport cv2\n\ndef depth_rotation(volume, angle):\n    \"\"\"\n    Apply depth rotation augmentation to a 3D volumetric object.\n    \n    Parameters:\n        volume (np.ndarray): 3D volumetric object represented as a numpy array.\n        angle(float): Angle in degrees for augmentation.\n    \n    Returns:\n        np.ndarray: Augmented 3D volumetric object.\n    \"\"\"\n    # Get dimensions of the volumetric object\n    depth, height, width = volume.shape\n    \n    # Calculate center of the object\n    center = (width // 2, height // 2)\n    \n    # Initialize empty array for augmented volume\n    augmented_volume = np.zeros_like(volume)\n    \n    # Iterate over each slice of the volumetric object\n    for z in range(depth):\n        # Create rotation matrix for the given angle (in degrees)\n        rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0)\n        \n        # Rotate slice around the center\n        rotated_slice = cv2.warpAffine(volume[z], rotation_matrix, (width, height))\n        \n        # Assign the rotated slice to the corresponding place in the augmented volume\n        augmented_volume[z] = rotated_slice\n    \n    return augmented_volume\n","metadata":{"execution":{"iopub.status.busy":"2024-05-27T17:52:32.346880Z","iopub.execute_input":"2024-05-27T17:52:32.347902Z","iopub.status.idle":"2024-05-27T17:52:32.358935Z","shell.execute_reply.started":"2024-05-27T17:52:32.347846Z","shell.execute_reply":"2024-05-27T17:52:32.357410Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport cv2\n\ndef width_rotation(volume, angle):\n    \"\"\"\n    Apply width rotation augmentation to a 3D volumetric object.\n    \n    Parameters:\n        volume (np.ndarray): 3D volumetric object represented as a numpy array.\n        angle (float): Angle in degrees for augmentation.\n    \n    Returns:\n        np.ndarray: Augmented 3D volumetric object.\n    \"\"\"\n    # Get dimensions of the volumetric object\n    depth, height, width = volume.shape\n    \n    # Calculate center of the object\n    center = (height // 2, depth // 2)\n    \n    # Initialize empty array for augmented volume\n    augmented_volume = np.zeros_like(volume)\n    \n    # Iterate over each width slice of the volumetric object\n    for x in range(width):\n        # Create rotation matrix for the given angle (in degrees)\n        rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0)\n        \n        # Rotate slice around the center\n        rotated_slice = cv2.warpAffine(volume[:, :, x], rotation_matrix, (height, depth))\n        \n        # Assign the rotated slice to the corresponding place in the augmented volume\n        augmented_volume[:, :, x] = rotated_slice\n    \n    return augmented_volume\n\ndef height_rotation(volume, angle):\n    \"\"\"\n    Apply height rotation augmentation to a 3D volumetric object.\n    \n    Parameters:\n        volume (np.ndarray): 3D volumetric object represented as a numpy array.\n        angle (float): Angle in degrees for augmentation.\n    \n    Returns:\n        np.ndarray: Augmented 3D volumetric object.\n    \"\"\"\n    # Get dimensions of the volumetric object\n    depth, height, width = volume.shape\n    \n    # Calculate center of the object\n    center = (width // 2, depth // 2)\n    \n    # Initialize empty array for augmented volume\n    augmented_volume = np.zeros_like(volume)\n    \n    # Iterate over each height slice of the volumetric object\n    for y in range(height):\n        # Create rotation matrix for the given angle (in degrees)\n        rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0)\n        \n        # Rotate slice around the center\n        rotated_slice = cv2.warpAffine(volume[:, y, :], rotation_matrix, (width, depth))\n        \n        # Assign the rotated slice to the corresponding place in the augmented volume\n        augmented_volume[:, y, :] = rotated_slice\n    \n    return augmented_volume\n","metadata":{"execution":{"iopub.status.busy":"2024-05-27T17:52:32.360894Z","iopub.execute_input":"2024-05-27T17:52:32.361250Z","iopub.status.idle":"2024-05-27T17:52:32.379094Z","shell.execute_reply.started":"2024-05-27T17:52:32.361222Z","shell.execute_reply":"2024-05-27T17:52:32.377179Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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()","metadata":{"execution":{"iopub.status.busy":"2024-05-27T17:52:32.382398Z","iopub.execute_input":"2024-05-27T17:52:32.382785Z","iopub.status.idle":"2024-05-27T17:52:32.395099Z","shell.execute_reply.started":"2024-05-27T17:52:32.382745Z","shell.execute_reply":"2024-05-27T17:52:32.394043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rotate(volume, d_angle = 0, h_angle = 0, w_angle = 0):\n    aug_vol = depth_rotation(volume, d_angle)\n    aug_vol = width_rotation(aug_vol, h_angle)\n    aug_vol = height_rotation(aug_vol, w_angle)\n    return aug_vol","metadata":{"execution":{"iopub.status.busy":"2024-05-27T17:57:39.727849Z","iopub.execute_input":"2024-05-27T17:57:39.728346Z","iopub.status.idle":"2024-05-27T17:57:39.734919Z","shell.execute_reply.started":"2024-05-27T17:57:39.728309Z","shell.execute_reply":"2024-05-27T17:57:39.733545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load 3D volumetric object from TIF file\n# volume = tifffile.imread(\"/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/AC/bcrick_10_000.tif\")\ntiff_path = \"/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/BC/sfaar_10_001.tif\"\nvolume = tifffile.imread(tiff_path)\nimage = sitk.ReadImage(tiff_path)\nimage_array = sitk.GetArrayFromImage(image)\nprint(volume, image_array.shape)\n","metadata":{"execution":{"iopub.status.busy":"2024-05-27T18:35:16.160016Z","iopub.execute_input":"2024-05-27T18:35:16.160428Z","iopub.status.idle":"2024-05-27T18:35:16.182633Z","shell.execute_reply.started":"2024-05-27T18:35:16.160395Z","shell.execute_reply":"2024-05-27T18:35:16.181570Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Specify azimuth and elevation angles for augmentation\nangles = [0, 90, 180]\n\nfor angle in angles:\n    # Apply azimuth and elevation augmentation\n    augmented_volume = height_rotation(volume, angle)\n    print(augmented_volume.shape)\n\n    # Save augmented volume to TIF file\n    tifffile.imwrite(\"augmented_3d_object.tif\", augmented_volume)\n\n    plot_surface(\"/kaggle/working/augmented_3d_object.tif\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"angles = [(67, 12, 99), (77, 33, 12)]\n\nfor angle in angles:\n    print(angle[0], angle[1], angle[2])\n    # Apply azimuth and elevation augmentation\n    augmented_volume = rotate(volume, angle[0], angle[1], angle[2])\n    print(augmented_volume.shape)\n\n    # Save augmented volume to TIF file\n    tifffile.imwrite(\"augmented_3d_object.tif\", augmented_volume)\n\n    plot_surface(\"/kaggle/working/augmented_3d_object.tif\")","metadata":{"execution":{"iopub.status.busy":"2024-05-27T17:57:45.142579Z","iopub.execute_input":"2024-05-27T17:57:45.143164Z","iopub.status.idle":"2024-05-27T17:57:45.250723Z","shell.execute_reply.started":"2024-05-27T17:57:45.143116Z","shell.execute_reply":"2024-05-27T17:57:45.249077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import numpy as np\n# import scipy.ndimage\n\n# def rotate_volume(volume, azimuth_angle, elevation_angle):\n#     # Convert angles to radians\n#     azimuth_angle_rad = np.radians(azimuth_angle)\n#     elevation_angle_rad = np.radians(elevation_angle)\n    \n#     # Define rotation matrices\n#     azimuth_rotation_matrix = np.array([\n#         [np.cos(azimuth_angle_rad), -np.sin(azimuth_angle_rad), 0],\n#         [np.sin(azimuth_angle_rad), np.cos(azimuth_angle_rad), 0],\n#         [0, 0, 1]\n#     ])\n    \n#     elevation_rotation_matrix = np.array([\n#         [np.cos(elevation_angle_rad), 0, np.sin(elevation_angle_rad)],\n#         [0, 1, 0],\n#         [-np.sin(elevation_angle_rad), 0, np.cos(elevation_angle_rad)]\n#     ])\n    \n#     # Apply rotation matrices\n#     rotated_volume = scipy.ndimage.affine_transform(\n#         volume,\n#         np.linalg.inv(azimuth_rotation_matrix @ elevation_rotation_matrix),\n#         output_shape=volume.shape,\n#         order=1,\n#         mode='constant',\n#         cval=0,\n#         prefilter=False\n#     )\n    \n#     return rotated_volume\n\n# # Example usage\n# # Assuming 'volume_data' is your volumetric data represented as a 3D NumPy array\n# # Azimuth angle range: [-180, 180], Elevation angle range: [-90, 90]\n# azimuth_angle = np.random.uniform(-180, 180)\n# elevation_angle = np.random.uniform(-90, 90)\n\n# volume_data = tifffile.imread(\"/kaggle/input/bugnist2024fgvc/BugNIST_DATA/train/AC/bcrick_10_000.tif\")\n\n# # print(volume_data.shape)\n\n# rotated_volume = rotate_volume(volume_data, azimuth_angle, elevation_angle)\n\n# tifffile.imwrite(\"augmented_3d_object_scipy.tif\", rotated_volume)\n\n# plot_surface(\"/kaggle/working/augmented_3d_object_scipy.tif\")","metadata":{"execution":{"iopub.status.busy":"2024-05-27T17:52:33.054345Z","iopub.execute_input":"2024-05-27T17:52:33.055560Z","iopub.status.idle":"2024-05-27T17:52:33.062420Z","shell.execute_reply.started":"2024-05-27T17:52:33.055494Z","shell.execute_reply":"2024-05-27T17:52:33.061064Z"},"trusted":true},"execution_count":null,"outputs":[]}]}