{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "5d4984fd", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Note: you may need to restart the kernel to use updated packages.\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", "gradio 5.43.1 requires fastapi<1.0,>=0.115.2, but you have fastapi 0.115.0 which is incompatible.\n", "gradio 5.43.1 requires pydantic<2.12,>=2.0, but you have pydantic 2.12.5 which is incompatible.\n", "gradio 5.43.1 requires starlette<1.0,>=0.40.0; sys_platform != \"emscripten\", but you have starlette 0.38.6 which is incompatible.\n" ] } ], "source": [ "%pip install -q torch torchvision pillow opencv-python segmentation-models-pytorch albumentations" ] }, { "cell_type": "code", "execution_count": 2, "id": "8e934e27", "metadata": {}, "outputs": [ { "ename": "OSError", "evalue": "[WinError 126] The specified module could not be found. Error loading \"c:\\Users\\abhay\\anaconda3\\Lib\\site-packages\\torch\\lib\\fbgemm.dll\" or one of its dependencies.", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mOSError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[2], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mtorch\u001b[39;00m\n\u001b[0;32m 2\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mtorchvision\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mtransforms\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mtransforms\u001b[39;00m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mPIL\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Image\n", "File \u001b[1;32mc:\\Users\\abhay\\anaconda3\\Lib\\site-packages\\torch\\__init__.py:148\u001b[0m\n\u001b[0;32m 146\u001b[0m err \u001b[38;5;241m=\u001b[39m ctypes\u001b[38;5;241m.\u001b[39mWinError(ctypes\u001b[38;5;241m.\u001b[39mget_last_error())\n\u001b[0;32m 147\u001b[0m err\u001b[38;5;241m.\u001b[39mstrerror \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m Error loading \u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mdll\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m or one of its dependencies.\u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[1;32m--> 148\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m err\n\u001b[0;32m 150\u001b[0m kernel32\u001b[38;5;241m.\u001b[39mSetErrorMode(prev_error_mode)\n\u001b[0;32m 153\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_preload_cuda_deps\u001b[39m(lib_folder, lib_name):\n", "\u001b[1;31mOSError\u001b[0m: [WinError 126] The specified module could not be found. Error loading \"c:\\Users\\abhay\\anaconda3\\Lib\\site-packages\\torch\\lib\\fbgemm.dll\" or one of its dependencies." ] } ], "source": [ "import torch\n", "import torchvision.transforms as transforms\n", "from PIL import Image\n", "import cv2\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import segmentation_models_pytorch as smp\n", "import albumentations as A\n", "from albumentations.pytorch import ToTensorV2\n", "\n", "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", "print(\"Using device:\", device)" ] }, { "cell_type": "code", "execution_count": null, "id": "f37c3d10", "metadata": {}, "outputs": [], "source": [ "# ── Load trained model ──────────────────────────────────────────────────────\n", "MODEL_PATH = \"best_model.pth\" # path to saved weights\n", "\n", "model = smp.Unet(\n", " encoder_name=\"efficientnet-b3\",\n", " encoder_weights=None, # weights loaded from checkpoint\n", " in_channels=3,\n", " classes=1,\n", " activation=None\n", ")\n", "model.load_state_dict(torch.load(MODEL_PATH, map_location=device))\n", "model.to(device)\n", "model.eval()\n", "print(\"Model loaded successfully.\")" ] }, { "cell_type": "code", "execution_count": null, "id": "c63c88a3", "metadata": {}, "outputs": [], "source": [ "# ── Preprocess & run inference ───────────────────────────────────────────────\n", "IMAGE_PATH = r\"test images\\test 1.png\" # test image\n", "PATCH_SIZE = 256\n", "\n", "transform = A.Compose([\n", " A.Normalize(mean=(0.485, 0.456, 0.406),\n", " std=(0.229, 0.224, 0.225)),\n", " ToTensorV2()\n", "])\n", "\n", "# Load image\n", "img_bgr = cv2.imread(IMAGE_PATH)\n", "assert img_bgr is not None, f\"Could not read image: {IMAGE_PATH}\"\n", "img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)\n", "\n", "h, w = img_rgb.shape[:2]\n", "\n", "# Pad so dimensions are divisible by PATCH_SIZE\n", "pad_h = (PATCH_SIZE - h % PATCH_SIZE) % PATCH_SIZE\n", "pad_w = (PATCH_SIZE - w % PATCH_SIZE) % PATCH_SIZE\n", "img_padded = np.pad(img_rgb, ((0, pad_h), (0, pad_w), (0, 0)), mode='reflect')\n", "H, W = img_padded.shape[:2]\n", "\n", "# Stitch patch predictions into a full mask\n", "full_mask = np.zeros((H, W), dtype=np.float32)\n", "\n", "with torch.no_grad():\n", " for i in range(0, H, PATCH_SIZE):\n", " for j in range(0, W, PATCH_SIZE):\n", " patch = img_padded[i:i+PATCH_SIZE, j:j+PATCH_SIZE]\n", " tensor = transform(image=patch)[\"image\"].unsqueeze(0).to(device)\n", " pred = torch.sigmoid(model(tensor)).squeeze().cpu().numpy()\n", " full_mask[i:i+PATCH_SIZE, j:j+PATCH_SIZE] = pred\n", "\n", "# Crop back to original size\n", "pred_mask = (full_mask[:h, :w] > 0.5).astype(np.uint8)\n", "print(f\"Inference done. Image size: {h}×{w} | Buildings detected: {pred_mask.sum()>0}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "ffbae7d8", "metadata": {}, "outputs": [], "source": [ "# ── Zoning mask & illegal building detection ─────────────────────────────────\n", "# Default zoning: right half is restricted. Modify as needed.\n", "def create_zoning_mask(shape):\n", " \"\"\"Returns a binary mask (1 = restricted zone).\"\"\"\n", " zm = np.zeros(shape, dtype=np.uint8)\n", " zm[:, shape[1] // 2:] = 1\n", " return zm\n", "\n", "def detect_illegal_buildings(building_mask, zoning_mask):\n", " num_labels, labels = cv2.connectedComponents(building_mask)\n", " illegal, legal = [], []\n", " for lbl in range(1, num_labels):\n", " pixels = (labels == lbl)\n", " if (pixels & (zoning_mask == 1)).any():\n", " illegal.append(lbl)\n", " else:\n", " legal.append(lbl)\n", " return illegal, legal, labels\n", "\n", "def overlay_illegal(image_rgb, labels, illegal_buildings):\n", " out = image_rgb.copy()\n", " for lbl in illegal_buildings:\n", " out[labels == lbl] = [255, 0, 0] # red highlight\n", " return out\n", "\n", "zoning_mask = create_zoning_mask(pred_mask.shape)\n", "illegal, legal, labels = detect_illegal_buildings(pred_mask, zoning_mask)\n", "overlay = overlay_illegal(img_rgb, labels, illegal)\n", "\n", "print(f\"Total buildings : {len(illegal) + len(legal)}\")\n", "print(f\"Illegal buildings: {len(illegal)}\")\n", "print(f\"Legal buildings : {len(legal)}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "6692053a", "metadata": {}, "outputs": [], "source": [ "# ── Visualize results ────────────────────────────────────────────────────────\n", "fig, axes = plt.subplots(1, 4, figsize=(20, 5))\n", "\n", "axes[0].imshow(img_rgb)\n", "axes[0].set_title(\"Input Image\")\n", "axes[0].axis(\"off\")\n", "\n", "axes[1].imshow(pred_mask, cmap=\"gray\")\n", "axes[1].set_title(\"Building Mask\")\n", "axes[1].axis(\"off\")\n", "\n", "axes[2].imshow(zoning_mask, cmap=\"gray\")\n", "axes[2].set_title(\"Zoning Mask\\n(white = restricted)\")\n", "axes[2].axis(\"off\")\n", "\n", "axes[3].imshow(overlay)\n", "axes[3].set_title(f\"Illegal Buildings (red)\\nIllegal: {len(illegal)} | Legal: {len(legal)}\")\n", "axes[3].axis(\"off\")\n", "\n", "plt.tight_layout()\n", "plt.show()" ] } ], "metadata": { "kernelspec": { "display_name": ".venv", "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.12.3" } }, "nbformat": 4, "nbformat_minor": 5 }