diff --git a/aggregatepatches.ipynb b/aggregatepatches.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..fc3e8bdd08b8fe941f3f47da2d6a98132afa92be --- /dev/null +++ b/aggregatepatches.ipynb @@ -0,0 +1,463 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reconstruction completed successfully!\n" + ] + } + ], + "source": [ + "import os\n", + "from PIL import Image\n", + "\n", + "# Parameters\n", + "patch_size = 256\n", + "overlap = 128 # 50% overlap\n", + "\n", + "# Directories for patches\n", + "processed_data_dir = r\"/data/nooshin/computationalAg/Nassar 2020/patches/data\"\n", + "processed_mask_dir = r\"/data/nooshin/computationalAg/Nassar 2020/patches/mask\"\n", + "processed_color_mask_dir = r\"/data/nooshin/computationalAg/Nassar 2020/patches/mask_color\"\n", + "\n", + "# Output directories for reconstructed images\n", + "reconstructed_data_dir = r\"/data/nooshin/computationalAg/Nassar 2020/reconstructed/data\"\n", + "reconstructed_mask_dir = r\"/data/nooshin/computationalAg/Nassar 2020/reconstructed/mask\"\n", + "reconstructed_color_mask_dir = r\"/data/nooshin/computationalAg/Nassar 2020/reconstructed/mask_color\"\n", + "\n", + "os.makedirs(reconstructed_data_dir, exist_ok=True)\n", + "os.makedirs(reconstructed_mask_dir, exist_ok=True)\n", + "os.makedirs(reconstructed_color_mask_dir, exist_ok=True)\n", + "\n", + "# Sub-regions to process\n", + "sub_regions_to_process = {\n", + " \"sub0\": (6449, 8642), # Example: original width and height for sub0\n", + " \"sub1\": (3342, 2970),\n", + " \"sub2\": (3527, 4827),\n", + " \"sub3\": (5570, 5755),\n", + " \"sub4\": (6126, 5012),\n", + " \"sub5\": (3342, 14481),\n", + "}\n", + "\n", + "# Function to aggregate patches\n", + "def aggregate_patches(patches, original_width, original_height, patch_size, overlap):\n", + " \"\"\"Reconstructs the original image from patches.\"\"\"\n", + " # Calculate padded width and height\n", + " padded_width = (original_width + patch_size - 1) // patch_size * patch_size\n", + " padded_height = (original_height + patch_size - 1) // patch_size * patch_size\n", + "\n", + " # Create a blank canvas\n", + " reconstructed_image = Image.new(\"RGB\", (padded_width, padded_height))\n", + "\n", + " # Stitch patches onto the canvas\n", + " idx = 0\n", + " for y in range(0, padded_height - patch_size + 1, overlap):\n", + " for x in range(0, padded_width - patch_size + 1, overlap):\n", + " reconstructed_image.paste(patches[idx], (x, y))\n", + " idx += 1\n", + "\n", + " # Crop to original dimensions to remove padding\n", + " return reconstructed_image.crop((0, 0, original_width, original_height))\n", + "\n", + "# Reconstruct images for each sub-region\n", + "for sub_region, (original_width, original_height) in sub_regions_to_process.items():\n", + " # Collect patches\n", + " data_patches = []\n", + " mask_patches = []\n", + " color_mask_patches = []\n", + "\n", + " patch_files = [f for f in os.listdir(processed_data_dir) if f.startswith(sub_region)]\n", + " patch_files.sort() # Ensure patches are loaded in order\n", + "\n", + " for patch_file in patch_files:\n", + " data_patch_path = os.path.join(processed_data_dir, patch_file)\n", + " mask_patch_path = os.path.join(processed_mask_dir, patch_file)\n", + " color_patch_path = os.path.join(processed_color_mask_dir, patch_file)\n", + "\n", + " if os.path.exists(data_patch_path):\n", + " data_patches.append(Image.open(data_patch_path))\n", + " if os.path.exists(mask_patch_path):\n", + " mask_patches.append(Image.open(mask_patch_path))\n", + " if os.path.exists(color_patch_path):\n", + " color_mask_patches.append(Image.open(color_patch_path))\n", + "\n", + " # Reconstruct images\n", + " if data_patches:\n", + " reconstructed_data = aggregate_patches(data_patches, original_width, original_height, patch_size, overlap)\n", + " reconstructed_data.save(os.path.join(reconstructed_data_dir, f\"{sub_region}.png\"))\n", + "\n", + " if mask_patches:\n", + " reconstructed_mask = aggregate_patches(mask_patches, original_width, original_height, patch_size, overlap)\n", + " reconstructed_mask.save(os.path.join(reconstructed_mask_dir, f\"{sub_region}.png\"))\n", + "\n", + " if color_mask_patches:\n", + " reconstructed_color_mask = aggregate_patches(color_mask_patches, original_width, original_height, patch_size, overlap)\n", + " reconstructed_color_mask.save(os.path.join(reconstructed_color_mask_dir, f\"{sub_region}.png\"))\n", + "\n", + "print(\"Reconstruction completed successfully!\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Processing sub0: Found 3468 patches.\n", + "Expected patches: 3468\n", + "Processing sub1: Found 648 patches.\n", + "Expected patches: 648\n", + "Processing sub2: Found 1064 patches.\n", + "Expected patches: 1064\n", + "Processing sub3: Found 1980 patches.\n", + "Expected patches: 1980\n", + "Processing sub4: Found 1920 patches.\n", + "Expected patches: 1920\n", + "Processing sub5: Found 3078 patches.\n", + "Expected patches: 3078\n", + "Reconstruction completed successfully!\n" + ] + } + ], + "source": [ + "import os\n", + "from PIL import Image\n", + "import numpy as np\n", + "\n", + "# Define patch directory and output directory\n", + "patch_dir = r\"/data/nooshin/computationalAg/Nassar 2020/patches/mask\"\n", + "output_dir = r\"/data/nooshin/computationalAg/Nassar 2020/reconstructed\"\n", + "os.makedirs(output_dir, exist_ok=True)\n", + "\n", + "# Parameters\n", + "patch_size = 256\n", + "overlap = 128\n", + "\n", + "def reconstruct_image(patch_files, original_height, original_width, patch_size, overlap):\n", + " \"\"\"\n", + " Reconstruct the original image from patches.\n", + " \"\"\"\n", + " # Initialize empty array for the reconstructed image\n", + " reconstructed_image = np.zeros((original_height, original_width), dtype=np.float64)\n", + " weight_map = np.zeros((original_height, original_width), dtype=np.float64)\n", + "\n", + " # Sort patch files to ensure correct order\n", + " patch_files = sorted(patch_files)\n", + " patch_index = 0\n", + "\n", + " # Iterate through the positions\n", + " for y_start in range(0, original_height, patch_size - overlap):\n", + " for x_start in range(0, original_width, patch_size - overlap):\n", + " # Ensure patch_index does not exceed the number of patch files\n", + " if patch_index >= len(patch_files):\n", + " print(f\"Warning: Patch index {patch_index} exceeds available patches.\")\n", + " continue\n", + "\n", + " # Load the current patch\n", + " patch = np.array(Image.open(patch_files[patch_index]))\n", + " patch_index += 1\n", + "\n", + " # Define the placement area\n", + " y_end = min(y_start + patch_size, original_height)\n", + " x_end = min(x_start + patch_size, original_width)\n", + "\n", + " # Place the patch in the reconstructed image\n", + " reconstructed_image[y_start:y_end, x_start:x_end] += patch[: y_end - y_start, : x_end - x_start]\n", + " weight_map[y_start:y_end, x_start:x_end] += 1\n", + "\n", + " # Normalize by the weight map and cast to uint8\n", + " reconstructed_image = (reconstructed_image / np.maximum(weight_map, 1)).astype(np.uint8)\n", + "\n", + " return Image.fromarray(reconstructed_image)\n", + "\n", + "\n", + "# Sub-regions with dimensions\n", + "sub_regions_to_process = {\n", + " \"sub0\": (6449, 8642), # Replace with actual dimensions\n", + " \"sub1\": (3342, 2970),\n", + " \"sub2\": (3527, 4827),\n", + " \"sub3\": (5570, 5755),\n", + " \"sub4\": (6126, 5012),\n", + " \"sub5\": (3342, 14481),\n", + "}\n", + "\n", + "for sub_region, (original_height, original_width) in sub_regions_to_process.items():\n", + " patch_files = [\n", + " os.path.join(patch_dir, file)\n", + " for file in os.listdir(patch_dir)\n", + " if file.startswith(sub_region)\n", + " ]\n", + "\n", + " # Debugging: Print number of patches and expected patches\n", + " num_patches = len(patch_files)\n", + " print(f\"Processing {sub_region}: Found {num_patches} patches.\")\n", + "\n", + " # Ensure enough patches are present\n", + " step_size = patch_size - overlap\n", + " expected_patches = ((original_height + step_size - 1) // step_size) * (\n", + " (original_width + step_size - 1) // step_size\n", + " )\n", + " print(f\"Expected patches: {expected_patches}\")\n", + "\n", + " if num_patches != expected_patches:\n", + " print(f\"Warning: Mismatch in patches for {sub_region}. Found: {num_patches}, Expected: {expected_patches}\")\n", + "\n", + " # Reconstruct the sub-region image\n", + " reconstructed_image = reconstruct_image(patch_files, original_height, original_width, patch_size, overlap)\n", + "\n", + " # Save the reconstructed image\n", + " reconstructed_image.save(os.path.join(output_dir, f\"{sub_region}_reconstructed.png\"))\n", + "\n", + "print(\"Reconstruction completed successfully!\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Warning: Mismatch in patches for sub0. Found: 3468, Expected: 3350\n", + "Warning: Mismatch in patches for sub1. Found: 648, Expected: 598\n", + "Warning: Mismatch in patches for sub2. Found: 1064, Expected: 999\n", + "Warning: Mismatch in patches for sub3. Found: 1980, Expected: 1892\n", + "Warning: Mismatch in patches for sub4. Found: 1920, Expected: 1833\n", + "Warning: Mismatch in patches for sub5. Found: 3078, Expected: 2938\n", + "Reconstruction of data patches completed successfully!\n" + ] + } + ], + "source": [ + "import os\n", + "from PIL import Image\n", + "import numpy as np\n", + "\n", + "# Define input and output directories\n", + "data_patch_dir = r\"/data/nooshin/computationalAg/Nassar 2020/patches/data\"\n", + "output_dir = r\"/data/nooshin/computationalAg/Nassar 2020/reconstructed\"\n", + "\n", + "# Create output directory if it doesn't exist\n", + "os.makedirs(output_dir, exist_ok=True)\n", + "\n", + "# Patch parameters\n", + "patch_size = 256\n", + "overlap = 128\n", + "step_size = patch_size - overlap\n", + "\n", + "# Sub-region metadata (include original dimensions)\n", + "sub_regions_metadata = {\n", + " \"sub0\": {\"width\": 6449, \"height\": 8642},\n", + " \"sub1\": {\"width\": 3342, \"height\": 2970},\n", + " \"sub2\": {\"width\": 3527, \"height\": 4827},\n", + " \"sub3\": {\"width\": 5570, \"height\": 5755},\n", + " \"sub4\": {\"width\": 6126, \"height\": 5012},\n", + " \"sub5\": {\"width\": 3342, \"height\": 14481},\n", + "}\n", + "\n", + "# Reconstruct an image from its patches\n", + "def reconstruct_data_image(patch_files, original_height, original_width, patch_size, overlap):\n", + " \"\"\"\n", + " Reconstruct an image from its patches with overlap.\n", + " \"\"\"\n", + " # Initialize an empty array for the reconstructed image\n", + " reconstructed_image = np.zeros((original_height, original_width, 3), dtype=np.float32)\n", + " weight_map = np.zeros((original_height, original_width), dtype=np.float32)\n", + "\n", + " patch_index = 0\n", + " step_size = patch_size - overlap\n", + " for y_start in range(0, original_height, step_size):\n", + " for x_start in range(0, original_width, step_size):\n", + " y_end = min(y_start + patch_size, original_height)\n", + " x_end = min(x_start + patch_size, original_width)\n", + "\n", + " # Load the current patch\n", + " if patch_index >= len(patch_files):\n", + " print(\"Warning: Insufficient patches to fully reconstruct.\")\n", + " break\n", + "\n", + " patch = np.array(Image.open(patch_files[patch_index]))\n", + " patch_index += 1\n", + "\n", + " # Place the patch in the reconstructed image\n", + " reconstructed_image[y_start:y_end, x_start:x_end, :] += patch[:y_end - y_start, :x_end - x_start, :]\n", + " weight_map[y_start:y_end, x_start:x_end] += 1\n", + "\n", + " # Normalize by the weight map to handle overlapping areas\n", + " reconstructed_image /= np.maximum(weight_map[:, :, None], 1)\n", + "\n", + " return Image.fromarray(reconstructed_image.astype(np.uint8))\n", + "\n", + "\n", + "# Process each sub-region for reconstruction\n", + "for sub_region, metadata in sub_regions_metadata.items():\n", + " original_width = metadata[\"width\"]\n", + " original_height = metadata[\"height\"]\n", + "\n", + " # Collect all patch files for the sub-region\n", + " patch_files = sorted([\n", + " os.path.join(data_patch_dir, file)\n", + " for file in os.listdir(data_patch_dir)\n", + " if file.startswith(sub_region)\n", + " ])\n", + "\n", + " # Verify the number of patches\n", + " num_patches_horizontally = (original_width - overlap) // step_size + 1\n", + " num_patches_vertically = (original_height - overlap) // step_size + 1\n", + " expected_patches = num_patches_horizontally * num_patches_vertically\n", + "\n", + " if len(patch_files) != expected_patches:\n", + " print(f\"Warning: Mismatch in patches for {sub_region}. Found: {len(patch_files)}, Expected: {expected_patches}\")\n", + "\n", + " # Reconstruct the sub-region image\n", + " reconstructed_image = reconstruct_data_image(patch_files, original_height, original_width, patch_size, overlap)\n", + "\n", + " # Save the reconstructed image\n", + " reconstructed_image.save(os.path.join(output_dir, f\"{sub_region}_reconstructed.png\"))\n", + "\n", + "print(\"Reconstruction of data patches completed successfully!\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Warning: Mismatch in patches for sub0. Found: 3468, Expected: 3350\n", + "Warning: Mismatch in patches for sub1. Found: 648, Expected: 598\n", + "Warning: Mismatch in patches for sub2. Found: 1064, Expected: 999\n", + "Warning: Mismatch in patches for sub3. Found: 1980, Expected: 1892\n", + "Warning: Mismatch in patches for sub4. Found: 1920, Expected: 1833\n", + "Warning: Mismatch in patches for sub5. Found: 3078, Expected: 2938\n", + "Reconstruction of data patches completed successfully!\n" + ] + } + ], + "source": [ + "import os\n", + "from PIL import Image\n", + "import numpy as np\n", + "\n", + "# Define input and output directories\n", + "data_patch_dir = r\"/data/nooshin/computationalAg/Nassar 2020/patches/data\"\n", + "output_dir = r\"/data/nooshin/computationalAg/Nassar 2020/reconstructed/withoutnorm\"\n", + "\n", + "# Create output directory if it doesn't exist\n", + "os.makedirs(output_dir, exist_ok=True)\n", + "\n", + "# Patch parameters\n", + "patch_size = 256\n", + "overlap = 128\n", + "step_size = patch_size - overlap\n", + "\n", + "# Sub-region metadata (include original dimensions)\n", + "sub_regions_metadata = {\n", + " \"sub0\": {\"width\": 6449, \"height\": 8642},\n", + " \"sub1\": {\"width\": 3342, \"height\": 2970},\n", + " \"sub2\": {\"width\": 3527, \"height\": 4827},\n", + " \"sub3\": {\"width\": 5570, \"height\": 5755},\n", + " \"sub4\": {\"width\": 6126, \"height\": 5012},\n", + " \"sub5\": {\"width\": 3342, \"height\": 14481},\n", + "}\n", + "\n", + "def reconstruct_data_image(patch_files, original_height, original_width, patch_size, overlap):\n", + " \"\"\"\n", + " Reconstruct an image from its patches without normalization.\n", + " \"\"\"\n", + " # Initialize an empty array for the reconstructed image\n", + " reconstructed_image = np.zeros((original_height, original_width, 3), dtype=np.uint8)\n", + "\n", + " patch_index = 0\n", + " for y_start in range(0, original_height, step_size):\n", + " for x_start in range(0, original_width, step_size):\n", + " y_end = min(y_start + patch_size, original_height)\n", + " x_end = min(x_start + patch_size, original_width)\n", + "\n", + " # Load the current patch\n", + " if patch_index >= len(patch_files):\n", + " print(\"Warning: Insufficient patches to fully reconstruct.\")\n", + " break\n", + "\n", + " patch = np.array(Image.open(patch_files[patch_index]))\n", + " patch_index += 1\n", + "\n", + " # Place the patch in the reconstructed image\n", + " reconstructed_image[y_start:y_end, x_start:x_end, :] = patch[:y_end - y_start, :x_end - x_start, :]\n", + "\n", + " return Image.fromarray(reconstructed_image)\n", + "\n", + "\n", + "# Process each sub-region for reconstruction\n", + "for sub_region, metadata in sub_regions_metadata.items():\n", + " original_width = metadata[\"width\"]\n", + " original_height = metadata[\"height\"]\n", + "\n", + " # Collect all patch files for the sub-region\n", + " patch_files = sorted([\n", + " os.path.join(data_patch_dir, file)\n", + " for file in os.listdir(data_patch_dir)\n", + " if file.startswith(sub_region)\n", + " ])\n", + "\n", + " # Verify the number of patches\n", + " num_patches_horizontally = (original_width - overlap) // step_size + 1\n", + " num_patches_vertically = (original_height - overlap) // step_size + 1\n", + " expected_patches = num_patches_horizontally * num_patches_vertically\n", + "\n", + " if len(patch_files) != expected_patches:\n", + " print(f\"Warning: Mismatch in patches for {sub_region}. Found: {len(patch_files)}, Expected: {expected_patches}\")\n", + "\n", + " # Reconstruct the sub-region image\n", + " reconstructed_image = reconstruct_data_image(patch_files, original_height, original_width, patch_size, overlap)\n", + "\n", + " # Save the reconstructed image\n", + " reconstructed_image.save(os.path.join(output_dir, f\"{sub_region}_reconstructed.png\"))\n", + "\n", + "print(\"Reconstruction of data patches completed successfully!\")\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}