Spaces:
Running
Running
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()
|