62 lines
2.4 KiB
Python
62 lines
2.4 KiB
Python
"""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 <run_dir> <page_num> [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)
|