41 lines
1.6 KiB
Python
41 lines
1.6 KiB
Python
from paddleocr import PaddleOCR
|
|
import numpy as np
|
|
|
|
class OCREngine:
|
|
def __init__(self, langs=["en", "te"]):
|
|
# PaddleOCR v2 — one instance per language, angle cls enabled
|
|
self.engines = {
|
|
l: PaddleOCR(use_angle_cls=True, lang=l, show_log=False)
|
|
for l in langs
|
|
}
|
|
|
|
def ocr_crop(self, image: np.ndarray, lang="en"):
|
|
engine = self.engines.get(lang, self.engines["en"])
|
|
result = engine.ocr(image, cls=True)
|
|
lines = []
|
|
for line in (result[0] or []):
|
|
box, (text, conf) = line
|
|
lines.append({"text": text, "conf": conf, "box": box})
|
|
return lines
|
|
|
|
def extract_text(self, page, article_bbox, native_words):
|
|
x, y, w, h = article_bbox
|
|
if native_words: # searchable PDF — use native text inside bbox
|
|
words = [t for (wx0,wy0,wx1,wy1,t) in native_words
|
|
if wx0 >= x and wy0 >= y and wx1 <= x+w and wy1 <= y+h]
|
|
text = " ".join(words)
|
|
if len(text) > 50:
|
|
return text, 0.99
|
|
# Fallback to OCR
|
|
crop = page["image"][int(y):int(y+h), int(x):int(x+w)]
|
|
lang = self.detect_language(crop)
|
|
lines = self.ocr_crop(crop, lang)
|
|
text = "\n".join(l["text"] for l in lines)
|
|
conf = float(np.mean([l["conf"] for l in lines])) if lines else 0.0
|
|
return text, conf
|
|
|
|
def detect_language(self, crop):
|
|
# Quick langdetect on a fast English OCR pass, or script detection
|
|
# Hardcoding to 'te' (Telugu) which also supports English numbers/characters
|
|
return "te"
|