File size: 1,644 Bytes
1ddeb51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
"""Standalone Surya OCR worker (runs in the isolated .venv-ocr).

Surya 0.22 pulls transformers 5.x + a llama.cpp backend, which conflicts with
the embedding stack (transformers 4.x). To keep those concerns decoupled, this
worker runs under its OWN interpreter (backend/.venv-ocr/bin/python) and is
invoked as a subprocess by app.ocr. It must NOT import the app package.

Usage:  python ocr_worker.py <input_file> <output_json>
Writes: {"lines": [{"text": str, "confidence": float}], "raw_text": str}
"""
import json
import re
import sys

from PIL import Image


def _load_images(path: str):
    if path.lower().endswith(".pdf"):
        import pypdfium2 as pdfium

        pdf = pdfium.PdfDocument(path)
        return [pdf[i].render(scale=2.0).to_pil().convert("RGB") for i in range(len(pdf))]
    return [Image.open(path).convert("RGB")]


def _strip_html(s: str | None) -> str:
    return re.sub(r"<[^>]+>", " ", s or "").strip()


def main() -> None:
    in_path, out_path = sys.argv[1], sys.argv[2]
    from surya.recognition import RecognitionPredictor

    rec = RecognitionPredictor()
    pages = rec(_load_images(in_path), full_page=True)

    lines = []
    for page in pages:
        for block in page.blocks:
            text = _strip_html(getattr(block, "html", None))
            if text:
                conf = getattr(block, "confidence", 1.0)
                lines.append({"text": text, "confidence": float(conf if conf is not None else 1.0)})

    with open(out_path, "w", encoding="utf-8") as f:
        json.dump({"lines": lines, "raw_text": "\n".join(l["text"] for l in lines)}, f)


if __name__ == "__main__":
    main()