satdetect / ARCHITECTURE.md
coderuday21's picture
Add Delhi zone/village dropdowns, location tracking, and project documentation
92ca429
|
raw
history blame
22.9 kB
# AI Change Detection β€” Architecture & Component Guide
## Overview
AI Change Detection is a full-stack web application that detects, classifies, and visualizes changes between two satellite or aerial images (before and after). It uses multi-signal image processing β€” combining color analysis, structural similarity, texture descriptors, and edge detection β€” to identify ground-level changes such as new buildings, deforestation, road construction, and more.
---
## System Architecture
```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Browser (SPA) β”‚
β”‚ index.html + style.css + app.js β”‚
β”‚ Login / Register / Upload / Results / History β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ REST API (JSON + multipart)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ FastAPI Backend (main.py) β”‚
β”‚ Auth routes Β· Detection route Β· History β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ auth.py β”‚ models.pyβ”‚ detection_engine.py β”‚
β”‚ JWT auth β”‚ ORM β”‚ Image processing pipeline β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚
β”‚ database.py β”‚ SQLite (local/HF Spaces) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```
---
## File-by-File Component Breakdown
### 1. `app/main.py` β€” API Server & Route Definitions
**Role:** The central FastAPI application. Defines all HTTP endpoints, wires together authentication, database, and the detection engine.
**Use cases solved:**
- **User registration & login** (`POST /api/auth/register`, `POST /api/auth/login`) β€” Creates accounts and issues JWT tokens stored as HTTP-only cookies.
- **Session management** (`POST /api/auth/logout`, `GET /api/me`) β€” Clears auth cookies; returns the current authenticated user.
- **Password reset** (`POST /api/auth/reset-password`) β€” Allows users to reset their password by email (no email verification β€” documented limitation).
- **Change detection** (`POST /api/detect`) β€” Accepts two images (before/after) plus configuration options, runs the full detection pipeline, saves the overlay image to disk, stores run metadata in the database, and returns results with a base64-encoded overlay for immediate display.
- **History** (`GET /api/history`, `DELETE /api/history/{id}`) β€” Lists past detection runs for the logged-in user; allows deletion of individual runs and their overlay files.
- **Static file serving** β€” Mounts the `static/` directory for CSS/JS and serves `templates/index.html` as the SPA entry point.
- **Upload size limiting** β€” Rejects images larger than 20 MB to prevent out-of-memory crashes.
---
### 2. `app/auth.py` β€” Authentication & Authorization
**Role:** Handles password hashing, JWT token creation/validation, and user lookup.
**Use cases solved:**
- **Secure password storage** β€” Uses bcrypt via `passlib` to hash passwords before storing them. Plaintext passwords never touch the database.
- **Stateless authentication** β€” Issues HS256 JWT tokens with a 7-day expiry. Tokens are sent as HTTP-only cookies (for browser requests) and also accepted as Bearer tokens in the Authorization header.
- **Multi-source token resolution** β€” `get_current_user()` checks three sources in order: Authorization header, HTTP cookie, then form field. This ensures authentication works for both API clients and browser multipart form submissions.
---
### 3. `app/models.py` β€” Database Models (ORM)
**Role:** Defines the SQLAlchemy ORM models that map to database tables.
**Tables:**
- **`users`** β€” Stores account data: email, bcrypt-hashed password, full name, and creation timestamp. Each user has a one-to-many relationship with detection runs.
- **`detection_runs`** β€” Stores metadata for each detection run: title, method used, pixel statistics (total, changed, percentage), region count, path to the saved overlay image, and a JSON blob of all classified regions with their sub-types and 3D analysis data.
**Use case solved:** Persistent storage of user accounts and detection history so users can revisit past results.
---
### 4. `app/database.py` β€” Database Connection & Session Management
**Role:** Configures the SQLAlchemy engine, session factory, and data directory paths.
**Use cases solved:**
- **Environment-aware storage** β€” Detects Hugging Face Spaces (via `SPACE_ID` env var) and uses a writable home directory; falls back to a local `data/` directory for development.
- **Database portability** β€” Defaults to SQLite for zero-config local development. Supports PostgreSQL via `DATABASE_URL` environment variable for production (with automatic `postgres://` β†’ `postgresql://` rewrite for SQLAlchemy 2.x compatibility).
- **Session lifecycle** β€” The `get_db()` generator provides request-scoped database sessions with automatic cleanup.
---
### 5. `app/detection_engine.py` β€” Image Processing & Classification Pipeline
This is the core of the application. It contains all image analysis algorithms organized into a sequential pipeline.
#### 5a. Pre-processing (`preprocess_image`)
**Use case:** Normalizes input images to a consistent format before analysis.
- Converts grayscale or RGBA images to RGB.
- Downscales images larger than 2000px on any side to prevent memory issues while preserving enough detail for analysis.
#### 5b. Image Registration (`register_images`)
**Use case:** Aligns the "after" image to the "before" image so pixel-level comparison is meaningful.
- Uses ORB feature detection to find matching keypoints between both images.
- Applies Lowe's ratio test to filter spurious matches.
- Computes a RANSAC homography to warp the after image into alignment.
- Rejects bad alignments via inlier ratio threshold and homography determinant check (catches degenerate transforms).
- **Why it matters:** Without alignment, even a slight camera angle difference would cause the entire image to appear "changed."
#### 5c. Radiometric Normalization (`normalize_radiometry`)
**Use case:** Corrects brightness and contrast differences between the two images caused by different lighting conditions, seasons, or sensors.
- Performs histogram matching in LAB color space (perceptually uniform) so the "after" image has the same color distribution as the "before."
- Applies CLAHE (Contrast Limited Adaptive Histogram Equalization) symmetrically to both images to enhance local contrast without introducing bias.
- **Why it matters:** A cloudy day vs. a sunny day would otherwise create massive false-positive "changes" everywhere.
#### 5d. SSIM Change Map (`compute_ssim_change_map`)
**Use case:** Measures structural dissimilarity between corresponding regions of both images.
- Computes per-pixel Structural Similarity Index (SSIM) using Gaussian-weighted windows.
- Outputs a dissimilarity map where 0 = identical and 1 = completely different.
- Clamps variance values to prevent numerical instability from floating-point rounding.
- **Why it matters:** SSIM captures structural patterns (edges, textures) that simple color difference would miss.
#### 5e. Texture Features (`compute_lbp`, `compute_texture_change`)
**Use case:** Detects changes in surface texture (e.g., smooth road vs. rough construction rubble).
- Computes Local Binary Patterns (LBP) β€” a texture descriptor that encodes the relationship between each pixel and its neighbors.
- The absolute difference between before/after LBP maps highlights regions where surface texture changed.
- **Why it matters:** Two regions can have similar colors but very different textures (e.g., grass vs. artificial turf, bare soil vs. concrete).
#### 5f. Edge Change Detection (`compute_edge_change`)
**Use case:** Identifies new or removed structural boundaries.
- Uses Canny edge detection with adaptive thresholds based on median intensity.
- Dilates edges so nearby edges match (tolerates minor misalignment).
- Computes the absolute difference to find edges present in one image but not the other.
- **Why it matters:** New buildings, roads, and demolished structures introduce or remove strong edges.
#### 5g. Detection Methods (4 options)
| Method | Description | Best For |
|--------|-------------|----------|
| **Image Difference** | LAB color space Delta-E difference with Otsu thresholding | Fast, simple comparisons with clear color changes |
| **Feature-Based** | Multi-space (LAB + HSV) feature clustering via KMeans | Subtle, distributed changes across large areas |
| **AI-Based Deep Learning** | Multi-signal fusion (color + SSIM + texture + edge) with entropy-weighted adaptive combination | Highest accuracy; catches both color and structural changes |
| **Hybrid Approach** | Weighted blend of all three methods (20% difference + 30% feature + 50% AI) | Maximum coverage when unsure which method is best |
**Image Difference** (`image_difference_method`):
- Converts to LAB and computes a weighted Delta-E (CIE76) difference per pixel.
- Applies Otsu's automatic threshold to separate "changed" from "unchanged."
- Fast but only catches color changes β€” misses structural changes where color stays similar.
**Feature-Based** (`feature_based_method`):
- Extracts LAB and HSV difference features per pixel.
- Downsamples to 250K pixels for KMeans clustering (4 clusters), then maps labels back to full resolution.
- The cluster with the highest mean feature magnitude is labeled "change."
- Good at finding spatially distributed or gradual changes.
**AI-Based Deep Learning** (`ai_deep_learning_method`):
- Fuses four independent signals: multi-scale LAB color difference, SSIM structural dissimilarity, LBP texture change, and Canny edge change.
- Weights each channel by its information entropy (channels with more discriminative power get higher weight).
- Applies Otsu thresholding followed by bilateral filtering for edge-preserving smoothing.
- The most accurate method β€” captures color, structure, texture, and edge changes simultaneously.
**Hybrid** (`hybrid_method`):
- Runs all three methods and combines their masks with fixed weights.
- AI method gets the most weight (50%) as it's most reliable.
#### 5h. Post-processing (`_clean_mask`)
**Use case:** Cleans up raw change masks to remove noise and fill gaps.
- Morphological closing (fills small gaps inside detected regions).
- Morphological opening (removes small noise speckles).
- Contour-based hole filling (ensures detected regions are solid).
- Sensitivity parameter controls the aggressiveness of gap-filling.
#### 5i. Visualization (`visualize_changes`)
**Use case:** Creates the final overlay image showing detected changes.
- Draws a semi-transparent red overlay on all changed pixels in the "after" image.
- Draws white bounding boxes around each classified region.
- Annotates regions with labels showing sub-type, building stories, and construction stage.
#### 5j. Object Classification (`classify_object_type`, `classify_with_ensemble`)
**Use case:** Determines what kind of ground-level change each detected region represents.
**Feature extraction** (`extract_advanced_features`):
- Extracts 17 features per region: color stats (RGB, HSV, LAB means/stds), vegetation index (NDVI), texture (LBP variance, standard deviation), edges (density, orientation entropy), GLCM-like contrast, shape ratios, and color ratios.
**Transient object filtering** (`_is_transient_object`):
- Filters out non-permanent changes: people, vehicles, animals, shadows.
- Uses area, aspect ratio, edge density, and texture variance thresholds.
**Classification categories:**
| Category | Key Indicators |
|----------|---------------|
| New Construction/Building | Low orientation entropy, compact shape, moderate edges, low saturation |
| Demolition/Clearing | High texture variance, high entropy, bright, low vegetation |
| Vegetation Change | High NDVI, green ratio, medium texture, high saturation |
| Water Body Change | High blue ratio, low texture, smooth surface, specific hue range |
| Road/Pavement Change | Elongated shape, homogeneous color, low saturation, low entropy |
| Bare Land/Soil Change | High red ratio, low NDVI, low texture, earth-tone hue |
**Ensemble voting** (`classify_with_ensemble`):
- Classifies the full region plus 5 sub-regions (quadrants + center).
- Combines votes weighted by confidence.
- Boosts confidence when β‰₯60% of sub-regions agree.
- Only excludes a region as transient if a majority of sub-regions are flagged.
#### 5k. Vegetation Sub-Classification (`classify_vegetation_subtype`)
**Use case:** Provides detailed breakdown of vegetation changes by comparing the before and after region crops.
| Sub-Type | Detection Logic |
|----------|----------------|
| Deforestation/Tree Removal | Before was green (high NDVI), after is bare (NDVI dropped, brightness increased) |
| New Vegetation/Growth | Before was bare, after is green (NDVI increased, saturation up) |
| Crop/Agricultural Change | Regular texture patterns in either image, moderate NDVI shift, large area |
| Vegetation Health Decline | Both images green but NDVI and saturation slightly decreased (browning/drought) |
| Seasonal Variation | Mild color/texture shift, both images still green |
#### 5l. Structural Sub-Classification (`classify_structural_subtype`)
**Use case:** Provides detailed breakdown of structural and road changes by comparing before/after structure presence, edge density, and texture.
| Sub-Type | Detection Logic |
|----------|----------------|
| New Building | No structure before, structure detected after |
| Building Expansion | Structure in both images, but after has higher edge density |
| Renovation/Modification | Structure in both, similar density but different appearance (brightness/saturation shift) |
| Partial Demolition | Structure before, reduced edges after |
| Full Demolition | Structure before, bare/empty after |
| Infrastructure Change | Elongated shape with high geometric regularity |
| New Road/Pavement | No structure before, structure after (for road-type regions) |
| Road Widening | Structure in both, edge density increased |
| Road Resurfacing | Structure in both, similar edges but brightness changed |
| Road Deterioration | Texture increased, edges decreased (surface degradation) |
#### 5m. 3D Building Analysis
**Use case:** Estimates building height/stories and classifies construction stage for building-type regions.
**Shadow-based height estimation** (`estimate_building_height`):
- Detects new shadow pixels adjacent to the building by comparing brightness in the expanded bounding box area between before and after images.
- Measures shadow length as the maximum spatial extent of the shadow cluster.
- Combines shadow ratio, footprint geometry (compact = likely taller), and texture regularity to estimate story count.
- Assumes 3 meters per story.
**Construction stage classification** (`classify_construction_stage`):
| Stage | Visual Indicators |
|-------|------------------|
| Foundation | Low texture, low edges, homogeneous, soil/concrete colors |
| Structural | High edges, geometric regularity (low entropy), high GLCM contrast |
| Under Construction | Mixed materials, irregular texture, medium edge density |
| Complete | Uniform roof, clean edges, low entropy, consistent color |
---
### 6. `templates/index.html` β€” Frontend Structure
**Role:** Single-page application (SPA) with four views managed by JavaScript.
**Views:**
- **Login** β€” Email/password form with password visibility toggle and "Forgot password" link.
- **Register** β€” Account creation form with name, email, and password.
- **Forgot Password** β€” Email + new password form (simplified reset without email verification).
- **Dashboard** β€” The main workspace containing:
- **Upload zone** β€” Drag-and-drop or click-to-browse for before/after images with live previews.
- **Detection options** β€” Method selector, title input, image registration and radiometric normalization toggles.
- **Results panel** β€” Statistics boxes (change %, changed pixels, total pixels, region count), before/after comparison slider, and a detailed regions table with columns for change type, sub-type, confidence, area, stories, height, construction stage, and center coordinates.
- **History** β€” List of past detection runs with view and delete actions.
---
### 7. `static/css/style.css` β€” Visual Design
**Role:** Complete styling for the application using CSS custom properties and a gradient theme.
**Key design decisions:**
- **Color theme** β€” Linear gradient from `#2e33c5` (blue) to `#cf2040` (red) applied to the navbar, footer, buttons, and accent elements. White background for content areas.
- **Sticky navbar** β€” Full-viewport-width gradient bar that stays fixed at the top during scrolling.
- **Mobile responsive** β€” Grid layouts collapse to single columns on screens under 768px. Font sizes, padding, and table layouts adapt to small screens.
- **Glassmorphism dropdown** β€” User account menu uses a gradient background with subtle shadow for the avatar popup.
- **Compare slider** β€” Custom CSS for the before/after image comparison handle with gradient accents.
- **Stat boxes** β€” Responsive font sizing with `clamp()` and compact number formatting to prevent overflow.
---
### 8. `static/js/app.js` β€” Client-Side Logic
**Role:** All browser-side interactivity β€” authentication flow, file uploads, API communication, result rendering, and UI state management.
**Key responsibilities:**
- **Authentication** β€” Login, register, forgot-password form handlers that call the API and store JWT tokens in localStorage. Automatic session check on page load (`init()`).
- **File upload** β€” Drag-and-drop and click-to-browse handlers with live image previews.
- **Detection submission** β€” Builds a FormData payload with images and settings, sends to `/api/detect`, and renders results.
- **Result rendering** β€” Populates stat boxes with compact-formatted numbers, fills the regions table, sets up the before/after comparison slider, and scrolls to results.
- **History management** β€” Loads past runs, renders them with view/delete actions, and handles deletion with an animated confirmation modal.
- **UI utilities** β€” View switching, error/success alerts, avatar dropdown toggle, password visibility toggle, and HTML escaping.
---
### 9. `Dockerfile` β€” Container Configuration
**Role:** Defines the Docker image for deployment on Hugging Face Spaces.
**Key aspects:**
- Base image: `python:3.11-slim` with OpenCV system dependencies (`libgl1`, `libglib2.0-0`, etc.).
- Non-root user (`appuser`) as required by Hugging Face Spaces security policy.
- Runs Gunicorn with a single Uvicorn worker on port 7860 (HF Spaces default) with 120-second timeout for long detection runs.
- Single worker prevents SQLite write-lock race conditions.
---
### 10. `requirements.txt` β€” Python Dependencies
| Package | Purpose |
|---------|---------|
| `fastapi` | Web framework for the REST API |
| `uvicorn` | ASGI server (production via Gunicorn) |
| `gunicorn` | Process manager for production deployment |
| `python-multipart` | Handles multipart/form-data file uploads |
| `sqlalchemy` | ORM for database operations |
| `psycopg2-binary` | PostgreSQL driver (for production databases) |
| `python-jose` | JWT token encoding/decoding |
| `passlib` + `bcrypt` | Password hashing (bcrypt pinned to 4.0.1 for compatibility) |
| `pillow` | Image loading and format conversion |
| `numpy` | Numerical array operations for image processing |
| `opencv-python-headless` | Core image processing (registration, morphology, edge detection, color conversion) |
| `scikit-learn` | KMeans clustering for feature-based detection; StandardScaler for normalization |
| `scipy` | Scientific computing utilities |
---
## Data Flow: End-to-End Detection Run
```
1. User uploads before + after images via browser
β”‚
2. POST /api/detect (multipart form with images + settings)
β”‚
3. Authentication check (JWT from cookie/header/form)
β”‚
4. Pre-processing
β”œβ”€β”€ Convert to RGB, limit to 2000px
β”‚
5. Image Registration (optional)
β”œβ”€β”€ ORB keypoints β†’ ratio test β†’ RANSAC homography β†’ warp
β”‚
6. Radiometric Normalization (optional)
β”œβ”€β”€ LAB histogram matching + symmetric CLAHE
β”‚
7. Change Detection (selected method)
β”œβ”€β”€ Image Difference: LAB Delta-E + Otsu
β”œβ”€β”€ Feature-Based: LAB/HSV features + KMeans clustering
β”œβ”€β”€ AI-Based: Multi-signal fusion (color + SSIM + texture + edge)
└── Hybrid: Weighted combination of all three
β”‚
8. Post-processing
β”œβ”€β”€ Morphological closing/opening + hole filling
β”‚
9. Region Analysis
β”œβ”€β”€ Connected components β†’ bounding boxes
β”œβ”€β”€ Feature extraction (17 features per region)
β”œβ”€β”€ Transient object filtering (remove people, cars, etc.)
β”œβ”€β”€ Primary classification (6 ground-level categories)
β”œβ”€β”€ Ensemble voting (full region + 5 sub-regions)
β”‚
10. Sub-Classification
β”œβ”€β”€ Vegetation: Deforestation / Growth / Crop / Health / Seasonal
β”œβ”€β”€ Structural: New / Expansion / Renovation / Partial Demo / Full Demo / Infrastructure
└── Road: New / Widening / Resurfacing / Deterioration
β”‚
11. 3D Building Analysis (for construction/demolition regions)
β”œβ”€β”€ Shadow detection β†’ height/stories estimation
└── Construction stage classification
β”‚
12. Visualization
β”œβ”€β”€ Red overlay on changed pixels
β”œβ”€β”€ Bounding boxes + annotation labels
β”‚
13. Response
β”œβ”€β”€ Save overlay to disk + database record
└── Return JSON: stats, regions, base64 overlay image
```
---
## Deployment
- **Local development:** Run `uvicorn app.main:app --reload` from the project root. SQLite database is created in `data/satellite_app.db`.
- **Hugging Face Spaces:** Push to the linked HF repo. The Dockerfile builds and deploys automatically. Database is stored at `/home/appuser/data/` (ephemeral β€” resets on container restart).
- **Production with PostgreSQL:** Set `DATABASE_URL` environment variable to a PostgreSQL connection string. Set `SECRET_KEY` to a strong random value.