"""Re-run ONLY PaddleOCR layout detection (no Claude calls) on a saved run's page PNG, at the default 0.5 cutoff and at a lowered threshold, and write the all-regions debug image for each so the effect of the threshold is visible. Usage: venv/bin/python3 _replay_regions.py [threshold] (threshold defaults to 0.3) """ import sys from collections import Counter from pathlib import Path from smart_extractor import detect_regions, draw_all_regions_debug def summarize(regions): c = Counter(r.get("type", "unknown") for r in regions) return ", ".join(f"{k}={v}" for k, v in sorted(c.items(), key=lambda kv: -kv[1])) def main(run_dir, page_num, threshold=0.3): run = Path(run_dir) png = run / "pages" / f"page_{page_num:03d}.png" out = Path(f"/tmp/replay_regions_{run.name}_p{page_num:03d}") out.mkdir(parents=True, exist_ok=True) print(f"=== page {png} -> {out} ===\n") # BASELINE: stock 0.5 cutoff print("--- detection @ default (0.5) ---") base = detect_regions(str(png), threshold=0.5) print(f" {len(base)} regions: {summarize(base)}") draw_all_regions_debug(str(png), base, out, page_num) Path(out / f"page_{page_num:03d}_allregions_debug.png").rename( out / f"page_{page_num:03d}_thr050.png") # LOWERED: threshold under test print(f"\n--- detection @ {threshold} ---") low = detect_regions(str(png), threshold=threshold) print(f" {len(low)} regions: {summarize(low)}") draw_all_regions_debug(str(png), low, out, page_num) Path(out / f"page_{page_num:03d}_allregions_debug.png").rename( out / f"page_{page_num:03d}_thr{int(threshold*100):03d}.png") # DELTA: new regions gained by lowering the cutoff print(f"\n--- delta: {len(low) - len(base)} more region(s) at {threshold} ---") base_boxes = {tuple(r["bbox"]) for r in base} gained = [r for r in low if tuple(r["bbox"]) not in base_boxes] gained.sort(key=lambda r: (r["bbox"][1], r["bbox"][0])) for r in gained: b = r["bbox"] print(f" + R{r['id']:>3} {r.get('type','?'):>16} conf={r.get('confidence',0):.2f} " f"bbox={b} ({b[2]-b[0]}x{b[3]-b[1]})") print(f"\nImages written to: {out}") for f in sorted(out.glob("*.png")): print(f" {f.name}") if __name__ == "__main__": thr = float(sys.argv[3]) if len(sys.argv) > 3 else 0.3 main(sys.argv[1], int(sys.argv[2]), thr)