Skip to content

Commit 47fac10

Browse files
committed
feat: adapt rapidocr v3
1 parent 479ec51 commit 47fac10

File tree

3 files changed

+81
-73
lines changed

3 files changed

+81
-73
lines changed

rapidocr_web/task.py

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,33 @@
44
import base64
55
import copy
66
import json
7-
from collections import namedtuple
8-
from functools import reduce
9-
from typing import List, Tuple, Union
7+
from dataclasses import asdict, dataclass
8+
from typing import Optional
109

1110
import cv2
1211
import numpy as np
13-
from rapidocr_onnxruntime import RapidOCR
12+
from rapidocr import RapidOCR
13+
14+
15+
@dataclass
16+
class OCRWebOutput:
17+
image: str
18+
total_elapse: str
19+
elapse_part: str
20+
rec_res: str
1421

1522

1623
class OCRWebUtils:
1724
def __init__(self) -> None:
1825
self.ocr = RapidOCR()
19-
self.WebReturn = namedtuple(
20-
"WebReturn",
21-
["image", "total_elapse", "elapse_part", "rec_res", "det_boxes"],
22-
)
2326

24-
def __call__(self, img_content: str) -> namedtuple:
27+
def __call__(self, img_content: Optional[str]) -> str:
2528
if img_content is None:
2629
raise ValueError("img is None")
30+
2731
img = self.prepare_img(img_content)
28-
ocr_res, elapse = self.ocr(img)
29-
return self.get_web_result(img, ocr_res, elapse)
32+
33+
return self.get_ocr_res(img)
3034

3135
def prepare_img(self, img_str: str) -> np.ndarray:
3236
img_str = img_str.split(",")[1]
@@ -37,37 +41,37 @@ def prepare_img(self, img_str: str) -> np.ndarray:
3741
image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
3842
return image
3943

40-
def get_web_result(
41-
self, img: np.ndarray, ocr_res: List, elapse: List
42-
) -> Tuple[Union[str, List, str, str]]:
43-
if ocr_res is None:
44-
total_elapse, elapse_part = 0, ""
45-
img_str = self.img_to_base64(img)
46-
rec_res = json.dumps([], indent=2, ensure_ascii=False)
47-
boxes = ""
48-
else:
49-
boxes, txts, scores = list(zip(*ocr_res))
50-
scores = [f"{v:.4f}" for v in scores]
51-
rec_res = list(zip(range(len(txts)), txts, scores))
52-
rec_res = json.dumps(rec_res, indent=2, ensure_ascii=False)
53-
54-
det_im = self.draw_text_det_res(np.array(boxes), img)
55-
img_str = self.img_to_base64(det_im)
56-
57-
total_elapse = reduce(lambda x, y: float(x) + float(y), elapse)
58-
elapse_part = ",".join([f"{x:.4f}" for x in elapse])
59-
60-
web_return = self.WebReturn(
44+
def get_ocr_res(self, img: np.ndarray) -> str:
45+
ocr_res = self.ocr(img)
46+
if ocr_res.txts is None:
47+
result = OCRWebOutput(
48+
image="",
49+
total_elapse="0",
50+
elapse_part="",
51+
rec_res="",
52+
)
53+
return json.dumps(asdict(result))
54+
55+
boxes, txts, scores = ocr_res.boxes, ocr_res.txts, ocr_res.scores
56+
scores = [f"{v:.4f}" for v in scores]
57+
rec_res = list(zip(range(len(txts)), txts, scores))
58+
rec_res = json.dumps(rec_res, indent=2, ensure_ascii=False)
59+
60+
det_im = self.draw_text_det_res(np.array(boxes), img)
61+
img_str = self.img_to_base64(det_im)
62+
63+
elapse_part = ",".join([f"{x:.4f}" for x in ocr_res.elapse_list])
64+
65+
web_return = OCRWebOutput(
6166
image=img_str,
62-
total_elapse=f"{total_elapse:.4f}",
67+
total_elapse=f"{ocr_res.elapse:.4f}",
6368
elapse_part=elapse_part,
6469
rec_res=rec_res,
65-
det_boxes=boxes,
6670
)
67-
return json.dumps(web_return._asdict())
71+
return json.dumps(asdict(web_return))
6872

6973
@staticmethod
70-
def img_to_base64(img) -> str:
74+
def img_to_base64(img: np.ndarray) -> str:
7175
img = cv2.imencode(".png", img)[1]
7276
img_str = str(base64.b64encode(img))[2:-1]
7377
return img_str

rapidocr_web/templates/index.html

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
<!DOCTYPE html>
22
<html lang="zh-CN">
3+
34
<head>
45
<meta charset="UTF-8">
56
<meta name="viewport" content="width=device-width, initial-scale=1.0">
67
<title>RapidOCR - 智能文字识别</title>
78
<link rel="stylesheet" type="text/css" href="/static/css/main.css">
8-
<link rel="shortcut icon" href="/static/css/favicon.ico" type="image/x-icon"/>
9+
<link rel="shortcut icon" href="/static/css/favicon.ico" type="image/x-icon" />
910
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
1011
</head>
12+
1113
<body>
1214
<div class="container">
1315
<!-- 头部区域 -->
@@ -23,7 +25,8 @@ <h1 class="main-title">
2325
<i class="fab fa-github"></i>
2426
Star项目
2527
</a>
26-
<a href="https://rapidai.github.io/RapidOCRDocs/main/install_usage/rapidocr_web/usage/" class="docs-link" target="_blank">
28+
<a href="https://rapidai.github.io/RapidOCRDocs/main/install_usage/rapidocr_web/usage/"
29+
class="docs-link" target="_blank">
2730
<i class="fas fa-book"></i>
2831
使用文档
2932
</a>
@@ -44,7 +47,7 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
4447
<i class="fas fa-plus"></i>
4548
选择图片
4649
</button>
47-
<input type="file" style="display: none;" name="pic" id="rapid_ocr" accept="image/*"/>
50+
<input type="file" style="display: none;" name="pic" id="rapid_ocr" accept="image/*" />
4851
</div>
4952
</div>
5053
</section>
@@ -67,7 +70,7 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
6770
<p>正在识别中...</p>
6871
</div>
6972
</div>
70-
<img id="detect_img" src="" alt="检测结果"/>
73+
<img id="detect_img" src="" alt="检测结果" />
7174
<div class="zoom-hint">
7275
<i class="fas fa-search-plus"></i> 点击或滚轮缩放,拖拽移动图片
7376
</div>
@@ -123,7 +126,7 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
123126
<div class="stat-value" id="recTime">0.000s</div>
124127
</div>
125128
</div>
126-
</div>
129+
</div>
127130
</div>
128131
</div>
129132
</div>
@@ -135,7 +138,7 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
135138
<script type="text/javascript">
136139
// 页面加载时,执行
137140
var targetFile = null;
138-
window.onload = function () {
141+
window.onload = function () {
139142
// 移除图片的宽高属性,让CSS控制
140143
$('#detect_img').removeAttr("width").removeAttr("height");
141144

@@ -146,33 +149,33 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
146149
$('#copyAllBtn').hide();
147150

148151
// 绑定复制按钮事件
149-
$('#copyAllBtn').on('click', function() {
152+
$('#copyAllBtn').on('click', function () {
150153
copyAllResults();
151154
});
152155

153156
// 确保函数在全局作用域中可用
154157
window.copyAllResults = copyAllResults;
155158
}
156159

157-
$("#rapid_ocr").on('change', function (){
160+
$("#rapid_ocr").on('change', function () {
158161
targetFile = document.getElementById("rapid_ocr").files[0];
159162
requestOCR();
160163
});
161164

162165
// 拖拽上传
163-
$("html").on("dragover", function(event) {
166+
$("html").on("dragover", function (event) {
164167
event.preventDefault();
165168
event.stopPropagation();
166169
$(this).addClass('dragging');
167170
});
168171

169-
$("html").on("dragleave", function(event) {
172+
$("html").on("dragleave", function (event) {
170173
event.preventDefault();
171174
event.stopPropagation();
172175
$(this).removeClass('dragging');
173176
});
174177

175-
$("html").on("drop", function(event) {
178+
$("html").on("drop", function (event) {
176179
event.preventDefault();
177180
event.stopPropagation();
178181
let trans = event.originalEvent.dataTransfer;
@@ -205,8 +208,8 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
205208
}
206209
}
207210

208-
function requestOCR(){
209-
if (!targetFile){
211+
function requestOCR() {
212+
if (!targetFile) {
210213
return;
211214
}
212215

@@ -215,7 +218,7 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
215218
let index = imageName.lastIndexOf('.');
216219
let extName = imageName.substr(index + 1);
217220
let imgArr = ['webp', 'jpg', 'bmp', 'png', 'jpeg'];
218-
if (!(imgArr.includes(extName.toLocaleLowerCase()))){
221+
if (!(imgArr.includes(extName.toLocaleLowerCase()))) {
219222
showNotification("图像文件格式不支持!", "error");
220223
return;
221224
}
@@ -228,16 +231,16 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
228231
}
229232

230233
var reader = new FileReader();
231-
reader.onload = function(e){
232-
var upload_data = {"file": reader.result};
234+
reader.onload = function (e) {
235+
var upload_data = { "file": reader.result };
233236
$.ajax({
234-
url:"/ocr",
235-
type:"POST",
237+
url: "/ocr",
238+
type: "POST",
236239
data: JSON.stringify(upload_data),
237240
contentType: 'application/json; charset=UTF-8',
238241
dataType: 'json',
239242

240-
beforeSend:function(){
243+
beforeSend: function () {
241244
// 显示结果区域和加载状态
242245
$("#resultsSection").show();
243246
$("#loadingOverlay").show();
@@ -253,7 +256,7 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
253256
$('#detect_img').show();
254257

255258
// 添加图片加载完成后的处理
256-
$("#detect_img").on('load', function() {
259+
$("#detect_img").on('load', function () {
257260
if (typeof adjustImageSizeAdaptive === 'function') {
258261
adjustImageSizeAdaptive(this);
259262
}
@@ -275,17 +278,17 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
275278
}
276279
},
277280

278-
success:function (data) {
281+
success: function (data) {
279282
$("#loadingOverlay").hide();
280283

281-
if (data){
282-
if (data['image']){
283-
$("#detect_img").attr('src', 'data:image/jpeg;base64,'+ data['image']);
284+
if (data) {
285+
if (data['image']) {
286+
$("#detect_img").attr('src', 'data:image/jpeg;base64,' + data['image']);
284287
$("#detect_img").removeAttr("width").removeAttr("height");
285288
$('#detect_img').show();
286289

287290
// 添加图片加载完成后的处理
288-
$("#detect_img").on('load', function() {
291+
$("#detect_img").on('load', function () {
289292
if (typeof adjustImageSizeAdaptive === 'function') {
290293
adjustImageSizeAdaptive(this);
291294
}
@@ -296,7 +299,7 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
296299
});
297300
}
298301

299-
if (data["total_elapse"]){
302+
if (data["total_elapse"]) {
300303
// 更新总耗时显示
301304
var recTimeElement = document.getElementById("rec_time");
302305
if (recTimeElement) {
@@ -305,12 +308,12 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
305308
}
306309
}
307310

308-
if (data["rec_res"]){
311+
if (data["rec_res"]) {
309312
var rec_res = JSON.parse(data["rec_res"]);
310313

311-
if (data['elapse_part']){
314+
if (data['elapse_part']) {
312315
var elapse_list = data['elapse_part'].split(',');
313-
}else{
316+
} else {
314317
var elapse_list = [0, 0, 0];
315318
}
316319

@@ -331,7 +334,7 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
331334

332335
// 根据置信度设置颜色
333336
let confidenceClass = score > 0.8 ? 'high-confidence' :
334-
score > 0.6 ? 'medium-confidence' : 'low-confidence';
337+
score > 0.6 ? 'medium-confidence' : 'low-confidence';
335338

336339
tableData += "<tr>"
337340
tableData += "<td class='row-number'>" + num + "</td>";
@@ -358,7 +361,7 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
358361
}
359362
},
360363

361-
error: function(xhr, status, error) {
364+
error: function (xhr, status, error) {
362365
$("#loadingOverlay").hide();
363366
showNotification("识别失败,请重试", "error");
364367
}
@@ -367,7 +370,7 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
367370
reader.readAsDataURL(targetFile)
368371
}
369372

370-
// 调整图像尺寸,保持宽高比 - 使用新的自适应函数
373+
// 调整图像尺寸,保持宽高比 - 使用新的自适应函数
371374
function adjustImageSize(imgElement) {
372375
if (typeof adjustImageSizeAdaptive === 'function') {
373376
adjustImageSizeAdaptive(imgElement);
@@ -389,7 +392,7 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
389392
}
390393
}
391394

392-
// 显示图片信息
395+
// 显示图片信息
393396
function showImageInfo(imgElement) {
394397
const imageInfo = document.getElementById('imageInfo');
395398
const dimensionsSpan = imageInfo.querySelector('.image-dimensions');
@@ -413,7 +416,7 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
413416
}
414417
}
415418

416-
// 更新性能统计信息
419+
// 更新性能统计信息
417420
function updatePerformanceStats(elapseList, totalElapse) {
418421
const detTime = parseFloat(elapseList[0]);
419422
const clsTime = parseFloat(elapseList[1]);
@@ -435,13 +438,13 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
435438
$("#statsContainer").css('opacity', '0').css('transform', 'translateY(20px)');
436439
setTimeout(() => {
437440
$("#statsContainer").css('transition', 'opacity 0.6s ease, transform 0.6s ease')
438-
.css('opacity', '1').css('transform', 'translateY(0)');
441+
.css('opacity', '1').css('transform', 'translateY(0)');
439442
}, 200);
440443
}
441444

442445

443446

444-
// 复制所有识别结果
447+
// 复制所有识别结果
445448
function copyAllResults() {
446449
console.log('copyAllResults function called');
447450

@@ -575,4 +578,5 @@ <h3 class="upload-title">拖拽图片到这里或点击上传</h3>
575578
}
576579
</script>
577580
</body>
581+
578582
</html>

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
Pillow<=10.0.0
22
requests
33
Flask>=2.1.0, <=3.0.0
4-
rapidocr_onnxruntime>=1.3.0,<=2.0.0
4+
rapidocr>=3.0.0

0 commit comments

Comments
 (0)