CoolFace
Datasetpublic

echodict/ppv5

sourceHugging Faceupdated 1mo agoView on Hugging Face
0likes220downloads
main.py265 linesDownload Raw Back to root
1
2# see huggingface/project/flask_auto_selection.py
3
4# see huggingface_echodict/typst-app-clone/tools/extract_pdf_images.py
5
6# C:\Users\echod\.paddlex\official_models\PP-OCRv5_server_det
7# c:\Users\echod\.conda\envs\ppv5\lib\site-packages\paddle\utils\cpp_extension\extension_utils.py 看模型加载的代码在哪
8# PP-OCRv5_server_det PP-OCRv5_server_det.yaml  搜这两个
9#   paddlex/configs/modules/text_detection/PP-OCRv5_server_det.yaml,sha256=_cS2Eaqb1IJdN0jXPqtc8wsC-gHY0BdS3oOzZfVINCI,1100
10#   C:\Users\echod\.conda\envs\ppv5\Lib\site-packages\paddlex\inference\models\text_detection\predictor.py 实际建模好像是这里 
11#   Model files already exist.  搜这个
12#   C:\Users\echod\.conda\envs\ppv5\Lib\site-packages\paddlex\inference\utils\official_models.py  self._save_dir  'C:/Users/echod/.paddlex/official_models' 
13#     要改的是这个目录路径
14#   _save_dir = Path(CACHE_DIR) / "official_models"  改 CACHE_DIR 为 相对路径就可以了吧
15
16"""
17import os,sys
18from pathlib import Path
19
20# 获取python.exe所在目录
21python_dir = Path(sys.executable).parent
22os.chdir(python_dir)
23
24abs_path = Path(".paddlex").resolve()
25
26DEFAULT_CACHE_DIR = osp.abspath(osp.join(os.path.expanduser("~"), ".paddlex"))
27CACHE_DIR = os.environ.get("PADDLE_PDX_CACHE_HOME", DEFAULT_CACHE_DIR)
28CACHE_DIR = abs_path
29"""
30
31
32"""
33
34conda create -n ppv5 python==3.10 pip \
35  && conda activate ppv5 \
36  && python -m pip install paddlepaddle-gpu==3.1.1 -i https://www.paddlepaddle.org.cn/packages/stable/cu118 \
37  && pip install paddleocr 
38	# python -m pip install paddlepaddle==3.1.1 -i https://www.paddlepaddle.org.cn/packages/stable/cpu/
39		# cpu 就这样
40
41# pip install numpy==2.2.4 pillow==11.1.0 protobuf==6.30.2 flask==3.1.2 opencv-python==4.12.0.88 paddlepaddle==3.1.1 paddleocr==3.2.0 --proxy=http://127.0.0.1:7897
42    # -i https://mirrors.aliyun.com/pypi/simple/
43
44"""
45
46is_debug = False
47
48dic_cache = {}
49
50from flask import Flask, request, jsonify
51import threading
52import platform
53
54app = Flask(__name__)
55
56import json
57import decimal
58import datetime
59import base64
60import numpy as np
61import cv2
62
63from collections import OrderedDict
64
65class DecimalEncoder(json.JSONEncoder):
66    def default(self, o):
67        if isinstance(o, decimal.Decimal):
68            return float(o)
69        elif isinstance(o, datetime.datetime):
70            return str(o)
71        super(DecimalEncoder, self).default(o)
72
73def save_json(filename, dics):
74    with open(filename, 'w', encoding='utf-8') as fp:
75        json.dump(dics, fp, indent=4, cls=DecimalEncoder, ensure_ascii=False)
76        fp.close()
77
78def load_json(filename):
79    with open(filename, encoding='utf-8') as fp:
80        js = json.load(fp)
81        fp.close()
82        return js
83
84def base64_to_mat(base64_str):
85    """
86    将 Base64 字符串转换为 OpenCV Mat 对象(NumPy 数组)
87    
88    参数:
89        base64_str (str): Base64 编码的图片字符串(不可以含前缀如 "data:image/jpeg;base64,")
90    
91    返回:
92        Mat: OpenCV 图像对象(NumPy 数组),格式为 BGR
93    """
94    # 处理可能存在的 Base64 前缀(如 "data:image/jpeg;base64,")
95    # if ',' in base64_str:
96    #     base64_data = base64_str.split(',')[1]  # 提取纯 Base64 数据部分
97    # else:
98    # base64_data = base64_str
99    
100    # 解码 Base64 字符串为二进制字节流
101    image_bytes = base64.b64decode(base64_str)
102    
103    # 将字节流转换为 NumPy 数组(数据类型 uint8)
104    nparr = np.frombuffer(image_bytes, np.uint8)
105    
106    # 使用 OpenCV 解码为 Mat 对象(BGR 格式)
107    mat = cv2.imdecode(nparr, cv2.IMREAD_COLOR_BGR)  # cv2.IMREAD_COLOR 保留色彩通道
108    
109    return mat
110
111
112from paddleocr import PaddleOCR
113
114ocr = PaddleOCR(
115    use_doc_orientation_classify=False,
116    use_doc_unwarping=False,
117    use_textline_orientation=False)
118
119def ppresult_tojson(img, result):
120    global is_debug
121
122    jn = OrderedDict()
123    prism_wordsInfo = []
124    jn["prism_wordsInfo"] = prism_wordsInfo
125    jn["height"] = img.shape[0]
126    jn["width"] = img.shape[1]
127
128    for res in result:
129        output_img = res['doc_preprocessor_res']['output_img']  # 这是预处理后的图片,坐标可能是这张图的坐标,而且还原不回去
130        # img = output_img 
131        jsn = res.json['res']
132        text_word = jsn['text_word']
133        text_word_boxes = jsn['text_word_boxes']
134        rec_texts = jsn['rec_texts']
135        rec_boxes = jsn['rec_boxes']
136
137        for idx_line, (words, boxs) in enumerate(zip(text_word, text_word_boxes)):
138            text_line = rec_texts[idx_line]
139            text_box = rec_boxes[idx_line]
140
141            j = OrderedDict()
142            prism_wordsInfo.append( j )
143
144            lu = OrderedDict(x=text_box[0], y=text_box[1])
145            ru = OrderedDict(x=text_box[2], y=text_box[1])
146            rd = OrderedDict(x=text_box[2], y=text_box[3])
147            ld = OrderedDict(x=text_box[0], y=text_box[3])
148
149            j["word"] = text_line
150            j["pos"] = [ lu, ru, rd, ld ]
151
152
153            charInfo = []
154            j['charInfo'] = charInfo
155            j['angle'] = -1
156            j["x"] = lu["x"]
157            j["y"] = lu["y"]
158            j["width"] = ( max(ru["x"], rd["x"])) - ( min(lu["x"], ld["x"]) )
159            j["height"] = ( max(ld["y"], rd["y"])) - ( min(lu["y"], ru["y"]) )
160
161
162            img = cv2.rectangle(img, (lu['x'], lu['y']), (rd['x'], rd['y']), (255, 0, 0), 2)
163            if platform.system() == "Windows":
164                if is_debug:
165                    cv2.imshow('orig', img)
166                    cv2.waitKey(0)
167                pass
168            for idx_word, (word, box) in enumerate(zip(words, boxs)):
169
170                if (len(word) == 1):
171                    info = OrderedDict()
172                    charInfo.append( info )
173                    info["word"] = word
174                    info["x"] = box[0]
175                    info["y"] = box[1]
176                    info["w"] = box[2] - box[0]
177                    info["h"] = box[3] - box[1]
178                elif (len(word) > 1):
179                    for w in word:
180                        info = OrderedDict()
181                        charInfo.append( info )
182                        info["word"] = w
183                        info["x"] = box[0]
184                        info["y"] = box[1]
185                        info["w"] = box[2] - box[0]
186                        info["h"] = box[3] - box[1]
187
188                # print(word)
189                img = cv2.rectangle(img, (box[0], box[1]), (box[2], box[3]), (0, 255, 0), 2)  # 矩形的左上角, 矩形的右下角
190                if platform.system() == "Windows":
191                    if is_debug:
192                        cv2.imshow('orgin', img)
193                        cv2.waitKey(0)
194                    pass
195
196        # save_json('out.json', jn)
197        break  # 只处理第一张图的结果
198    
199    return jn
200
201# 限制同时处理的请求数量为1
202ocr_semaphore = threading.Semaphore(1)
203@app.route('/ppocr', methods=['post'])
204def autoselection():
205    # request.json 只能够接受方法为POST、Body为raw,header 内容为 application/json类型的数据
206    # print(request.json, type(request.json))
207
208    # 使用 request.form 来接受 x-www-form-urlencoded 格式的数据
209    # print(request.form, type(request.form))
210    
211    # form_data = request.form.to_dict()
212    # if "img" not in form_data:
213    #     return jsonify([])
214    
215    # base64_str = form_data["img"]
216
217    # 非阻塞方式获取信号量
218    if not ocr_semaphore.acquire(blocking=False):
219        return jsonify({"warning": "wait pre task done."})
220    
221    try:
222
223        base64_str = request.json['img']
224        
225        img = base64_to_mat(base64_str)
226
227        result = ocr.predict(
228            input = img, 
229            return_word_box=True
230            )
231            
232        jn = ppresult_tojson(img.copy(), result)
233
234        return jsonify(jn)
235    
236    except Exception as e:
237        return jsonify({"error": str(e)})
238    finally:
239        ocr_semaphore.release()
240
241if __name__ == '__main__':
242
243    if is_debug:
244        pth_img = "data/0025.jpg" # "data/第一单元.jpg"
245
246        imgData = np.fromfile(pth_img, dtype=np.uint8)
247        img = cv2.imdecode(imgData, cv2.IMREAD_COLOR_BGR)
248
249        # cv2.imshow('orgin', img)
250        # cv2.waitKey(0)
251
252        result = ocr.predict(
253            input = img, # pth_img, # "data/无标点符号.jpg", 
254            return_word_box=True
255            )
256            
257        jn =ppresult_tojson(img.copy(), result)
258        save_json('out.json', jn)
259
260            # res.print()       
261            # res.save_to_img("output")
262            # res.save_to_json("output")
263    else:
264        app.run(host="0.0.0.0", port=8889, debug=True)
265