| """ | |
| OCR 引擎封装模块 | |
| """ | |
| import logging | |
| from pathlib import Path | |
| from typing import Optional | |
| logger = logging.getLogger(__name__) | |
| class PaddleOCRWrapper: | |
| """PaddleOCR 引擎封装""" | |
| def __init__(self): | |
| self._ocr_engine = None | |
| def get_engine(self): | |
| """获取OCR引擎实例""" | |
| if self._ocr_engine is None: | |
| from app.utils.ocr_engine import get_ocr_engine | |
| self._ocr_engine = get_ocr_engine() | |
| return self._ocr_engine | |
| def extract_text(self, image_path: str) -> dict: | |
| """ | |
| 从图片中提取文本 | |
| Args: | |
| image_path: 图片路径 | |
| Returns: | |
| 包含提取结果的字典: | |
| { | |
| "success": bool, | |
| "text": str, # 提取的文本(按行连接) | |
| "lines": list, # 按行提取的文本列表 | |
| "error": str # 错误信息(如果失败) | |
| } | |
| """ | |
| try: | |
| engine = self.get_engine() | |
| if engine is None: | |
| return { | |
| "success": False, | |
| "text": "", | |
| "lines": [], | |
| "error": "OCR引擎未初始化" | |
| } | |
| # 检查文件是否存在 | |
| path = Path(image_path) | |
| if not path.exists(): | |
| return { | |
| "success": False, | |
| "text": "", | |
| "lines": [], | |
| "error": f"图片文件不存在: {image_path}" | |
| } | |
| # 执行OCR识别 | |
| logger.info(f"开始OCR识别: {image_path}") | |
| result = engine.ocr(str(image_path), cls=False) | |
| # 解析结果 | |
| if result is None or len(result) == 0: | |
| return { | |
| "success": True, | |
| "text": "", | |
| "lines": [], | |
| "error": None | |
| } | |
| # 提取文本行 | |
| lines = [] | |
| for page_result in result: | |
| if page_result is None: | |
| continue | |
| for line in page_result: | |
| if line and len(line) >= 2: | |
| text = line[1][0] # line[1][0] 是识别的文本 | |
| lines.append(text) | |
| return { | |
| "success": True, | |
| "text": "\n".join(lines), | |
| "lines": lines, | |
| "error": None | |
| } | |
| except Exception as e: | |
| logger.error(f"OCR识别失败: {e}", exc_info=True) | |
| return { | |
| "success": False, | |
| "text": "", | |
| "lines": [], | |
| "error": str(e) | |
| } | |
| # 全局OCR封装实例 | |
| _ocr_wrapper: Optional[PaddleOCRWrapper] = None | |
| def get_ocr_wrapper() -> PaddleOCRWrapper: | |
| """获取全局OCR封装实例""" | |
| global _ocr_wrapper | |
| if _ocr_wrapper is None: | |
| _ocr_wrapper = PaddleOCRWrapper() | |
| return _ocr_wrapper |