Spaces:
Sleeping
Sleeping
Download ocr_engine.py from Praneeth4040/LazarFlowEasyOCR: direct link, hf CLI and curl.
- Browser
- Download file 2.74 kB
-
https://huggingface.co/spaces/Praneeth4040/LazarFlowEasyOCR/resolve/main/ocr_engine.py
- Command line
-
hf download hf://spaces/Praneeth4040/LazarFlowEasyOCR/ocr_engine.py
-
curl -L -o ocr_engine.py https://huggingface.co/spaces/Praneeth4040/LazarFlowEasyOCR/resolve/main/ocr_engine.py
2.74 kB
| from typing import Optional, List | |
| import logging | |
| import easyocr | |
| import numpy as np | |
| from PIL import Image | |
| import io | |
| import anyio | |
| logger = logging.getLogger(__name__) | |
| class OCREngine: | |
| """Wrapper for EasyOCR library.""" | |
| def __init__(self, languages: Optional[List[str]] = None, gpu: bool = False): | |
| """ | |
| Initializes the EasyOCR reader. | |
| Args: | |
| languages: List of language codes (e.g., ['en'] for English). | |
| Defaults to ['en'] if not provided. | |
| gpu: Whether to use GPU acceleration. Defaults to False (CPU only). | |
| """ | |
| self.languages = languages or ['en'] | |
| self.gpu = gpu | |
| self.reader = None | |
| self._init_reader() | |
| def _init_reader(self): | |
| """Lazy initialization of the EasyOCR reader.""" | |
| try: | |
| logger.info(f"Initializing EasyOCR with languages={self.languages}, gpu={self.gpu}...") | |
| self.reader = easyocr.Reader(self.languages, gpu=self.gpu) | |
| logger.info("EasyOCR reader initialized successfully") | |
| except Exception as e: | |
| raise RuntimeError(f"Failed to initialize EasyOCR: {e}") | |
| async def detect_text(self, content: bytes, req_id: str = "Unknown") -> str: | |
| """ | |
| Performs text detection on image bytes asynchronously. | |
| Args: | |
| content: Image bytes (PNG, JPG, etc.) | |
| req_id: Request ID for trace logging. | |
| Returns: | |
| Extracted text as a string. | |
| """ | |
| try: | |
| # Wrap the CPU-bound OCR logic in a thread to keep the event loop free | |
| return await anyio.to_thread.run_sync(self._detect_text_sync, content, req_id) | |
| except Exception as e: | |
| logger.error(f"EasyOCR async text detection failed: {e}", exc_info=True) | |
| raise RuntimeError(f"EasyOCR async text detection failed: {e}") | |
| def _detect_text_sync(self, content: bytes, req_id: str) -> str: | |
| """Synchronous implementation of text detection.""" | |
| logger.info(f"[{req_id}] ⚙️ EasyOCR starting processing thread. Thread CPU bound task starting.") | |
| # Convert bytes to PIL Image | |
| pil_image = Image.open(io.BytesIO(content)) | |
| # EasyOCR works with numpy arrays | |
| # Convert PIL to numpy array | |
| np_image = np.array(pil_image) | |
| # Perform OCR | |
| # detail=0 returns only text, skipping bounding box and confidence math (faster) | |
| # paragraph=True groups text together which is slightly faster for joining | |
| result = self.reader.readtext(np_image, detail=0, paragraph=True) | |
| logger.info(f"[{req_id}] 🏁 EasyOCR thread finished. Extracted {len(result)} paragraphs.") | |
| return "\n".join(result) | |