| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- from __future__ import annotations
-
- import logging
- import os
- import shutil
- from pathlib import Path
-
- from src.ocr.paddle_engine import OcrPageResult, ParsedBlock
-
- logger = logging.getLogger(__name__)
-
- _ENV_LOADED: bool = False
-
-
- def _load_env() -> None:
- global _ENV_LOADED
- if _ENV_LOADED:
- return
- env_path = Path(__file__).resolve().parent.parent.parent / ".env"
- if env_path.exists():
- with open(env_path) as f:
- for line in f:
- line = line.strip()
- if line and not line.startswith("#") and "=" in line:
- key, _, value = line.partition("=")
- key = key.strip()
- if key not in os.environ:
- os.environ[key] = value.strip().strip("\"'")
- _ENV_LOADED = True
-
-
- def _ensure_env() -> None:
- _load_env()
- os.environ.setdefault("SURYA_INFERENCE_BACKEND", "llamacpp")
- os.environ.setdefault("SURYA_GUIDED_LAYOUT", "false")
- if "LLAMA_CPP_BINARY" not in os.environ:
- binary = shutil.which("llama-server") or os.path.expanduser(
- "~/.local/bin/llama-server"
- )
- if Path(binary).exists():
- os.environ["LLAMA_CPP_BINARY"] = binary
-
-
- class SuryaEngine:
- """OCR engine using Surya 2 VLM via llama.cpp."""
-
- def __init__(self) -> None:
- _ensure_env()
- try:
- from surya.inference import SuryaInferenceManager
- from surya.recognition import RecognitionPredictor
-
- self._manager = SuryaInferenceManager()
- self._predictor = RecognitionPredictor(self._manager)
- except ImportError as e:
- msg = (
- "Surya engine not available. Install: pip install surya-ocr torch"
- )
- raise ImportError(msg) from e
-
- def process(self, image_path: str) -> OcrPageResult:
- from PIL import Image
-
- image = Image.open(image_path)
- results = self._predictor([image])
-
- blocks: list[ParsedBlock] = []
- raw_json: dict = {}
-
- if results:
- page = results[0]
- for blk in getattr(page, "blocks", []):
- html = getattr(blk, "html", "") or ""
- label = getattr(blk, "label", "text")
- bbox = getattr(blk, "bbox", [0, 0, 0, 0])
- confidence = float(getattr(blk, "confidence", 0.9))
- blocks.append(
- ParsedBlock(
- label=label,
- content=html,
- bbox=(int(bbox[0]), int(bbox[1]), int(bbox[2]), int(bbox[3])),
- confidence=confidence,
- )
- )
-
- return OcrPageResult(
- blocks=blocks,
- raw_json=raw_json,
- width=image.width,
- height=image.height,
- )
-
-
- _surya_engine: SuryaEngine | None = None
-
-
- def surya_ocr_image(image_path: str) -> OcrPageResult:
- global _surya_engine
- if _surya_engine is None:
- _surya_engine = SuryaEngine()
- return _surya_engine.process(image_path)
|