kocr/core/recognizer.py

90 lines
3.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""KOCR v5 — OCR 识别模块(简化版:原图直出,无预处理)"""
import cv2
from paddleocr import PaddleOCR
_ocr = None
def get_ocr_instance(config: dict):
"""懒加载 PaddleOCR 实例"""
global _ocr
if _ocr is None:
_ocr = PaddleOCR(
use_angle_cls=config.get('use_angle_cls', True),
lang=config.get('lang', 'ch'),
use_gpu=config.get('use_gpu', False),
show_log=config.get('show_log', False),
det_db_thresh=config.get('det_db_thresh', 0.3),
det_db_box_thresh=config.get('det_db_box_thresh', 0.5),
det_db_unclip_ratio=config.get('det_db_unclip_ratio', 2.2),
det_limit_side_len=config.get('max_side_len', 1600),
det_db_score_mode=config.get('det_db_score_mode', 'slow'),
min_size=config.get('min_size', 8),
rec_drop_score=config.get('rec_drop_score', 0.5),
)
return _ocr
def run_ocr(image, ocr_config: dict, photo_type: str = 'normal') -> list:
"""对图像执行 OCR返回 [(text, confidence, cx, cy, box), ...]
输入:
image: numpy array (cv2.imread) 或 图像文件路径
ocr_config: dictPaddleOCR 参数)
photo_type: str — 照片类型,用于动态调参
返回:
排序后的 lines: [(text, conf, cx, cy, box), ...]
按 (y, x) 排序
"""
# 根据照片类型动态调整 OCR 参数
config_override = dict(ocr_config)
if photo_type == 'flash':
config_override['det_db_thresh'] = config_override.get('det_db_thresh_flash', 0.18)
elif photo_type == 'dark':
config_override['det_db_thresh'] = config_override.get('det_db_thresh_dark', 0.25)
elif photo_type == 'blurry':
config_override['det_db_thresh'] = config_override.get('det_db_thresh_blurry', 0.2)
# normal 保持默认
ocr = get_ocr_instance(config_override)
# 支持 numpy array 和 文件路径
result = ocr(image)
# PaddleOCR v2.8 返回格式多变,兼容处理
lines_raw = []
if result is None:
return []
# tuple of 3: (boxes, texts, elapsed)
if isinstance(result, tuple) and len(result) >= 2:
boxes = result[0]
texts = result[1]
if boxes and texts:
for box, (text, conf) in zip(boxes, texts):
if conf < 0.4:
continue
cx = float((box[0][0] + box[2][0]) / 2)
cy = float((box[0][1] + box[2][1]) / 2)
lines_raw.append((text, conf, cx, cy, box))
# 旧版格式: list of [[box], (text, conf), ...]
elif isinstance(result, list):
for item in result:
if isinstance(item, (list, tuple)) and len(item) >= 2:
box = item[0]
if isinstance(box, (list, tuple)) and len(box) >= 1:
text, conf = item[1]
if conf < 0.4:
continue
cx = float((box[0][0] + box[2][0]) / 2)
cy = float((box[0][1] + box[2][1]) / 2)
lines_raw.append((text, conf, cx, cy, box))
# 按 y 排序(从上到下),同 y 按 x 排序(从左到右)
lines_raw.sort(key=lambda l: (l[3], l[2]))
return lines_raw