Spaces:
Running
Running
| """Live-like ablation matching job 68 / report 77 path for before6/after6.""" | |
| from __future__ import annotations | |
| import sys | |
| from pathlib import Path | |
| import cv2 | |
| import numpy as np | |
| from dotenv import load_dotenv | |
| from PIL import Image | |
| ROOT = Path(__file__).resolve().parents[1] | |
| sys.path.insert(0, str(ROOT)) | |
| load_dotenv(ROOT / ".env", override=True) | |
| from app.detection_engine import ( # noqa: E402 | |
| _alignment_ncc, | |
| ai_deep_learning_method, | |
| analyze_change_regions, | |
| get_detection_max_size, | |
| normalize_radiometry, | |
| preprocess_image, | |
| recover_chromatic_roof_construction, | |
| recover_dark_roof_construction, | |
| split_weakly_bridged_change_blobs, | |
| strip_alignment_edge_ribbons_from_mask, | |
| strip_parking_cluster_from_mask, | |
| strip_shadow_fragments_from_mask, | |
| strip_shadow_only_from_mask, | |
| strip_transient_from_mask, | |
| strip_weak_seasonal_veg_from_mask, | |
| visualize_changes, | |
| ) | |
| def main(): | |
| before_p = ROOT / "data/library_sources/central_delhi/Images/before6.tif" | |
| after_p = ROOT / "data/library_sources/central_delhi/Images/after6.tif" | |
| b_pil = Image.open(before_p).convert("RGB") | |
| a_pil = Image.open(after_p).convert("RGB") | |
| if a_pil.size != b_pil.size: | |
| a_pil = a_pil.resize(b_pil.size, Image.Resampling.LANCZOS) | |
| # Match job_runner: large max_size keeps native 1429x1180 | |
| ms = 20000 | |
| b0 = preprocess_image(b_pil, max_size=ms) | |
| a0 = preprocess_image(a_pil, max_size=ms) | |
| ncc = float(_alignment_ncc(b0, a0)) | |
| ok = ncc >= 0.55 | |
| print("shape", b0.shape, "ncc", round(ncc, 4), "ok", ok) | |
| b_chr, a_chr = b0.copy(), a0.copy() | |
| b, a = normalize_radiometry(b0, a0) | |
| m, dbg = ai_deep_learning_method(b, a, sensitivity=0.45, registration_ok=ok) | |
| print("dl thr", dbg.get("threshold_score"), "model", dbg.get("model_changed_px"), | |
| "combined", dbg.get("combined_changed_px")) | |
| def px(x): | |
| return int(np.sum(x > 127)) | |
| print("after_dl", px(m)) | |
| m = strip_transient_from_mask(m, b, a) | |
| print("transient", px(m)) | |
| m = strip_shadow_only_from_mask(m, b, a, registration_ok=ok) | |
| print("shadow_only", px(m)) | |
| m = strip_shadow_fragments_from_mask(m, b, a, registration_ok=ok) | |
| print("fragments", px(m)) | |
| m = strip_alignment_edge_ribbons_from_mask(m) | |
| print("ribbons", px(m)) | |
| m = strip_parking_cluster_from_mask(m, b, a) | |
| m = strip_weak_seasonal_veg_from_mask(m, b, a) | |
| m = recover_chromatic_roof_construction(m, b_chr, a_chr, registration_ok=ok) | |
| print("chroma", px(m)) | |
| m = recover_dark_roof_construction(m, b_chr, a_chr, registration_ok=ok) | |
| print("dark", px(m)) | |
| m = strip_shadow_fragments_from_mask(m, b, a, registration_ok=False) | |
| m = strip_alignment_edge_ribbons_from_mask(m) | |
| m = split_weakly_bridged_change_blobs(m) | |
| print("final", px(m), f"{100 * px(m) / m.size:.2f}%") | |
| regs = analyze_change_regions( | |
| m, a_chr, min_area=150, use_ensemble=False, | |
| before_img=b_chr, registration_ok=False, | |
| ) | |
| print("regions", len(regs)) | |
| for r in regs[:12]: | |
| w, h = r["bbox"][2], r["bbox"][3] | |
| print( | |
| f" #{r['id']} area={r['area']} {w}x{h} " | |
| f"fill={r.get('fill_ratio')} verts={len(r.get('polygon') or [])} " | |
| f"{r.get('object_type')}" | |
| ) | |
| out = ROOT / "data/delhi_cd/friday_drone_report_fix/report77_fix" | |
| out.mkdir(parents=True, exist_ok=True) | |
| overlay = visualize_changes(b_chr, a_chr, m, regions=regs, shape_mode="polygon") | |
| cv2.imwrite(str(out / "overlay.png"), cv2.cvtColor(overlay, cv2.COLOR_RGB2BGR)) | |
| print("wrote", out / "overlay.png") | |
| print("COMPARE report75=171544/29 report77=150915/24 target<<both") | |
| if __name__ == "__main__": | |
| main() | |