File size: 3,055 Bytes
fbd9d3d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
"""
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