""" OCR engine using rapidocr-onnxruntime (PP-OCRv4 weights). No PaddlePaddle dependency — pure ONNX Runtime. Language packs are downloaded automatically by rapidocr on first use. """ import logging import numpy as np from app.config import VisionSettings from app.services.vision.base import OCREngine, OCRResult logger = logging.getLogger(__name__) class RapidOCREngine(OCREngine): def __init__(self, settings: VisionSettings): from rapidocr_onnxruntime import RapidOCR self._min_confidence = settings.ocr.min_confidence self._engine = RapidOCR() logger.info("RapidOCR engine initialized") def run(self, image: np.ndarray) -> list[OCRResult]: result, _ = self._engine(image) if not result: return [] out = [] for box, text, score in result: if score < self._min_confidence: continue # box is [[x1,y1],[x2,y2],[x3,y3],[x4,y4]] — take bounding rect xs = [p[0] for p in box] ys = [p[1] for p in box] h, w = image.shape[:2] bbox = [ min(xs) / w, min(ys) / h, max(xs) / w, max(ys) / h, ] out.append(OCRResult(text=text, confidence=float(score), bbox=bbox)) return out