"""Post one or more images to an OCR endpoint and save text_lines per image. Used to freeze the accuracy baseline and to capture candidate outputs for CER. Usage: python scripts/capture_ocr_text.py \ --url http://127.0.0.1:5002/v1/api/ai/suya_ocr_vllm/ \ --out-dir baseline_outputs \ temp_image_c3c56948-282e-453b-8fac-6c482243d1e5.jpg """ from __future__ import annotations import argparse import base64 from pathlib import Path import requests def _payload(image_path: Path) -> dict: suffix = image_path.suffix.lstrip(".").lower() or "png" return { "file": base64.b64encode(image_path.read_bytes()).decode("utf-8"), "type": "jpg" if suffix == "jpeg" else suffix, "skip_text_detection": False, "skip_table_detection": False, "recognize_math": False, "ocr_with_boxes": True, } def capture(url: str, image_path: Path, out_dir: Path, timeout: float) -> str: resp = requests.post(url, json=_payload(image_path), timeout=timeout) body = resp.json() text = (body.get("data") or {}).get("text_lines", "") if isinstance(body.get("data"), dict) else "" out_dir.mkdir(parents=True, exist_ok=True) (out_dir / (image_path.stem + ".txt")).write_text(text, encoding="utf-8") return text def main() -> None: parser = argparse.ArgumentParser(description="Capture OCR text_lines per image.") parser.add_argument("images", nargs="+", type=Path) parser.add_argument("--url", required=True) parser.add_argument("--out-dir", type=Path, required=True) parser.add_argument("--timeout", type=float, default=900) args = parser.parse_args() for image in args.images: capture(args.url, image, args.out_dir, args.timeout) print(f"captured {image.name} -> {args.out_dir}") if __name__ == "__main__": main()