e
gcw_GSiqzzLf/simple_symbol_det-npu
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

simple_symbol_det - 符号检测模型 (昇腾 NPU 适配)

模型介绍

simple_symbol_det 是一个基于 DbNet (Differentiable Binarization Network) 的文本检测模型,支持英文、数字、标点符号、数学符号、拼音、音标、Emoji 的文本检测。

该模型使用 PyTorch 框架训练,导出为 ONNX 格式进行推理,能够检测图像中的各类文字和符号区域,输出文本检测框。

原始模型地址

  • ModelScope: csg800/simple_symbol_det

任务类型

  • OCR 文字检测 (ocr-detection)
  • 文本检测 (Text Detection)

模型框架

  • PyTorch (训练)
  • ONNX (推理)

输入格式

  • 形状: [batch_size, 1, height, width],类型为 float32
  • 灰度图像,像素值归一化到 [0, 1]
  • 预处理尺寸: 768 x 768 (保持宽高比,不足部分填充白色)

输出格式

  • 形状: [batch_size, output_height, output_width],类型为 float32
  • 输出为概率图,每个像素表示属于文本区域的概率 (0~1)
  • 经过阈值化和后处理得到文本检测框 (四边形四点坐标)

依赖环境

依赖版本
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

NPU 适配说明

该模型以 ONNX 格式提供,通过 ONNX Runtime CANN ExecutionProvider 实现在华为昇腾 NPU 上的推理。适配过程无需修改模型结构,仅需在加载模型时指定 CANNExecutionProvider 作为执行引擎。

适配要点

  1. 使用 onnxruntime-cann 替代标准 onnxruntime,即可获得 CANN 执行引擎支持
  2. CPU 与 NPU 使用完全相同的预处理和后处理代码
  3. 模型在 NPU 上检测结果与 CPU 高度一致,检测框坐标完全一致

环境准备

# 安装基础依赖
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-cann

推理命令

使用 CPU 推理

cd /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.jpg

使用 NPU 推理

python3 inference.py \
  --model_path /path/to/last.onnx \
  --image_path ./test_text.jpg \
  --provider CANNExecutionProvider \
  --draw ./result_npu.jpg

CPU vs NPU 精度对比

python3 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 ms4.95 ms
推理加速比1x32.2x

NPU 推理在保持精度的同时,相比 CPU 推理获得了约 32 倍的性能提升。

推理终端输出

检测框详情

序号CPU 得分NPU 得分得分差异
10.71640.71640.0000
20.75320.75330.0001
30.64550.64550.0000
40.79170.79190.0002
50.69410.69390.0002

CPU 和 NPU 的检测框坐标完全一致(平均坐标差异 0.00 像素)。

CPU/NPU 精度测试方法

  1. 同时使用 ONNX Runtime CPUExecutionProvider 和 CANNExecutionProvider 加载模型
  2. 对同一张测试图像进行预处理,确保输入完全一致
  3. 分别运行推理,记录输出概率图
  4. 对比指标:
    • 输出概率图数值对比: 计算最大/平均绝对误差、相对误差、MSE
    • 二值化预测一致率: 判断二值化后每个像素是否一致
    • 检测框数量一致率: 对比 CPU 和 NPU 检测到的文本区域数量
    • 检测框坐标差异: 对比每个框的四点坐标差异
    • 检测得分差异: 对比每个框的置信度得分

CPU/NPU 精度测试结果

精度指标数值
检测框数量一致是 (均为 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.221x
NPU (CANN)4.9532.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_ratios

检测框提取

def 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 上推理成功。

模型标签

  • #+NPU
  • #+CV
  • #+OCR
  • #+文字检测
  • #+昇腾
  • #+文本检测
  • #+DbNet
  • #+ONNX