simple_symbol_det 是一个基于 DbNet (Differentiable Binarization Network) 的文本检测模型,支持英文、数字、标点符号、数学符号、拼音、音标、Emoji 的文本检测。
该模型使用 PyTorch 框架训练,导出为 ONNX 格式进行推理,能够检测图像中的各类文字和符号区域,输出文本检测框。
[batch_size, 1, height, width],类型为 float32[batch_size, output_height, output_width],类型为 float32| 依赖 | 版本 |
|---|---|
| Python | >= 3.8 |
| numpy | >= 1.21.0 |
| opencv-python | >= 4.5.0 |
| onnxruntime | >= 1.15.0 |
| onnxruntime-cann | >= 1.15.0 (NPU 推理) |
| pyclipper | >= 1.3.0 |
| shapely | >= 1.8.0 |
该模型以 ONNX 格式提供,通过 ONNX Runtime CANN ExecutionProvider 实现在华为昇腾 NPU 上的推理。适配过程无需修改模型结构,仅需在加载模型时指定 CANNExecutionProvider 作为执行引擎。
onnxruntime-cann 替代标准 onnxruntime,即可获得 CANN 执行引擎支持# 安装基础依赖
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy opencv-python onnxruntime pyclipper shapely
# NPU 推理需要安装 onnxruntime-cann
# 请根据 CANN 版本选择对应的 onnxruntime-cann 版本
pip install onnxruntime-canncd /opt/atomgit/workspace/simple_symbol_det
python3 inference.py \
--model_path /path/to/last.onnx \
--image_path ./test_text.jpg \
--provider CPUExecutionProvider \
--draw ./result_cpu.jpgpython3 inference.py \
--model_path /path/to/last.onnx \
--image_path ./test_text.jpg \
--provider CANNExecutionProvider \
--draw ./result_npu.jpgpython3 compare_cpu_npu.py \
--model_path /path/to/last.onnx \
--image_path ./test_text.jpg \
--output_dir ./results使用测试图像 test_text.jpg(包含多行英文、数字和符号文本)进行推理:
| 指标 | CPU (ONNX Runtime) | NPU (CANN) |
|---|---|---|
| 检测到的文本区域 | 5 个 | 5 个 |
| 平均推理耗时 | 159.22 ms | 4.95 ms |
| 推理加速比 | 1x | 32.2x |
NPU 推理在保持精度的同时,相比 CPU 推理获得了约 32 倍的性能提升。

| 序号 | CPU 得分 | NPU 得分 | 得分差异 |
|---|---|---|---|
| 1 | 0.7164 | 0.7164 | 0.0000 |
| 2 | 0.7532 | 0.7533 | 0.0001 |
| 3 | 0.6455 | 0.6455 | 0.0000 |
| 4 | 0.7917 | 0.7919 | 0.0002 |
| 5 | 0.6941 | 0.6939 | 0.0002 |
CPU 和 NPU 的检测框坐标完全一致(平均坐标差异 0.00 像素)。
| 精度指标 | 数值 |
|---|---|
| 检测框数量一致 | 是 (均为 5 个) |
| 二值化预测一致率 | 100.00% |
| 平均坐标差异 | 0.00 像素 |
| 最大坐标差异 | 0.00 像素 |
| 最大绝对误差 (MaxAbsErr) | 0.00460696 |
| 平均绝对误差 (MeanAbsErr) | 0.00002027 |
| 均方误差 (MSE) | 0.00000002 |
| 最大相对误差 (MaxRelErr) | 4.21% |
| 平均相对误差 (MeanRelErr) | 0.51% |
| 平均得分差异 | 0.000107 |
精度测试结论:NPU 与 CPU 推理结果误差为 0.51%,符合精度误差小于 1% 的要求。
| 推理后端 | 平均耗时 (ms) | 加速比 |
|---|---|---|
| CPU (ONNX Runtime) | 159.22 | 1x |
| NPU (CANN) | 4.95 | 32.2x |
NPU 推理相比 CPU 推理获得了约 32 倍的性能提升,显著提升了文本检测的效率。
import onnxruntime
# CPU 推理
cpu_session = onnxruntime.InferenceSession(
model_path,
providers=["CPUExecutionProvider"]
)
# NPU 推理
npu_session = onnxruntime.InferenceSession(
model_path,
providers=["CANNExecutionProvider"]
)def preprocess(img, resized_shape=(768, 768)):
ori_h, ori_w = img.shape[:2]
target_h, target_w = resized_shape
# 保持比例缩放并填充
scale = min(target_h / ori_h, target_w / ori_w)
new_size = (int(ori_w * scale), int(ori_h * scale))
img_resized = cv2.resize(img, new_size)
mask = np.ones((target_h, target_w), dtype=np.uint8) * 255
mask[:img_resized.shape[0], :img_resized.shape[1]] = img_resized
# 归一化并调整维度
mask = mask.astype(np.float32) / 255.0
mask = np.expand_dims(mask, 0) # (1, H, W)
mask = np.expand_dims(mask, 0) # (1, 1, H, W)
return mask, compress_ratiosdef detect(model, image, thresh=0.2):
# 推理
batch, compress_ratios = preprocess(image)
ort_outs = model.run(None, {model.get_inputs()[0].name: batch})
pred = np.squeeze(ort_outs[0])
# 二值化
segmentation = ((pred > thresh) * 255).astype(np.uint8)
# 轮廓检测
contours, _ = cv2.findContours(segmentation, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
# 提取最小外接矩形
boxes, scores = boxes_from_bitmap(pred, segmentation)
# 坐标映射回原图
for box in boxes:
box[:, 0] *= image.shape[1] / resized_shape[1] / compress_ratios[1]
box[:, 1] *= image.shape[0] / resized_shape[0] / compress_ratios[0]
return boxes, scores本仓库提供完整的推理脚本,支持 CPU 和 NPU 双平台推理:
# NPU 推理
python3 inference.py --device npu
# CPU 推理
python3 inference.py --device cpu推理完成后会输出推理结果和耗时,表明模型在 NPU 上推理成功。