diff --git a/.claude/launch.json b/.claude/launch.json new file mode 100644 index 0000000000000000000000000000000000000000..06cbfb440fee6b80d435b0f3f177bb5b656dcc2a --- /dev/null +++ b/.claude/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.1", + "configurations": [ + { + "name": "change-detection-dev", + "runtimeExecutable": "venv/Scripts/python.exe", + "runtimeArgs": ["run.py"], + "port": 8000 + } + ] +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..7ff55803d6040c422a719b07db7f87ffd459046b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +__pycache__ +*.pyc +.git +.gitignore +data/satellite_app.db +data/overlays/* +*.md +.env diff --git a/.env.example b/.env.example new file mode 100644 index 0000000000000000000000000000000000000000..9ab3aabf448151586156097495f3a216754262b5 --- /dev/null +++ b/.env.example @@ -0,0 +1,159 @@ +# Copy to .env and uncomment values as needed (optional for local dev). +# python run.py sets APP_MODE=dda automatically. + +# APP_MODE=dda +# REQUIRED for stable login sessions (including in production): without this, +# a random secret is generated per process start, invalidating every existing +# session/cookie on each restart. Generate one with: +# python -c "import secrets; print(secrets.token_hex(32))" +# SECRET_KEY=change-me-to-a-long-random-string + +# Database (default: SQLite in data/satellite_app.db) +# DATABASE_URL=sqlite:///./data/satellite_app.db +# +# MySQL (production for this project): install the driver first +# (pip install pymysql, already in requirements.txt), then set: +# DATABASE_URL=mysql+pymysql://user:password@host:3306/dbname +# URL-encode special characters in the password (e.g. @ -> %40). +# +# PostgreSQL also supported: +# DATABASE_URL=postgresql://user:pass@host/db + +# Local image library folder (default: library_sources/) +# LOCAL_LIBRARY_ROOT=C:/path/to/your/images + +# Image upload limit in MB (default 15360 = 15 GB) +# MAX_GEOTIFF_MB=15360 +# MAX_IMAGE_MB=15360 + +# Automatic mode: identified same-area pairs can be queued on a cadence. +# The queue does NOT start when the app launches. On the Automatic tab, set +# interval (days) and run-at time (IST), then click Start. Manual mode is +# still click-to-run only. The local server must stay running while the +# schedule is armed. Set AUTO_DETECT_ENABLED=0 to hide/disable the feature. +# AUTO_DETECT_ENABLED=1 +# AUTO_DETECT_INTERVAL_DAYS=10 +# AUTO_DETECT_RUN_AT=02:00 + +# Max pixel dimension for detection (lower = less RAM, default 4096 local) +# DETECTION_MAX_SIDE=4096 + +# --- Accuracy controls (all optional; defaults preserve current behavior) --- +# Inference mode: downscaled | fullres_tiled | auto +# auto = fullres_tiled when before/after paths are GeoTIFF (RCA Critical #1) +# DETECTION_INFERENCE_MODE=auto +# Full-res cap (px) in fullres_tiled mode; 0 = native resolution +# DETECTION_FULLRES_MAX_SIDE=8192 +# Native side (px) above which GeoTIFFs stream from disk windows (avoids OOM) +# Default lowered 8192→4096 (RCA Significant #5) +# DETECTION_WINDOWED_THRESHOLD=4096 +# Soft RAM budget (MB) per in-memory array before switching to windowed streaming +# DETECTION_TILE_MEMORY_MB=1536 +# Tile size / overlap for full-res scoring (overlap default 0.35 — RCA #6 seams) +# DETECTION_TILE_SIZE=512 +# DETECTION_TILE_OVERLAP=0.35 +# Skip SIFT registration on GPS-aligned GeoTIFF pairs: true|false|auto (RCA #4) +# DETECTION_SKIP_REGISTRATION_GEOTIFF=auto +# Local Delhi fine-tuned AdaptFormer (v3 frozen = Test F1 0.581 @ thr 0.2). +# Relative paths are resolved against the repo root (not the process CWD). +# ADAPTFORMER_WEIGHTS=models/adaptformer_delhi/v3_frozen +# Val-calibrated DL threshold (alias: DETECTION_DL_THRESHOLD). v3 = 0.2 +# ADAPTFORMER_THRESHOLD=0.2 +# DETECTION_DL_THRESHOLD=0.2 +# Multi-scale DL fusion: off or a comma list, e.g. 0.5,1.0,1.5 +# DETECTION_MULTISCALE=off +# Fusion strategy: smart_union | hysteresis | dl_only +# v3 ablation (runs/v3_app_ablation): dl_only @ 0.2 ≈ Test F1 0.58; +# smart_union/hysteresis collapsed F1 to ~0.04 — prefer dl_only with v3. +# DETECTION_FUSION=dl_only +# TTA: off | hflip | full | auto. Ablation: hflip ≈ same F1, ~2x slower on CPU. +# DETECTION_TTA=off +# Preprocessing toggles +# DETECTION_CLAHE=true +# DETECTION_HIST_MATCH=false +# DETECTION_SKIP_PREBLUR= # auto: on in fullres_tiled mode +# Border pixels zeroed in mask cleanup (auto: 4 fullres / 12 downscaled) +# DETECTION_BORDER_MARGIN= +# Tiles per GPU forward pass (1 = no batching) +# DETECTION_TILE_BATCH=1 +# Save a downsampled probability-map PNG per run for debugging +# DETECTION_SAVE_PROB_MAP=false +# Skip the deep model entirely on tiles that are fully unchanged between before/ +# after (worst-cell LAB distance below this value — biggest single cell diff, +# not an average, so a small real change is never diluted away and missed). +# Big speed win on large images where most of the scene is static background; +# 0/unset = disabled (default). Start conservative (e.g. 3-5). +# DETECTION_SKIP_UNCHANGED_THRESHOLD=0 + +# --- smart_union fusion calibration (Delhi accuracy sprint, Day 4-6) --- +# Base classical-score percentile floor for smart_union fusion. Tuned from +# 0.92 -> 0.90 against real Delhi Sentinel-2 imagery: +53% mean F1 on the +# 16-pair labeled eval set, verified to pass the full synthetic regression +# suite (incl. the mandatory car-FP gate) unchanged. Lower values (0.75-0.85) +# scored even higher on Delhi but were REJECTED — they cause false positives +# on the parked_cars synthetic case. See runs/calibration/best_params.json +# for the full decision record (winning + rejected configs, with reasons). +# DETECTION_CL_Q_BASE=0.90 +# Base DL confidence floor for smart_union fusion (default 0.36). Tested +# down to 0.10 against Delhi imagery — no meaningful effect at full-set scale +# (the pretrained AdaptFormer model's near-zero output on this coarse-GSD, +# out-of-domain imagery isn't a thresholding problem; needs fine-tuning, not +# calibration). Left at default. See runs/calibration/best_params.json. +# DETECTION_DL_FLOOR_BASE=0.15 + +# --- Research-integration channels (KPCAMNet / IR-MAD / SRCDNet / BIT_CD) --- +# KPCA deep features (KPCAMNet): auto (default; drives Feature-Based method), +# on (also adds a channel to the classical score map), off +# DETECTION_KPCA=auto +# Analysis-resolution cap for KPCA feature extraction (CPU bound) +# DETECTION_KPCA_MAX_SIDE=768 +# IR-MAD change statistic: auto (default) | on (adds classical channel) | off +# DETECTION_IRMAD=auto +# Regression radiometric normalization from IR-MAD no-change pixels +# (off by default: reduced F1 on the LEVIR-CD gate; useful for strong +# sensor/illumination mismatch between acquisitions) +# DETECTION_IRMAD_NORM=false +# Resample GeoTIFF pairs to a common (coarser) GSD before detection +# DETECTION_GSD_HARMONIZE=true +# Relative GSD difference that triggers harmonization/preflight warning +# DETECTION_GSD_TOLERANCE=0.15 +# Preflight overlap gate: below this fraction of the after-image footprint, +# a pair is rejected as not suitable for change detection (hard fail) +# DETECTION_MIN_OVERLAP_HARD=0.02 +# Below this fraction, overlap is weak but detection still runs (soft warning) +# DETECTION_MIN_OVERLAP_WARN=0.20 +# Ensemble AdaptFormer with BIT_CD (requires weights, see below; default off) +# DETECTION_ENSEMBLE=off +# BIT_CD LEVIR-CD checkpoint path. Download best_ckpt.pt from the BIT_CD +# repo's release links (https://github.com/justchenhao/BIT_CD) and place it at +# app/cd_models/weights/bit_cd_levir.pth (raw training checkpoints with a +# model_G_state_dict key are accepted as-is). +# BIT_CD_WEIGHTS=app/cd_models/weights/bit_cd_levir.pth + +# Public URL for report links in emails (default http://localhost:8000 locally) +# PUBLIC_BASE_URL=http://localhost:8000 + +# Email notifications (optional). Password reset still uses this backend. +# EMAIL_API_URL=https://emailservice.managemybusinessess.com/api/email/send +# Login SMS OTP: POST ToMobile/Message to SMS_API_URL (default: same host as +# EMAIL_API_URL with /api/sms/send). Or set SMS_PROVIDER=fast2sms + SMS_API_KEY. +# SMS_API_URL= +# SMS_PROVIDER= +# SMS_API_KEY= +# LOGIN_OTP_LOG=1 +# SMTP_HOST=smtp.gmail.com +# SMTP_PORT=587 +# SMTP_USER= +# SMTP_PASS= + +# Hugging Face model cache directory +# HF_HOME=./.hf_cache + +# Department export API (optional — FR-08) +# DEPT_API_URL=https://dept.example.gov/api/changes +# DEPT_API_KEY=your-api-key + +# DDA admin account (optional — UAT / ops) +# DDA_ADMIN_EMAIL=admin@example.com +# DDA_ADMIN_PASSWORD=change-me +# DDA_TRAINING_EXPORT_KEY=secret-key-for-fp-export diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..912333268f3be4ea3635ad9ebcda1dc1edc2fd9c --- /dev/null +++ b/.gitignore @@ -0,0 +1,44 @@ +__pycache__/ +*.pyc +*.pyo +data/satellite_app.db +data/overlays/* +!data/overlays/.gitkeep +data/library_cache/ +# Local library images (too large for git — keep on disk only) +library_sources/**/*.tif +library_sources/**/*.tiff +library_sources/**/*.TIF +library_sources/**/*.TIFF +data/library_sources/**/*.tif +data/library_sources/**/*.tiff +data/library_sources/**/*.TIF +data/library_sources/**/*.TIFF +data/library_sources/**/*.png +data/library_sources/**/*.jpg +data/library_sources/**/*.jpeg +!library_sources/**/.gitkeep +.env +*.egg-info/ +dist/ +build/ +venv/ +# Generated eval/calibration outputs (masks, leaderboards, metrics) +runs/ +# Large fine-tuned weights (export locally via scripts/export_adaptformer_delhi.py) +models/adaptformer_delhi/best/ +models/adaptformer_delhi/*.pt +*.safetensors +# Local label backup from merge conflicts +docs/delhi_eval/labels/_local_backup_*/ +# WHU reference dataset (real-data pipeline test set, not Delhi imagery — see docs/whu_reference/) +data/whu_reference/ +data/large_geotiff_test/ +data/large_geotiff_test.zip +# Third-party CD clones + DSIFN Drive downloads (hundreds of MB) +third_party/ +models/dsifn_proxy/*.pt +# Building-footprint reference data (461MB geojson — exceeds GitHub's 100MB limit) +data/building_footprints/ +# Priyanka synthetic CD triplets (before/after/mask PNGs — local training only) +data/synthetic_cd/ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000000000000000000000000000000000..c0cbb98867dbc8533cd6b4cd53316b51661a6561 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "PowerShell: Launch Current File", + "type": "PowerShell", + "request": "launch", + "script": "${file}", + "args": [] + } + ] +} \ No newline at end of file diff --git a/AI_Change_Detection_Handover.md b/AI_Change_Detection_Handover.md new file mode 100644 index 0000000000000000000000000000000000000000..a22bc5191d8df6afdddc0676b7d70674b7e3eac9 --- /dev/null +++ b/AI_Change_Detection_Handover.md @@ -0,0 +1,280 @@ +# AI Change Detection — Project Handover Document + +**Prepared by:** Development Team +**Date:** February 7, 2026 +**Version:** 2.0 +**Live URL:** [Hugging Face Spaces — AI Change Detection](https://huggingface.co/spaces/coderuday21/satdetect) + +--- + +## 1. Executive Summary + +AI Change Detection is a web-based application that automatically detects, classifies, and visualizes changes between two satellite or aerial images taken at different times. Users upload a "before" and "after" image, and the system identifies what changed on the ground — new buildings, deforestation, road construction, demolitions, water body changes, and more. + +The application provides detailed reports including change statistics, object-level classification with sub-type breakdowns, 3D building analysis (estimated height and construction stage), and an interactive visual overlay highlighting all detected changes in red. + +--- + +## 2. Problem Statement + +Manually comparing satellite imagery to identify ground-level changes is: + +- **Time-consuming** — Analysts spend hours visually scanning large image pairs pixel by pixel. +- **Error-prone** — Human eyes miss subtle changes in vegetation health, gradual construction, or surface texture shifts. +- **Inconsistent** — Different analysts may classify the same change differently. +- **Unscalable** — As the volume of imagery grows (urban planning, environmental monitoring, disaster response), manual review cannot keep pace. + +**AI Change Detection solves this** by automating the entire detection-to-classification pipeline, delivering consistent, quantified results in seconds. + +--- + +## 3. Target Users + +| User Role | How They Use It | +|-----------|----------------| +| Urban planners | Track unauthorized construction, building expansion, and infrastructure changes | +| Environmental analysts | Monitor deforestation, vegetation health decline, and land-use changes | +| Disaster response teams | Assess structural damage after natural disasters by comparing pre/post imagery | +| Agricultural analysts | Detect crop changes, seasonal variation, and land conversion | +| Government agencies | Monitor compliance with zoning and environmental regulations | +| Construction firms | Track construction progress and stage classification over time | + +--- + +## 4. Key Features + +### 4.1 Multi-Method Change Detection + +The system offers four detection methods, each suited to different scenarios: + +| Method | Best For | Speed | +|--------|----------|-------| +| **Image Difference** | Quick scans where changes involve obvious color shifts (e.g., cleared forest) | Fastest | +| **Feature-Based** | Subtle, distributed changes across large areas (e.g., gradual land-use shift) | Fast | +| **AI-Based Deep Learning** | Highest accuracy — combines color, structure, texture, and edge analysis | Moderate | +| **Hybrid Approach** | Maximum coverage when unsure which type of changes to expect | Slowest | + +Users select the method per run depending on their accuracy vs. speed needs. + +### 4.2 Intelligent Pre-Processing + +Before comparing images, the system can automatically: + +- **Align images** (Image Registration) — Corrects for camera angle, zoom, and position differences between the two photos so the comparison is pixel-accurate. +- **Normalize lighting** (Radiometric Normalization) — Corrects for brightness/contrast differences caused by weather, time of day, or different cameras, preventing false positives from lighting alone. + +Both options are user-toggleable per run. + +### 4.3 Ground-Level Change Classification + +Every detected change region is automatically classified into one of six categories: + +| Category | What It Detects | +|----------|----------------| +| **New Construction / Building** | New structures appearing on previously empty land | +| **Demolition / Clearing** | Structures or vegetation that have been removed | +| **Vegetation Change** | Any change in plant cover — forests, crops, parks | +| **Water Body Change** | New, expanded, or reduced water features | +| **Road / Pavement Change** | New roads, widened paths, resurfaced areas | +| **Bare Land / Soil Change** | Exposed earth, grading, land preparation | + +**Transient objects are automatically filtered out** — people, vehicles, animals, and shadows are excluded so only permanent ground-level changes are reported. + +### 4.4 Detailed Sub-Classification + +Each primary category is further broken down into specific sub-types by comparing the "before" and "after" regions: + +**Vegetation Sub-Types:** + +| Sub-Type | What It Means | +|----------|---------------| +| Deforestation / Tree Removal | Green area has been cleared — trees or vegetation removed | +| New Vegetation / Growth | Previously bare area now has plant cover | +| Crop / Agricultural Change | Farmland has changed crop type or land use pattern | +| Vegetation Health Decline | Plants are browning or showing signs of drought/disease | +| Seasonal Variation | Normal seasonal color shift, both periods still green | + +**Structural Sub-Types:** + +| Sub-Type | What It Means | +|----------|---------------| +| New Building | Structure appeared where none existed before | +| Building Expansion | Existing building has been extended or enlarged | +| Renovation / Modification | Building exists in both images but has changed appearance | +| Partial Demolition | Part of a structure has been removed | +| Full Demolition | Entire structure has been removed, area is now bare | +| Infrastructure Change | Non-building structures (bridges, towers, utilities) | + +**Road Sub-Types:** + +| Sub-Type | What It Means | +|----------|---------------| +| New Road / Pavement | Road appeared where none existed before | +| Road Widening | Existing road has been expanded | +| Road Resurfacing | Road surface has been repaved (different appearance, same width) | +| Road Deterioration | Road surface has degraded | + +### 4.5 3D Building Analysis + +For regions classified as buildings or construction, the system provides: + +- **Estimated Stories** — Number of floors, calculated from shadow analysis and building footprint geometry. +- **Estimated Height** — Height in meters (based on 3m per story). +- **Construction Stage** — Classified as Foundation, Structural, Under Construction, or Complete based on visual features. + +### 4.6 Interactive Visual Output + +- **Red overlay** — All detected changes are highlighted in red on the "after" image. +- **Before/After slider** — A draggable comparison slider lets users visually inspect what changed by sliding between the original and the annotated result. +- **Annotated bounding boxes** — Each detected region gets a labeled bounding box showing its sub-type, stories, and construction stage. + +### 4.7 User Accounts & History + +- **Secure login system** — Email/password registration with encrypted password storage. +- **Detection history** — All past runs are saved with their results, overlay images, and metadata. Users can revisit or delete previous runs. +- **Password reset** — Users can reset their password from the login screen. + +### 4.8 Responsive Design + +The application is fully functional on desktop browsers and mobile devices, with an optimized layout for smaller screens. + +--- + +## 5. Technology Stack + +| Layer | Technology | Purpose | +|-------|-----------|---------| +| **Frontend** | HTML, CSS, JavaScript (Vanilla) | Single-page application — no framework dependencies | +| **Backend** | Python, FastAPI | REST API server handling authentication and detection | +| **Image Processing** | OpenCV, NumPy, Scikit-learn, Pillow | Core algorithms for detection, classification, and visualization | +| **Database** | SQLite (local), PostgreSQL (production-ready) | User accounts and detection run history | +| **Authentication** | JWT tokens, bcrypt password hashing | Secure stateless authentication | +| **Deployment** | Docker, Hugging Face Spaces | Containerized cloud deployment | + +--- + +## 6. Application Screens + +### Login / Registration +- Clean login form with email and password +- Password visibility toggle (eye icon) +- "Forgot password" option +- Toggle between sign-in and registration + +### Dashboard (Main Screen) +- **Upload Section** — Two drag-and-drop zones for before and after images with live previews +- **Configuration** — Method selector, run title, and optional pre-processing toggles +- **Results Section** — Appears after running detection: + - Statistics bar: change percentage, changed pixels, total pixels, region count + - Before/after comparison slider + - Detailed table of all detected regions with type, sub-type, confidence, area, building data, and coordinates +- **History Section** — List of all past runs with option to view overlay or delete + +--- + +## 7. Output Data Per Detection Run + +Each run produces the following data: + +| Field | Description | +|-------|-------------| +| Change Percentage | Proportion of the image area that changed | +| Changed Pixels | Total number of pixels detected as changed | +| Total Pixels | Total image area in pixels | +| Regions Count | Number of distinct change regions identified | +| **Per Region:** | | +| Change Type | Primary category (Construction, Vegetation, etc.) | +| Sub-Type | Detailed sub-classification (New Building, Deforestation, etc.) | +| Confidence | Classification confidence score (0–100%) | +| Area | Region size in pixels | +| Estimated Stories | Number of building floors (building regions only) | +| Estimated Height | Height in meters (building regions only) | +| Construction Stage | Foundation / Structural / Under Construction / Complete (building regions only) | +| Center Coordinates | Location of the region center in the image | +| Overlay Image | Annotated image with red highlights and bounding boxes | + +--- + +## 8. Deployment & Access + +### Current Deployment +- **Platform:** Hugging Face Spaces (free tier) +- **URL:** https://huggingface.co/spaces/coderuday21/satdetect +- **Container:** Docker-based, auto-deploys on code push +- **Database:** SQLite (ephemeral — resets when the container restarts) + +### Limitations of Current Deployment +| Limitation | Impact | Mitigation Path | +|-----------|--------|-----------------| +| Ephemeral database | User accounts and history are lost on container restart | Migrate to external PostgreSQL database | +| No email verification on password reset | Anyone who knows an email can reset the password | Implement token-based email verification flow | +| Single-worker server | Cannot handle high concurrent load | Scale to multiple workers with PostgreSQL | +| Free-tier resources | Limited CPU/memory, images capped at 2000px and 20MB | Upgrade to paid hosting for larger images | + +### For Production Deployment +To move from the current demo to a production environment, the following would be needed: +1. External PostgreSQL database for persistent storage +2. Email service integration (SendGrid, AWS SES) for password reset verification +3. Paid cloud hosting (AWS, GCP, or Azure) for better performance +4. HTTPS with a custom domain +5. Environment-based secret key management + +--- + +## 9. How Accuracy Works + +The system does **not** use a pre-trained deep learning model (no neural network). Instead, it uses a **multi-signal fusion approach** — combining multiple independent analysis methods that each measure a different aspect of change: + +1. **Color difference** — Measures how much the color changed at each pixel (in perceptually uniform color space). +2. **Structural similarity** — Measures whether the patterns and structures at each pixel changed. +3. **Texture analysis** — Measures whether the surface texture changed (smooth → rough, etc.). +4. **Edge detection** — Measures whether structural boundaries appeared or disappeared. + +These four signals are weighted by their discriminative power and fused into a single change map. This approach is: + +- **Transparent** — Every decision can be traced to specific visual features (no "black box"). +- **Deterministic** — The same inputs always produce the same outputs. +- **No training data required** — Works on any satellite/aerial imagery without needing labeled datasets. + +**Trade-off:** A trained deep learning model (e.g., U-Net, Siamese network) would likely achieve higher accuracy on specific datasets, but would require labeled training data and GPU resources. The current approach provides good accuracy out-of-the-box for general-purpose change detection. + +--- + +## 10. Future Enhancement Opportunities + +| Enhancement | Business Value | +|-------------|---------------| +| Deep learning model integration (U-Net / Siamese CNN) | Significantly higher detection accuracy on trained domains | +| Batch processing / multi-image upload | Analyze time-series imagery for trend analysis | +| GIS integration (GeoTIFF, coordinate mapping) | Pin changes to real-world geographic coordinates | +| PDF/Excel report export | Downloadable reports for stakeholder distribution | +| Webhook / API integration | Automate detection as part of larger monitoring pipelines | +| Role-based access (admin, analyst, viewer) | Team collaboration with permission controls | +| Notification system | Alert stakeholders when significant changes are detected | +| Cloud-optimized image storage | Handle very large satellite tiles (10,000+ pixels) | + +--- + +## 11. Repository Structure + +``` +change_detection_webapp/ +├── app/ +│ ├── main.py → API server and route definitions +│ ├── auth.py → Authentication (JWT, password hashing) +│ ├── models.py → Database table definitions +│ ├── database.py → Database connection setup +│ └── detection_engine.py → All image processing and classification algorithms +├── templates/ +│ └── index.html → Frontend page structure +├── static/ +│ ├── css/style.css → All visual styling +│ └── js/app.js → Client-side logic +├── Dockerfile → Container build instructions +├── requirements.txt → Python package dependencies +└── ARCHITECTURE.md → Technical architecture reference (for developers) +``` + +--- + +*For technical implementation details, refer to `ARCHITECTURE.md` in the project repository.* diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 0000000000000000000000000000000000000000..1e1af5c5b1ab772f7f8178a9008c6a601a985f62 --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,387 @@ +# 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) / MySQL │ +└─────────────────────┴───────────────────────────┘ +``` + +--- + +## 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. Production uses MySQL via `DATABASE_URL` (`mysql+pymysql://...`); PostgreSQL is also supported (with automatic `postgres://` → `postgresql://` rewrite for SQLAlchemy 2.x compatibility). `pool_pre_ping` is enabled for any non-SQLite backend so stale/dropped remote connections are transparently recycled. +- **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 | +| `pymysql` | MySQL driver (production database) | +| `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. Uses `DATABASE_URL` if set (MySQL for this project), otherwise SQLite in `data/satellite_app.db`. +- **Hugging Face Spaces:** Push to the linked HF repo. The Dockerfile builds and deploys automatically. Falls back to SQLite at `/home/appuser/data/` (ephemeral — resets on container restart) unless `DATABASE_URL` is set. +- **Production with MySQL:** Set `DATABASE_URL` to a `mysql+pymysql://user:pass@host:3306/dbname` connection string (`pymysql` driver is in `requirements.txt`). Set `SECRET_KEY` to a strong random value. On Render, set `DATABASE_URL` manually in the dashboard (Environment tab) — it's `sync: false` in `render.yaml`, not committed to git. +- **Production with PostgreSQL** (also supported): same pattern with a `postgresql://` URL — requires adding `psycopg2-binary` to `requirements.txt` first (not installed by default). diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000000000000000000000000000000000000..cdcffa961458eaf2c20c7af730ebc4ff6fbb3e7e --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,227 @@ +# Deployment — Two Hugging Face Spaces + +This project uses **two separate Hugging Face Spaces** so the live app stays stable while you build changes for a new client. + +| Environment | Space | Git remote | Branch | URL | +|-------------|-------|------------|--------|-----| +| **Production** (current clients) | `coderuday21/satdetect` | `hf` | `production` | https://huggingface.co/spaces/coderuday21/satdetect | +| **Development** (new client work) | `coderuday21/satdetect-dev` | `hf-dev` | `master` | https://huggingface.co/spaces/coderuday21/satdetect-dev | + +--- + +## One-time setup: create the dev Space + +1. Open **https://huggingface.co/new-space** +2. Set: + - **Owner:** `coderuday21` + - **Space name:** `satdetect-dev` + - **SDK:** Docker + - **Visibility:** Public (or Private if you prefer) +3. Click **Create Space**. + +Then add the dev remote (once): + +```powershell +cd change_detection_webapp +git remote add hf-dev https://huggingface.co/spaces/coderuday21/satdetect-dev +``` + +If `hf-dev` already exists, update it: + +```powershell +git remote set-url hf-dev https://huggingface.co/spaces/coderuday21/satdetect-dev +``` + +Push the current development code to the new Space: + +```powershell +git push hf-dev master:main --force +``` + +> **First push only:** Hugging Face creates a starter README commit when you create the Space. Use `--force` once to replace it with your app. Later pushes can omit `--force`. + +Or run the helper script: + +```powershell +.\scripts\push_hf_dev.ps1 +``` + +--- + +## Branch strategy + +``` +production ──► hf (satdetect) — live app (no login; direct to detection) +master ──► hf-dev (satdetect-dev) — new client experiments and upcoming changes +``` + +- **`production`** — tracks the stable live release (currently same as `master`, no login). +- **`master`** — active development; push to the dev Space for testing before promoting to production. + +Work on new client features on `master`. When ready for the live app, merge into `production` and push to `hf`. + +--- + +## Deploy commands + +### Production (live app — no login) + +```powershell +git checkout production +git merge master +git push hf production:main +``` + +Or push `master` directly to production: + +```powershell +git push hf master:main +``` + +Helper: + +```powershell +.\scripts\push_hf_production.ps1 +``` + +### Development (new client Space) + +After every change you want on the dev Space: + +```powershell +git checkout master +git push hf-dev master:main +``` + +Helper: + +```powershell +.\scripts\push_hf_dev.ps1 +``` + +--- + +## GitHub mirror + +**Repo:** https://github.com/Uday-at-Vedang/DDA.ChangeDetection +**Default branch on GitHub:** `main` + +Push the full app from local `master`: + +```powershell +git push origin master:main +``` + +Push the production branch too: + +```powershell +git push origin production:main-production +``` + +Set upstream (once, after first push): + +```powershell +git branch --set-upstream-to=origin/main master +``` + +--- + +## Environment variables (both Spaces) + +Set these in each Space’s **Settings → Repository secrets / Variables** if needed: + +| Variable | Purpose | +|----------|---------| +| `APP_MODE` | Set to `dda` on **satdetect-dev** only (enables Vedangsoft library UI) | +| `STORAGE_ROOT` | Tree library root directory (default: `data/library_sources/`) | +| `LOCAL_LIBRARY_ROOT` | Alias for storage root override | +| `MAX_GEOTIFF_MB` | Library GeoTIFF upload cap (default **5120** = 5 GB on dev) | +| `MAX_IMAGE_MB` | PNG/JPEG library cap (default 50 MB) | +| `SECRET_KEY` | Optional legacy JWT setting (login disabled) | +| `DATABASE_URL` | MySQL (production) instead of SQLite — `mysql+pymysql://user:pass@host:3306/db`; PostgreSQL also supported | +| `SMTP_USER` / `SMTP_PASS` | Email notifications via Gmail SMTP | +| `EMAIL_API_URL` | Custom email API (default in code) | +| `DEPT_API_URL` / `DEPT_API_KEY` | Departmental submit API (optional) | +| `DDA_ADMIN_EMAIL` / `DDA_ADMIN_PASSWORD` | Seed admin user on dev (role: admin) | +| `DDA_TRAINING_EXPORT_KEY` | Header `X-DDA-Training-Key` for false-positive export | + +### Detection accuracy controls (optional, dev-first) + +All default to the previous behavior, so leaving them unset changes nothing. + +| Variable | Purpose | +|----------|---------| +| `DETECTION_MAX_SIDE` | Downscaled-path pixel cap (default 4096 local / 2048 hosted) | +| `DETECTION_INFERENCE_MODE` | `downscaled` (default) or `fullres_tiled` (native detail) | +| `DETECTION_FULLRES_MAX_SIDE` | Full-res cap in fullres mode; 0 = native (default 8192) | +| `DETECTION_WINDOWED_THRESHOLD` | Native side above which GeoTIFFs stream from disk windows (default 8192) | +| `DETECTION_TILE_MEMORY_MB` | RAM budget per array before switching to windowed streaming (default 1536) | +| `DETECTION_TILE_SIZE` / `DETECTION_TILE_OVERLAP` | Full-res tile geometry (default 512 / 0.25) | +| `DETECTION_MULTISCALE` | `off` or scale list e.g. `0.5,1.0,1.5` (max-fused for recall) | +| `DETECTION_FUSION` | `smart_union` (default) or `hysteresis` | +| `DETECTION_CLAHE` / `DETECTION_HIST_MATCH` | Preprocessing toggles (CLAHE on, hist-match off) | +| `DETECTION_SKIP_PREBLUR` | Skip denoise (auto-on in fullres mode) | +| `DETECTION_BORDER_MARGIN` | Mask border zeroing (auto: 4 fullres / 12 downscaled) | +| `DETECTION_TILE_BATCH` | Tiles per GPU forward pass (default 1) | +| `DETECTION_SAVE_PROB_MAP` | Save a per-run probability PNG for debugging (default off) | + +Dev Space can omit `SECRET_KEY` (login is disabled on both Spaces). + +--- + +## Tree library layout (unlimited depth) + +Images are organized in a **configurable tree** (zone → area → year → image type, or any depth): + +```text +library_sources/ + central_delhi/ + karol_bagh/ + 2025/ + Images/ + satellite.tif +``` + +- **API:** `GET /api/dda/tree`, `POST /api/dda/tree/nodes`, upload via `POST /api/dda/tree/nodes/{id}/images/upload` +- **UI:** Recursive tree sidebar on Library and Change Detection tabs; **Manage** (admin) for create/rename/move/delete +- **Storage:** Slug-based disk paths; display names in `node_path` +- **Local folders:** Create folders under `library_sources/{zone}/{area}/…/` and drop files into `Images/`; click **Refresh** (or restart app) to sync disk → DB via `POST /api/dda/local/rescan` +- **Legacy:** Flat `library_sources/YEAR/` files auto-migrate to `Unassigned/Legacy/{year}/Images/` on startup + +--- + +## UAT checklist (satdetect-dev) + +Run before promoting any Vedangsoft feature to production: + +1. **Health** — `GET /health` returns `status: ok`, `appMode: dda`, `dda.libraryImages` ≥ 0 +2. **Tree library** — Create zone → area → year nodes (admin); upload GeoTIFF to node; tree + grid show breadcrumb +3. **Compare** — Tree sidebar filters image grid; T1/T2 dropdowns list all images; Run Detection completes with plausible lat/lng on georeferenced TIFFs +4. **Viewer** — Slider / T1 / T2 / Overlay modes; click region to locate +5. **Review** — Confirm and False Positive; Export confirmed CSV; Submit confirmed +6. **Reports** — PDF download; `/dda/reports/{id}` page; email link (if SMTP configured) +7. **Session isolation** — Two browsers see separate history (per-session cookie) +8. **Admin** — `GET /api/dda/admin/status` (analyst+); stale job reconcile after restart +9. **Training export** — Mark false positives → `GET /api/dda/training/export` (admin or export key) +10. **Security** — Path traversal blocked (`../` in library path); upload size limit enforced + +Sign-off: DDA stakeholder approves sample runs on dev Space before any push to `satdetect` production. + +--- + +## Quick reference + +```powershell +# Daily work (new client) +git checkout master +# ... edit code ... +git add . +git commit -m "Your message" +git push hf-dev master:main + +# Update live app (only when ready) +git checkout production +git merge master # or cherry-pick specific commits +git push hf production:main +git checkout master +``` diff --git a/DEV_SETUP.md b/DEV_SETUP.md new file mode 100644 index 0000000000000000000000000000000000000000..87c87fe1b9b85435bc0eaeb65aea424e31b4defe --- /dev/null +++ b/DEV_SETUP.md @@ -0,0 +1,284 @@ +# Vedangsoft Change Detection — Local Dev Setup + +This repo is the **development branch** of the satellite change-detection app (DDA SOW). It runs the full dev UI: image library, GeoTIFF comparison, async jobs, reports, and PDF export. + +**Live dev Space (reference):** https://coderuday21-satdetect-dev.hf.space +**Production Space (do not deploy this repo there without review):** https://coderuday21-satdetect.hf.space + +--- + +## 1. Prerequisites + +| Requirement | Notes | +|-------------|--------| +| **Python 3.10 – 3.12** | Tested with **3.11** (same as Docker). 3.13+ may have wheel issues for some packages. | +| **Git** | Clone this repository. | +| **~4 GB free disk** | PyTorch (CPU), transformers model cache, and sample GeoTIFFs. | +| **RAM 8 GB+ recommended** | Detection loads AdaptFormer; large GeoTIFFs use more RAM. | + +### Windows (GeoTIFF / rasterio) + +`rasterio` needs GDAL. Easiest options: + +**Option A — pip wheels (try first):** +```powershell +pip install -r requirements.txt +python -c "import rasterio; print('rasterio OK', rasterio.__version__)" +``` + +**Option B — if rasterio fails, use Conda for GDAL then pip for the rest:** +```powershell +conda create -n dda-cd python=3.11 -y +conda activate dda-cd +conda install -c conda-forge gdal rasterio -y +pip install -r requirements.txt +``` + +**Option C — OSGeo4W:** Install [OSGeo4W](https://trac.osgeo.org/osgeo4w/) and ensure `gdal` is on `PATH` before `pip install rasterio`. + +### macOS / Linux + +```bash +# macOS (Homebrew) +brew install gdal + +# Ubuntu/Debian +sudo apt-get install gdal-bin libgdal-dev +export GDAL_CONFIG=/usr/bin/gdal-config +pip install -r requirements.txt +``` + +--- + +## 2. Clone and install + +```bash +git clone https://github.com/Uday-at-Vedang/Change-Detection-DEV.git +cd Change-Detection-DEV +python -m venv venv +``` + +**Windows:** +```powershell +venv\Scripts\activate +pip install -U pip setuptools wheel +pip install -r requirements.txt +``` + +**macOS / Linux:** +```bash +source venv/bin/activate +pip install -U pip setuptools wheel +pip install -r requirements.txt +``` + +> First `pip install` may take 10–20 minutes (PyTorch + transformers). + +--- + +## 3. Environment variables (optional) + +Copy the template and edit if needed: + +```bash +cp .env.example .env +``` + +| Variable | Default (local) | Purpose | +|----------|----------------|---------| +| `APP_MODE` | `dda` (set by `run.py`) | `dda` = full dev UI; `legacy` = simple upload UI | +| `SECRET_KEY` | random fallback | Set in production | +| `DATABASE_URL` | SQLite in `data/` | Set to MySQL (`mysql+pymysql://...`) for production; PostgreSQL also supported | +| `LOCAL_LIBRARY_ROOT` | `library_sources/` | Custom image library folder | +| `MAX_GEOTIFF_MB` | `5120` | Max GeoTIFF upload size (MB) | +| `DETECTION_MAX_SIDE` | `4096` local / `2048` HF | Max pixel side for detection | +| `EMAIL_API_URL` | manager API | Email notifications | +| `SMTP_USER` / `SMTP_PASS` | — | Use SMTP if API URL empty | +| `PUBLIC_BASE_URL` | `http://localhost:8000` | Report links in emails | + +Local dev does **not** require email config unless you test notifications. + +--- + +## 4. Image library (local GeoTIFFs) + +Place images under year folders (not committed to git — too large): + +``` +library_sources/ + 2024/ + site_a.tif + 2025/ + site_b.tif + 2026/ +``` + +See `library_sources/README.md` for details. Supported: `.tif`, `.tiff`, `.png`, `.jpg`. + +After adding files, start the app and click **Image Library → Refresh**. + +--- + +## 5. Run the app + +```bash +python run.py +``` + +Opens **http://127.0.0.1:8000** with the Vedangsoft dev UI (Home, Image Library, Change Detection, and Reports pages). + +Alternative (with auto-reload during development): + +```bash +set APP_MODE=dda # Windows +export APP_MODE=dda # macOS/Linux +uvicorn app.main:app --reload --host 127.0.0.1 --port 8000 +``` + +### First run + +- Creates `data/satellite_app.db` and `data/overlays/`. +- Downloads **AdaptFormer** model from Hugging Face on first detection (~500 MB). Requires internet. +- Seed data: Delhi zone/village hierarchy is loaded automatically in DDA mode. + +### Health check + +```bash +curl http://127.0.0.1:8000/health +``` + +Expected: `"appMode": "dda"`, `"status": "ok"`. + +--- + +## 6. Using the dev UI + +1. **Image Library** — scan year folders, upload GeoTIFFs (up to 5 GB), view hierarchy. +2. **Change Detection** — pick Base (T1) and Comparison (T2), run detection (async jobs on HF; sync locally). +3. **Reports** — history, PDF download, browser report at `/dda/reports/{id}`. +4. **Bell icon** — in-app notifications for completed jobs. +5. **Review (FR-08)** — Confirm / False Positive per region, export confirmed CSV, submit to dept API (`DEPT_API_URL`). +6. **Session users** — Each browser gets isolated history via `dda_session_id` cookie (no login required). +7. **Admin** — Optional `DDA_ADMIN_EMAIL` / `DDA_ADMIN_PASSWORD` for admin role; `GET /api/dda/admin/status`. + +--- + +## 7. Project layout (Vedangsoft) + +``` +app/ + main.py # FastAPI entry + detection_engine.py # Change detection pipeline + dda/ # DDA modules (library, jobs, reports, geo) +static/js/dda/ # Dev frontend +templates/ + partials/navbar_dda.html, result_modal_dda.html # shared includes + home_dda.html, library_dda.html, detect_dda.html, reports_dda.html +docs/IMPLEMENTATION_PLAN_DDA.md # SOW phase plan +``` + +--- + +## 8. Troubleshooting + +| Issue | Fix | +|-------|-----| +| `ImportError: rasterio` | Install GDAL (see §1), then reinstall rasterio | +| Simple upload UI instead of the Vedangsoft dev UI | Set `APP_MODE=dda` or use `python run.py` | +| Library empty | Add `.tif` files under `library_sources/YYYY/` and click Refresh | +| Detection slow / OOM | Lower `DETECTION_MAX_SIDE=2048` or use smaller images | +| Model download fails | Check internet; set `HF_HOME` to a writable folder | +| Port 8000 in use | Change `PORT` in `run.py` or use `--port 8001` with uvicorn | + +--- + +## 9. Deploy to Hugging Face dev Space (maintainers) + +See `DEPLOYMENT.md`. Dev Space remote: + +```powershell +git remote add hf-dev https://huggingface.co/spaces/coderuday21/satdetect-dev +git push hf-dev master:main +``` + +Do **not** push `master` to production `satdetect` without explicit sign-off. + +--- + +## 10. Key API endpoints (Vedangsoft) + +| Method | Path | Description | +|--------|------|-------------| +| GET | `/health` | Health + app mode | +| GET | `/api/dda/local/images` | Library image list | +| POST | `/api/dda/jobs` | Queue async detection | +| GET | `/api/dda/reports/{id}/pdf` | PDF export | +| GET | `/dda/reports/{id}` | Browser report page | +| GET | `/api/history` | Detection run history | + +--- + +## 11. Delhi evaluation workflow (accuracy calibration) + +Full end-to-end reproduction of the Delhi accuracy-improvement sprint (see `Accuracy_Improvement_Plan.xlsx`). Every command below runs from the repo root. + +### 11.1 Curate real Delhi pairs + +`library_sources/` ships empty (real imagery isn't committed — see `library_sources/README.md`). Two ways to populate it: + +```bash +# Free, openly-licensed Sentinel-2 imagery (10m GSD — good for large land-use +# change, vegetation, water bodies; not reliable for individual buildings/roads) +python scripts/build_delhi_pairs_sentinel2.py --count 32 + +# Or, once you have your own imagery (DDA-provided GeoTIFFs, drone, etc.) in +# library_sources//: +python scripts/build_delhi_manifest.py --scan # see what's available +python scripts/build_delhi_manifest.py --add --before library_sources/2024/x.tif \ + --after library_sources/2026/x.tif --zone "..." --change-types building,road +python scripts/build_delhi_manifest.py --validate # check coverage (>=30 pairs, all 4 change types) +``` + +### 11.2 Label ground-truth masks + +```bash +# Semi-automated candidate generation (CVA + adaptive threshold + blob filter) +python scripts/generate_candidate_masks.py + +# Review docs/delhi_eval/labels/candidates/previews/*.png (before | after | mask | overlay), +# then promote or reject each one: +python scripts/accept_candidate_mask.py --pair-id delhi_0001 +python scripts/accept_candidate_mask.py --reject --pair-id delhi_0002 +``` +Candidate masks are a starting point, not ground truth — always eyeball the preview before promoting. See `docs/delhi_eval/manifest.json` notes per pair for known limitations found during review (e.g. diffuse changes needing hand-drawn rough polygons instead). + +### 11.3 Run the detection harness against the labeled set + +```bash +python scripts/compare_methods.py --manifest docs/delhi_eval/manifest.json \ + --methods "AI-Based Deep Learning,Feature-Based,Hybrid Approach" --sensitivities 0.5 \ + --out runs/delhi_baseline +``` +Reports per-pair IoU/F1/precision/recall for every labeled pair (unlabeled pairs run without ground-truth scoring). + +### 11.4 Grid-search calibration + +```bash +python scripts/grid_search_calibration.py --methods "AI-Based Deep Learning" \ + --sensitivities 0.5 --cl-qs 0.80,0.85,0.90,0.92 --manifest docs/delhi_eval/manifest.json +``` +Sweeps `sensitivity` / `DETECTION_FUSION` / `DETECTION_DL_FLOOR_BASE` / `DETECTION_CL_Q_BASE` and ranks configs by mean F1 in `runs/calibration/leaderboard.csv`. **Always verify a promising config against the synthetic regression suite (11.5) before promoting it** — the highest Delhi F1 isn't automatically safe; see `runs/calibration/best_params.json` for a real example of a config that won on Delhi but broke a regression gate. + +### 11.5 Synthetic regression gate (mandatory before promoting any default) + +```bash +python scripts/validate_detection.py --benchmark --method "AI-Based Deep Learning" \ + --sensitivity 0.5 --out runs/synthetic_check +``` +Four cases: `inserted_buildings`, `brightness_only`, `misaligned_change`, `parked_cars` (the mandatory car/transient-FP guard — must stay F1=1.0). Pass `--method`/`--sensitivity` to test any calibrated config; set the relevant `DETECTION_*` env vars first to test non-default fusion parameters. + +**Known gap:** the plan also references a LEVIR-CD regression case and a kappa statistic (Phase 0, marked "Complete"). Neither actually exists in this codebase as of the Day 5/6 calibration pass — only the 4 synthetic cases above are real, runnable gates. Treat any claim of "LEVIR-CD gate passing" as unverified until that harness is actually built. + +### 11.6 Promote a verified config to production defaults + +Once a config passes 11.5 unchanged, hardcode it as the new default in `app/detection_config.py` (e.g. `get_cl_q_base()`'s fallback value), then re-run 11.3 and 11.5 **with no env var set** to confirm the new default behaves identically to what was verified. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..387db1c69c69173e8044790dc4d8411ff46281f0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,55 @@ +FROM python:3.11-slim + +# Ensure build logs flush immediately (helps when HF shows “BUILDING” with no output) +ENV PYTHONUNBUFFERED=1 + +# System dependencies for OpenCV and image processing +RUN apt-get update && apt-get install -y --no-install-recommends \ + libgl1 \ + libglib2.0-0 \ + libsm6 \ + libxext6 \ + libxrender1 \ + gdal-bin \ + libgdal-dev \ + && rm -rf /var/lib/apt/lists/* + +# Create non-root user (required by Hugging Face Spaces) +RUN useradd -m -u 1000 appuser + +WORKDIR /app + +# Build-time info + cache-bust: +# Changing APP_BUILD forces Docker to re-run subsequent layers (including pip install). +ARG APP_BUILD=38 +ENV MAX_GEOTIFF_MB=15360 +ENV APP_BUILD=${APP_BUILD} +ENV GDAL_CONFIG=/usr/bin/gdal-config +RUN echo "Docker build start: APP_BUILD=${APP_BUILD}" && python -V + +# Install Python dependencies +COPY requirements.txt . +RUN pip install --no-cache-dir --disable-pip-version-check --default-timeout=300 -U pip setuptools wheel +RUN pip install --no-cache-dir --disable-pip-version-check --default-timeout=300 --prefer-binary -r requirements.txt -v + +# Pre-download the AdaptFormer model so cold starts are instant +ENV HF_HOME=/app/.hf_cache +RUN python -c "from transformers import AutoImageProcessor, AutoModel; \ + AutoImageProcessor.from_pretrained('deepang/adaptformer-LEVIR-CD', cache_dir='/app/.hf_cache', trust_remote_code=True); \ + AutoModel.from_pretrained('deepang/adaptformer-LEVIR-CD', cache_dir='/app/.hf_cache', trust_remote_code=True); \ + print('Model pre-downloaded successfully')" + +# Copy application code +COPY . . + +# Create data directories with correct permissions +RUN mkdir -p data/overlays && chown -R appuser:appuser /app + +USER appuser + +# HF Spaces generally uses 7860, but binding to $PORT is safer. +ENV PORT=7860 +EXPOSE 7860 + +# Bind to runtime PORT so health checks always reach the server. +CMD ["sh", "-c", "uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-7860} --log-level info --timeout-keep-alive 600"] diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8c89e7500724573a20c157b3289da834b13675cd --- /dev/null +++ b/README.md @@ -0,0 +1,133 @@ +--- +title: Vedangsoft Change Detection (Dev) +emoji: 🛰️ +colorFrom: gray +colorTo: green +sdk: docker +app_port: 7860 +--- + +# Vedangsoft Change Detection — Development + +Satellite / drone **change detection** web app for the DDA Scope of Work. This repository tracks **dev-only** features (`APP_MODE=dda`): image library, GeoTIFF comparison, async jobs, geo-referenced regions, reports, and PDF export. + +> **New to the project?** Start with **[DEV_SETUP.md](DEV_SETUP.md)** — step-by-step install and run instructions for your machine. + +| Environment | URL | +|-------------|-----| +| **Dev Space (HF)** | https://coderuday21-satdetect-dev.hf.space | +| **Local** | http://127.0.0.1:8000 after `python run.py` | + +## Quick start + +```bash +git clone https://github.com/Uday-at-Vedang/Change-Detection-DEV.git +cd Change-Detection-DEV +python -m venv venv +venv\Scripts\activate # Windows +# source venv/bin/activate # macOS/Linux +pip install -r requirements.txt +python run.py +``` + +1. Add GeoTIFFs to `library_sources/2025/` (or other year folders). +2. Open **Image Library → Refresh**. +3. Use **Change Detection** to compare T1 vs T2. + +Full details: **[DEV_SETUP.md](DEV_SETUP.md)** · SOW plan: **`docs/IMPLEMENTATION_PLAN_DDA.md`** · HF deploy: **`DEPLOYMENT.md`** + +--- + +# Satellite Change Detection — Standalone Web App + +Standalone web application for satellite image change detection with **database storage** and a **clean, modern UI**. Opens directly on the detection page — no sign-in required. + +## Features + +- **Vedangsoft dev UI** — Home, Library, Detection, Reports pages (when `APP_MODE=dda`) +- **Direct access** — upload and run detection immediately (no login) +- **Database** — SQLite by default; MySQL in production via `DATABASE_URL` (PostgreSQL also supported); stores detection runs +- **Change detection** — AdaptFormer deep learning + hybrid / difference methods +- **GeoTIFF library** — Year-folder library, 5 GB upload limit, lat/lng on regions +- **Object classification** — Changed regions labeled (Water, Vegetation, Building, Road, etc.) +- **History & reports** — Past runs, PDF export, email notifications +- **Region polygons** — Engine footprints (`polygon` / `polygonGeo`) in the result overlay + viewer SVG; export via `GET /api/dda/reports/{id}/export.geojson` (bbox/Point fallback for older runs). Verify: `python scripts/verify_polygon_mvp.py` + +## Setup (legacy summary) + +See **[DEV_SETUP.md](DEV_SETUP.md)** for the complete guide. Minimal steps: + +1. **Create a virtual environment (recommended)** + + ```bash + cd change_detection_webapp + python -m venv venv + source venv/bin/activate # Windows: venv\Scripts\activate + ``` + +2. **Install dependencies** + + ```bash + pip install -r requirements.txt + ``` + +3. **Run the app** + + ```bash + python run.py + # or: uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 + ``` + +4. Open **http://localhost:8000** in your browser. + +## First run + +- The DB (SQLite locally, or the configured `DATABASE_URL`) and `data/` (overlay images) are created automatically on first use. +- **DDA mode:** place images in `library_sources/YYYY/` and use the Library tab. +- **Legacy mode:** upload Before/After PNGs on the detection page. +- AdaptFormer model downloads from Hugging Face on first detection (~500 MB). + +## Configuration + +- **DDA mode:** `APP_MODE=dda` (default when using `run.py`). Copy `.env.example` → `.env` for optional overrides. +- **Database**: set `DATABASE_URL` to use another DB — MySQL (production for this project): `mysql+pymysql://user:pass@host:3306/db`, or PostgreSQL: `postgresql://user:pass@host/db`. Otherwise SQLite under `data/satellite_app.db` is used. +- **JWT**: set `SECRET_KEY` via env in production. +- **Email**: `EMAIL_API_URL` or `SMTP_USER` / `SMTP_PASS` — see `.env.example`. + +## Project layout + +``` +change_detection_webapp/ +├── app/ +│ ├── main.py # FastAPI app, routes +│ ├── dda/ # DDA dev modules (library, jobs, reports) +│ └── detection_engine.py # Change detection pipeline +├── static/js/dda/ # DDA frontend +├── templates/ +│ ├── partials/navbar_dda.html, result_modal_dda.html # shared includes +│ ├── home_dda.html, library_dda.html, detect_dda.html, +│ │ reports_dda.html # Vedangsoft dev UI pages +│ ├── login_dda.html, report_dda.html +│ └── index.html # legacy (APP_MODE=legacy) UI +├── library_sources/ # Local GeoTIFF library (year folders) +├── docs/IMPLEMENTATION_PLAN_DDA.md +├── DEV_SETUP.md # Colleague setup guide +├── requirements.txt +└── run.py # Local launcher (APP_MODE=dda) +``` + +## API (Vedangsoft highlights) + +- `GET /health` — app mode and version +- `GET /api/dda/local/images` — library image list +- `POST /api/dda/jobs` — queue async detection +- `GET /api/dda/reports/{id}/pdf` — PDF download +- `GET /dda/reports/{id}` — browser report page +- `POST /api/detect` — legacy multipart upload detect +- `GET /api/history` — detection run history + +## Hugging Face: Space stuck on “Restarting” + +1. Open your Space → **Settings** → under **Build**, click **Clear build cache** → Save. Then trigger a rebuild (push a commit or click **Restart**). +2. Check **Logs** (Build logs + App logs) for Python errors or “Killed” (out of memory). +3. In **Settings** → **Hardware**, try a slightly larger CPU/memory if available. diff --git a/WORKFLOW.md b/WORKFLOW.md new file mode 100644 index 0000000000000000000000000000000000000000..cfed10464c7b789ddbc03850e34bb6c63a7e1a12 --- /dev/null +++ b/WORKFLOW.md @@ -0,0 +1,371 @@ +# Satellite Change Detection — Project Workflow Guide + +A complete walkthrough of how this project is structured, how a detection request +flows through the system, and how to run it locally. Read this top-to-bottom to get +familiar with the codebase. + +--- + +## 1. What this project does + +This is a **standalone web application for satellite image change detection**. A user +uploads two images of the same place taken at different times (a **"before"** and an +**"after"**), and the app: + +1. Aligns the two images (registration). +2. Normalizes their colors/brightness. +3. Runs change detection (classical computer vision + a pretrained deep-learning model). +4. Finds and classifies the changed regions (new buildings, vegetation change, water, etc.). +5. Draws the changes on an overlay image and shows statistics. +6. Saves the run to a per-user history (with login/accounts). + +It is deployed as a Docker container on **Hugging Face Spaces**, but runs the same way locally. + +--- + +## 2. Tech stack + +| Layer | Technology | +|-------|-----------| +| Backend API | **FastAPI** (Python), served by **uvicorn** | +| Image processing | **OpenCV**, **NumPy**, **scikit-learn** | +| Deep learning | **PyTorch** + **Hugging Face Transformers** (AdaptFormer model) | +| Database | **SQLAlchemy** ORM over **SQLite** (default) or **PostgreSQL** | +| Auth | **JWT** tokens (python-jose) + **bcrypt** password hashing (passlib) | +| Frontend | Plain **HTML + CSS + vanilla JavaScript** (single-page app) | +| Email | HTTP email API or SMTP (optional notifications) | +| Deployment | **Docker** → Hugging Face Spaces | + +There is **no build step** for the frontend — it's static files served directly. + +--- + +## 3. Repository structure + +``` +change_detection_webapp/ +├── app/ +│ ├── main.py # FastAPI app + all HTTP routes (entry point) +│ ├── detection_engine.py # CORE: preprocessing, registration, detection, classification +│ ├── model_inference.py # AdaptFormer deep-learning model loader + tiled inference +│ ├── cd_models/ # Extra DL building blocks +│ │ ├── change_model.py # Siamese U-Net architecture (optional, needs weights) +│ │ └── model_utils.py # tiling, multi-scale, confidence-map helpers +│ ├── auth.py # JWT create/verify, password hashing, current-user lookup +│ ├── database.py # SQLAlchemy engine/session, DATA_DIR resolution +│ ├── models.py # ORM models: User, DetectionRun +│ └── notifier.py # Email notification sending +├── static/ +│ ├── css/style.css # All styles +│ └── js/app.js # All frontend logic (auth, upload, render results) +├── templates/ +│ └── index.html # Single-page UI shell +├── scripts/ +│ └── validate_detection.py # Sanity checks for the detection pipeline +├── data/ # Created at runtime: SQLite DB + overlay/thumbnail images +├── requirements.txt # Python dependencies +├── Dockerfile # Container build (also pre-downloads the model) +├── README.md # Short setup notes (Hugging Face front-matter on top) +└── WORKFLOW.md # This document +``` + +> Note: the `app/cd_models/` folder is named `cd_models` (not `models`) on purpose — +> `app/models.py` already exists for the database models, and a folder named `models` +> would shadow it and break imports. + +--- + +## 4. High-level architecture + +```mermaid +flowchart LR + browser["Browser (index.html + app.js)"] -->|"HTTP / JSON"| api["FastAPI (main.py)"] + api --> auth["auth.py (JWT)"] + api --> engine["detection_engine.py"] + engine --> model["model_inference.py (AdaptFormer)"] + api --> db["(SQLite / Postgres via models.py)"] + api --> notifier["notifier.py (email)"] + api --> files["data/overlays (result images)"] +``` + +- The **browser** talks only to FastAPI over JSON + multipart form uploads. +- **main.py** is the only place that defines routes; it delegates the heavy lifting to + `detection_engine.run_detection(...)`. +- Results (overlay PNGs, thumbnails) are written to `data/overlays/` and referenced by URL. +- Run metadata is stored in the database. + +--- + +## 5. The detection pipeline (the core workflow) + +This is the most important part to understand. Everything happens inside +`run_detection()` in [`app/detection_engine.py`](app/detection_engine.py). + +```mermaid +flowchart TD + start["run_detection(before, after, method, sensitivity, ...)"] --> pre["preprocess_image() -- RGB, resize, denoise"] + pre --> reg{"registration enabled?"} + reg -->|yes| align["register_images() -- SIFT/ORB + ECC align, returns quality metrics"] + reg -->|no| norm + align --> norm{"normalization enabled?"} + norm -->|yes| radio["normalize_radiometry() -- LAB color match + CLAHE"] + norm -->|no| method + radio --> method["pick detection method"] + method --> ai["AI-Based Deep Learning (default)"] + method --> diff["Image Difference"] + method --> feat["Feature-Based (KMeans)"] + method --> hyb["Hybrid / Hybrid AI"] + ai --> fuse["AdaptFormer score + classical score -> confidence-gated fusion"] + diff --> mask + feat --> mask + hyb --> fuse + fuse --> mask["binary change mask"] + mask --> regions["analyze_change_regions() -- connected components + classify + NMS"] + regions --> viz["visualize_changes() -- draw boxes on overlay"] + viz --> out["return mask, overlay, stats, regions"] +``` + +### Step by step + +1. **Preprocess** (`preprocess_image`): convert to RGB, cap the size (default 1600px max + side) for speed, apply light Gaussian blur (and a bilateral filter only when the image + is noisy) to reduce sensor noise without destroying edges. + +2. **Register / align** (`register_images`): the two screenshots rarely line up perfectly. + - First tries **SIFT + FLANN** feature matching → homography. + - Falls back to **ORB** features if SIFT is weak. + - Refines with **ECC** (sub-pixel alignment). + - Falls back to **multi-scale ECC** if feature matching fails entirely. + - Returns an `(img1, img2_aligned, registration_ok, reg_meta)` tuple. `registration_ok` + and the quality metrics (inlier ratio, NCC) are surfaced to the UI as an + **alignment warning** when the alignment is weak — important for Google Earth + screenshots that differ in zoom/crop. + +3. **Radiometric normalization** (`normalize_radiometry`): match the "after" image's color + statistics to the "before" image in LAB space, plus symmetric CLAHE on the lightness + channel, so lighting/season differences don't look like real change. + +4. **Detection method** (selected by the `method` argument): + - **AI-Based Deep Learning** (default): runs the **AdaptFormer** model + (`model_inference.predict_change_mask`) to get a per-pixel change probability map, + computes a **classical** multi-channel score map (color ΔE, SSIM, texture/LBP, edges, + change-vector analysis), then **fuses** them with `fuse_dl_and_classical()`. Fusion is + **confidence-gated** (not a blind union): the model drives structural changes, the + classical signal + Excess-Green index supports vegetation changes. + - **Image Difference**: LAB ΔE difference with adaptive (Otsu/MAD) thresholding. + - **Feature-Based**: KMeans clustering of per-pixel difference features. + - **Hybrid / Hybrid AI**: weighted combinations of the above. + +5. **Clean the mask** (`_clean_mask`): morphological open/close, hole filling, remove tiny + or thin (shadow-like) components. + +6. **Find & classify regions** (`analyze_change_regions`): connected-components on the mask + → bounding boxes → `classify_object_type()` assigns a label (New Construction/Building, + Vegetation Change, Water Body Change, Road/Pavement, Bare Land, etc.) with a confidence + and severity → **non-maximum suppression** removes overlapping/duplicate boxes. + +7. **Visualize** (`visualize_changes`): draw a subtle tint on changed pixels and numbered, + color-coded boxes for the top regions. + +8. **Return** `change_mask, result_image, stats, change_regions` back to `main.py`. + +### Sensitivity + +The `detection_sensitivity` slider (0–1, default 0.5) shifts thresholds: higher = detect +more (more recall, more false positives), lower = stricter (fewer, higher-confidence +detections). + +--- + +## 6. The deep-learning model + +- File: [`app/model_inference.py`](app/model_inference.py) +- Model: **`deepang/adaptformer-LEVIR-CD`** (a change-detection transformer trained on the + LEVIR-CD building dataset), pulled from the Hugging Face Hub. +- It is **pre-downloaded at Docker build time** (see the Dockerfile) so cold starts are fast, + and **preloaded on app startup** so the first request isn't slow. +- Inference is **tile-based**: the image is split into overlapping 256×256 tiles (the model's + native size), each tile is predicted, and the results are stitched back with a + raised-cosine blend to avoid visible seams. +- If PyTorch/Transformers aren't installed or the model fails to load, the engine **falls + back gracefully** to the classical-only path — the app still works. + +`app/cd_models/change_model.py` contains a from-scratch **Siamese U-Net** as an alternative +DL backbone. It only activates if a trained weights file exists at +`app/cd_models/weights/siamese_unet_cd.pt` (none is shipped), so it's currently dormant. + +--- + +## 7. Request lifecycle (auth + detect) + +```mermaid +sequenceDiagram + participant U as Browser + participant A as FastAPI (main.py) + participant Au as auth.py + participant E as detection_engine.py + participant D as Database + + U->>A: POST /api/auth/login {email, password} + A->>Au: verify_password + create_access_token + Au-->>A: JWT + A-->>U: token (also set as httpOnly cookie) + + U->>A: POST /api/detect (before, after, method, ...) + token + A->>Au: resolve user from token/cookie + A->>E: run_detection(...) + E-->>A: mask, overlay, stats, regions + A->>D: save DetectionRun row + A->>A: write overlay + thumbnails to data/overlays/ + A-->>U: JSON {statistics, regions, overlayBase64Png, ...} + U->>U: app.js renders overlay + regions table +``` + +--- + +## 8. Data model + +Defined in [`app/models.py`](app/models.py): + +- **User**: `id, email (unique), hashed_password, full_name, created_at` +- **DetectionRun**: `id, user_id, title, method, total_pixels, changed_pixels, + change_percentage, regions_count, overlay_path, before/after thumbnail paths, zone, + village, regions_json (serialized regions), created_at` + +The database file lives at `data/satellite_app.db` (SQLite) and is created automatically on +first run. Set `DATABASE_URL` to use PostgreSQL instead. + +--- + +## 9. API reference + +All routes are in [`app/main.py`](app/main.py). + +| Method & path | Purpose | +|---------------|---------| +| `POST /api/auth/register` | Create account `{email, password, full_name}` → token | +| `POST /api/auth/login` | Log in `{email, password}` → token (+ cookie) | +| `POST /api/auth/logout` | Clear auth cookie | +| `POST /api/auth/reset-password` | Set a new password `{email, new_password}` | +| `GET /api/me` | Current user (requires auth) | +| `POST /api/detect` | **Main endpoint.** multipart: `before`, `after` files + `method`, `title`, `zone`, `village`, `enable_registration`, `enable_normalization`, `detection_sensitivity`, `min_region_area`, `notify_email` | +| `GET /api/history` | List the current user's past runs | +| `POST /api/notify/test` | Send a test email | +| `GET /api/overlay/` | Serve a saved overlay / thumbnail image | +| `GET /health` | Lightweight health check (no DB) | +| `GET /` | Serves the single-page UI | + +`POST /api/detect` returns: `statistics` (pixels, change %, threshold debug, alignment +warning), `regions` (list with type/confidence/severity/bbox), and the overlay as base64 PNG. + +--- + +## 10. Frontend + +- [`templates/index.html`](templates/index.html) is the shell: login/register forms, the + upload form, history table, and the result modal. +- [`static/js/app.js`](static/js/app.js) handles everything client-side: calling the API, + storing the token, submitting the detect form, and rendering results (the before/after + slider, the regions table, alignment warnings, and fusion stats). +- [`static/css/style.css`](static/css/style.css) holds all styling. +- Cache-busting: the `?v=NN` suffixes on the CSS/JS ``/` + + + + + diff --git a/templates/admin_modules_dda.html b/templates/admin_modules_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..c5ef82ddb1acea50ebe498d47bb681bcd371e9bc --- /dev/null +++ b/templates/admin_modules_dda.html @@ -0,0 +1,94 @@ + + + + + + App Modules — Vedangsoft Change Detection + + + + +
+ {% include "partials/navbar_dda.html" %} + +
+ {% include "partials/alerts_dda.html" %} + +
+
+

App Modules

+

Centralized module master used by the nav menu and role permissions.

+
+ +
+
+

Modules

+
+ + +
+
+
+ Show + + entries +
+

Loading modules…

+ +
+
+
+
+ + + + + + + + + + + diff --git a/templates/admin_roles_users_dda.html b/templates/admin_roles_users_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..3f8128c202d7b63f5b5e9a723d60595dcb3d55f2 --- /dev/null +++ b/templates/admin_roles_users_dda.html @@ -0,0 +1,133 @@ + + + + + + Roles & Users — Vedangsoft Change Detection + + + + +
+ {% include "partials/navbar_dda.html" %} + +
+ {% include "partials/alerts_dda.html" %} + +
+
+

Roles & Users

+

Manage role hierarchy, per-module permissions, and user accounts.

+
+ +
+
+
+

Role Hierarchy

+ +
+

Loading roles…

+
+ +
+
+

Users

+
+ + +
+
+

Loading users…

+ +
+
+
+
+
+ + + + + + + + + + + + + + diff --git a/templates/audit_log_dda.html b/templates/audit_log_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..3f7f3810b68f25e3b552d3017ee5cbcb92661246 --- /dev/null +++ b/templates/audit_log_dda.html @@ -0,0 +1,62 @@ + + + + + + Audit Log — Vedangsoft Change Detection + + + + +
+ {% include "partials/navbar_dda.html" %} + +
+ {% include "partials/alerts_dda.html" %} + +
+
+

📋 Audit Log

+

User activity audit trail

+
+ +
+
+

Activity

+
+ + +
+
+
+ + + + + + + +
+

Loading audit log…

+ +
+
+
+
+ + + + + + + diff --git a/templates/detect_dda.html b/templates/detect_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..b7bb50a76fdf30f1f79ecadd5d8eef4bbc5bf29d --- /dev/null +++ b/templates/detect_dda.html @@ -0,0 +1,197 @@ + + + + + + Change Detection — Vedangsoft Change Detection + + + + + +
+ {% include "partials/navbar_dda.html" %} + +
+ {% include "partials/alerts_dda.html" %} + +
+
+ +
+
+
+

Detection options

+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+ + + + +
+

+ + +
+ +
+
+

Change Detection

+
+ + +
+
+

+
+
+ + +
+

+
+ + + + +
+

+
+
+
+ Before (T1) +
+ + +
+
+ After (T2) +
+ + +
+
+
+ +
+
+
+

Same-area pairs

+
+
+
+
+
+

Pick from library

+
+

Click T1 or T2 on an image, or use the dropdowns above (all images).

+
+

Loading library images…

+
+ +
+
+ +
+
+

Ready to detect?

+

Select Before and After images, then run detection from here or the top of the page.

+
+ +
+
+
+
+
+
+ + + + + + {% include "partials/result_modal_dda.html" %} + + + + + + + + + + + + diff --git a/templates/exception_log_dda.html b/templates/exception_log_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..92b2f2fd59ae473e01ddef3504a39f698535b3c5 --- /dev/null +++ b/templates/exception_log_dda.html @@ -0,0 +1,138 @@ + + + + + + Exception Log — Vedangsoft Change Detection + + + + +
+ {% include "partials/navbar_dda.html" %} + +
+ {% include "partials/alerts_dda.html" %} + +
+
+
+

💥 Exception Log

+

System errors captured by the global exception handler

+
+
+ + +
+
+ + +
+
+
+
💥
+
0
+
500 Errors (this page)
+
+
+
⚠️
+
0
+
Other Errors (this page)
+
+
+
📋
+
0
+
Total Filtered Records
+
+
+
🔥
+
0
+
Unhandled (this page)
+
+
+ +
+
+

Errors

+
+ + + +
+
+
+ + + + + + +
+

Loading exception log…

+ +
+
+ + + +
+
+
+ + + + + + + + + + diff --git a/templates/forgot_password_dda.html b/templates/forgot_password_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..e2043deca33661b919aad946578d3902d496e436 --- /dev/null +++ b/templates/forgot_password_dda.html @@ -0,0 +1,68 @@ + + + + + + Forgot Password — Vedangsoft Change Detection + + + + + +
+
+
+ + Vedangsoft Change Detection +
+ +
+
+

Forgot password

+
+

Enter the email on your account and we'll send you a link to reset your password.

+ + + + +
+
+ + +
+ +
+ + +
+
+
+ + + + + diff --git a/templates/home_dda.html b/templates/home_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..422ae1cf3a7ad2e5dd31ff24f789d963cc1bf755 --- /dev/null +++ b/templates/home_dda.html @@ -0,0 +1,133 @@ + + + + + + Dashboard — Vedangsoft Change Detection + + + + +
+ {% include "partials/navbar_dda.html" %} + +
+ {% include "partials/alerts_dda.html" %} + +
+
+
+
+

Welcome

+

System-wide overview of every change detection run, region, and report.

+
+
+ + +
+
+
+ + + +
+ +
+

Change Detection Overview

+

Click any stat to view detection reports.

+
+

Loading overview…

+
+
+ + +
+

Latest Detection Result

+

Loading latest result…

+
+ + +
+

Detections by Role

+

Detection activity grouped by the role of the user who ran it.

+

Loading role breakdown…

+
+ + +
+
+

Region-wise Analysis

+ Click a region to filter villages below +
+

Loading regions…

+
+ +
+
+

Village-wise Analysis

+
+ + +
+
+

Click a village to view its detection history and compare runs.

+

Loading villages…

+
+ + +
+

Change Comparison

+

Select a village above to compare its latest and previous detection results.

+
+ + +
+

Charts & Graphs

+
+
+

Detections by Region

+ +
+
+

Detections by Role

+ +
+
+

Detections by Village / Location

+ +
+
+

Detection Trend (last 6 months)

+ +
+
+

Detected vs Unclassified Changes

+ +
+
+
+ + +
+
+

Recent Reports

+ View all reports +
+

Loading recent reports…

+
+
+
+
+
+ + + + + + + + diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000000000000000000000000000000000000..7dd536e98f5001a331ca917839755babb9cfe4de --- /dev/null +++ b/templates/index.html @@ -0,0 +1,237 @@ + + + + + + AI Change Detection + + + +
+ +
+
+
+ + AI Change Detection +
+
+ + + + + +
+
+ +

Upload / Detection

+
+
+
+
+ + +
+
+ + +
+
+
+
+ +
+ +
+ +
No file chosen
+ +
+
+ +
+ +
+ +
No file chosen
+ +
+
+
+
+ + +
+

+ For Google Earth screenshots: use the same map location, zoom level, and crop for before and after images. +

+
+ + +
+
+ +
+
+ +
+
+
+
+ + +
+
+ + +
+
+
+
+ +
+ +
+
+ + +
+
+
+ + + + +
+
+ +

History View

+
+
+ + + + + + + + + + + + + +
TimestampBeforeAfterResultRegions% ChangeActions
+
+ +
+ +
+
+ + + + + + + + + + diff --git a/templates/library_dda.html b/templates/library_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..7c4f84440c7322681c7c94ebffa86ed43a0198be --- /dev/null +++ b/templates/library_dda.html @@ -0,0 +1,206 @@ + + + + + + Master Library — Vedangsoft Change Detection + + + + + +
+ {% include "partials/navbar_dda.html" %} + +
+ {% include "partials/alerts_dda.html" %} + +
+
+ +
+
+
+

Upload images

+ +
+

Select a folder, then drop files here or browse. Folders keep their subfolder names.

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+

Drag & drop files or a folder

+

GeoTIFF, PNG, or JPEG. Multiple files and nested folders are supported.

+
+ + +
+

No files selected.

+
+ +
+
+ Storage layout +

Organize images in a configurable zone → area → year → type hierarchy.

+

+              
+
+
+
+

Same-area pairs

+ +
+

Images that cover the same place are grouped automatically. The oldest is Before and the newest is After.

+

Loading pairs…

+
+
+
+

Images

+ +
+

Select a node in the tree.

+ +

Click an image to view · use the delete button to remove from library

+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + diff --git a/templates/login_dda.html b/templates/login_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..fa04c2a24d03523194b73e3f9bd6aa3cb52d7fcc --- /dev/null +++ b/templates/login_dda.html @@ -0,0 +1,137 @@ + + + + + + Sign In — Vedangsoft Change Detection + + + + + +
+
+
+ + Vedangsoft Change Detection +
+ +
+
+

Sign in

+
+ + + + +
+ + +
+ +
+
+ + + +
+ +
+ + + +
+ +
+ + + + +
+ +
+ + + +
+ +
+ +
+ + +
+
Optional — you can add or change this later in your profile.
+ +
+ +
+ + Forgot password? +
+ + +
+ + + +
+ Need an account? Create one + +
+
+
+
+ + + + + + diff --git a/templates/logs_dda.html b/templates/logs_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..e3344041a7a50542dd5686d1afcaf34ea7eba68e --- /dev/null +++ b/templates/logs_dda.html @@ -0,0 +1,62 @@ + + + + + + Logs — Vedangsoft Change Detection + + + + +
+ {% include "partials/navbar_dda.html" %} + +
+ {% include "partials/alerts_dda.html" %} + +
+
+

Application logs

+

Live view of recent server events. Filter, download, or clear the buffer.

+
+ +
+
+

Logs

+
+ + + + Download + +
+
+
+ + + +
+

Loading logs…

+
+
+
+
+ + + + + + + diff --git a/templates/masters_villages_dda.html b/templates/masters_villages_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..4f2de991e664d4194734ee86b44a437741d0ce71 --- /dev/null +++ b/templates/masters_villages_dda.html @@ -0,0 +1,66 @@ + + + + + + Village / Location — Vedangsoft Change Detection + + + + +
+ {% include "partials/navbar_dda.html" %} + +
+ {% include "partials/alerts_dda.html" %} + +
+
+

Village / Location

+

Master list of villages and locations, grouped under a zone or district.

+
+ +
+
+

Locations

+
+ + + +
+
+

Loading…

+
+
+
+
+ + + + + + + + + diff --git a/templates/masters_zones_dda.html b/templates/masters_zones_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..fe8f4bb8d7204a206f65f84b1e8cf8a0bb57b1a5 --- /dev/null +++ b/templates/masters_zones_dda.html @@ -0,0 +1,59 @@ + + + + + + Zone / District — Vedangsoft Change Detection + + + + +
+ {% include "partials/navbar_dda.html" %} + +
+ {% include "partials/alerts_dda.html" %} + +
+
+

Zone / District

+

Master list of zones and districts used to organize imagery and reports.

+
+ +
+
+

Zones

+
+ + +
+
+

Loading…

+
+
+
+
+ + + + + + + + + diff --git a/templates/partials/alerts_dda.html b/templates/partials/alerts_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..86baad33f7622d31669b7ef7282b2ccc4789bcf7 --- /dev/null +++ b/templates/partials/alerts_dda.html @@ -0,0 +1,2 @@ + + diff --git a/templates/partials/navbar_dda.html b/templates/partials/navbar_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..0e68eef1d006de29ebc2394021c0bd58d43bfc05 --- /dev/null +++ b/templates/partials/navbar_dda.html @@ -0,0 +1,96 @@ + diff --git a/templates/partials/result_modal_dda.html b/templates/partials/result_modal_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..00cfa4d3756ae69d858a10abdeabddccaa93eb66 --- /dev/null +++ b/templates/partials/result_modal_dda.html @@ -0,0 +1,114 @@ + + diff --git a/templates/profile_dda.html b/templates/profile_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..1c5a55ffdfb66706bb9b982bae70f06aa1df9d48 --- /dev/null +++ b/templates/profile_dda.html @@ -0,0 +1,105 @@ + + + + + + My Profile — Vedangsoft Change Detection + + + + +
+ {% include "partials/navbar_dda.html" %} + +
+ {% include "partials/alerts_dda.html" %} + +
+
+

My Profile

+

View and update your account information.

+
+ +
+
+
+ +

 

+

 

+ +
+
+ Account status + Active +
+
+ Last login + — +
+
+
+
+ +
+
+

Personal Information

+ + +
+
+
+ + +
+
+ + +
+
+
+ +
+ + +
+
+ +
+
+ +
+

Change Password

+ + +
+
+ + +
+
+
+ + +
At least 8 characters
+
+
+ + +
+
+ +
+
+
+
+
+
+
+ + + + + + + + diff --git a/templates/report_dda.html b/templates/report_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..7bd6166f563c38ec6fb641d53d6ac5e9d324a991 --- /dev/null +++ b/templates/report_dda.html @@ -0,0 +1,69 @@ + + + + + + Vedangsoft Detection Report + + + + +
+
+
+ Vedangsoft Change Detection — Report +
+
+ ← Back to app + + +
+
+ + +

Loading report…

+ +
+ + + + + diff --git a/templates/reports_dda.html b/templates/reports_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..daf0ddce9795ec8d1ecff090ea30558fcc8f03f5 --- /dev/null +++ b/templates/reports_dda.html @@ -0,0 +1,87 @@ + + + + + + Reports — Vedangsoft Change Detection + + + + + +
+ {% include "partials/navbar_dda.html" %} + +
+ {% include "partials/alerts_dda.html" %} + +
+
+
+

Detection Reports

+
+ + +
+
+

Filter by text, status, source, area, or date. Download PDF or open the browser report.

+
+ + + + + + + + +
+

Loading reports…

+ +
+
+
+
+ + {% include "partials/result_modal_dda.html" %} + + + + + + + + + + diff --git a/templates/reset_password_dda.html b/templates/reset_password_dda.html new file mode 100644 index 0000000000000000000000000000000000000000..a5fdf359fddebdcb60a6dccbc33d47dca7c822e8 --- /dev/null +++ b/templates/reset_password_dda.html @@ -0,0 +1,77 @@ + + + + + + Reset Password — Vedangsoft Change Detection + + + + + +
+
+
+ + Vedangsoft Change Detection +
+ +
+
+

Reset password

+
+ + + + +
+
+ + +
At least 8 characters
+ +
+
+ + + +
+ +
+ + +
+
+
+ + + + +