ONNX导出后怎么用?cv_resnet18_ocr-detection跨平台部署教程
1. 教程目标与适用人群
你是否已经训练好了一个OCR文字检测模型,却不知道如何把它用到其他设备上?比如手机、嵌入式设备或者没有GPU的服务器?
本教程将手把手带你完成cv_resnet18_ocr-detection模型从ONNX导出到实际推理调用的全过程。无论你是AI新手还是有一定经验的开发者,都能快速掌握:
- 如何在WebUI中一键导出ONNX模型
- ONNX模型的结构和输入输出格式解析
- 跨平台Python推理代码实现
- 常见问题排查与性能优化建议
整个过程无需编写复杂代码,基于科哥构建的镜像环境即可完成,真正做到“小白友好、开箱即用”。
2. 环境准备与模型导出
2.1 启动服务并进入ONNX导出界面
首先确保你已经成功运行了cv_resnet18_ocr-detection镜像,并启动了WebUI服务。
cd /root/cv_resnet18_ocr-detection bash start_app.sh服务启动后,在浏览器访问:http://你的服务器IP:7860
点击顶部导航栏的“ONNX 导出” Tab页,进入模型导出界面。
2.2 设置输入尺寸并导出模型
在ONNX导出页面中,你需要设置两个关键参数:
| 参数 | 说明 |
|---|---|
| 输入高度 | 模型接受的图片高度(单位:像素) |
| 输入宽度 | 模型接受的图片宽度(单位:像素) |
默认值为800x800,适用于大多数场景。如果你追求更快的推理速度,可以选择640x640;若需要更高精度识别小字,可选择1024x1024。
提示:输入尺寸越大,模型对细节保留越好,但推理时间更长、内存占用更高。
设置完成后,点击“导出 ONNX”按钮,系统会自动开始转换流程。
导出成功后,你会看到类似以下提示:
导出成功!文件路径:/root/cv_resnet18_ocr-detection/model_800x800.onnx,大小:35.2MB此时你可以点击“下载 ONNX 模型”将.onnx文件保存到本地。
3. ONNX模型结构解析
3.1 什么是ONNX?
ONNX(Open Neural Network Exchange)是一种开放的神经网络交换格式,支持跨框架、跨平台部署。它允许你在PyTorch训练的模型导出后,用TensorRT、OpenVINO、ONNX Runtime等引擎在不同设备上运行。
这意味着:
可以脱离原始训练环境
支持CPU/GPU/NPU多种硬件加速
易于集成进C++、Java、JavaScript等生产系统
3.2 模型输入输出分析
通过查看源码和推理逻辑,我们可以确定该模型的输入输出规范如下:
输入张量(input)
- 名称:
input - 形状:
(1, 3, H, W)1:batch size(目前仅支持单图)3:RGB三通道H:高度(如800)W:宽度(如800)
- 数据类型:
float32 - 值范围:
[0, 1](需归一化)
输出张量(outputs)
模型返回多个结果,主要包括:
| 输出名称 | 含义 | 形状示例 |
|---|---|---|
boxes | 检测框坐标(四点) | (N, 8) |
scores | 置信度分数 | (N,) |
texts | 识别文本内容(需配合OCR识别头) | 列表形式 |
其中每个检测框由[x1,y1,x2,y2,x3,y3,x4,y4]表示一个四边形区域。
4. Python环境下的ONNX推理实战
4.1 安装依赖库
要运行ONNX模型,你需要安装onnxruntime和图像处理库:
pip install onnxruntime opencv-python numpy推荐使用GPU版本以提升性能:
pip install onnxruntime-gpu # 若有NVIDIA显卡4.2 完整推理代码示例
下面是一个完整的Python脚本,用于加载ONNX模型并进行文字检测:
import onnxruntime as ort import cv2 import numpy as np import time # 加载ONNX模型 model_path = "model_800x800.onnx" session = ort.InferenceSession(model_path, providers=['CUDAExecutionProvider']) # 使用GPU # 读取测试图片 image = cv2.imread("test.jpg") ori_h, ori_w = image.shape[:2] # 图像预处理 input_h, input_w = 800, 800 input_blob = cv2.resize(image, (input_w, input_h)) input_blob = input_blob.transpose(2, 0, 1)[np.newaxis, ...].astype(np.float32) / 255.0 # 执行推理 start_time = time.time() outputs = session.run(None, {"input": input_blob}) inference_time = time.time() - start_time # 解析输出 boxes = outputs[0] # 形状: (N, 8) scores = outputs[1] # 形状: (N,) # texts = outputs[2] # 如果包含识别结果 print(f"推理耗时: {inference_time:.3f}s") print(f"检测到 {len(boxes)} 个文本区域") # 可视化结果 vis_image = image.copy() for i, box in enumerate(boxes): if scores[i] < 0.2: # 过滤低置信度框 continue pts = box.reshape(4, 2).astype(int) cv2.polylines(vis_image, [pts], isClosed=True, color=(0, 255, 0), thickness=2) cv2.imwrite("detection_result.png", vis_image) print("结果已保存至 detection_result.png")4.3 关键步骤说明
| 步骤 | 注意事项 |
|---|---|
| 图像缩放 | 必须与导出时设定的尺寸一致(如800x800) |
| 通道顺序 | OpenCV是HWC,需转为CHW |
| 归一化 | 除以255.0,确保输入在[0,1]区间 |
| provider选择 | CPU用'CPUExecutionProvider',GPU用'CUDAExecutionProvider' |
5. 跨平台部署实践指南
5.1 在无GPU服务器上部署
很多生产环境只有CPU资源。这时可以使用ONNX Runtime的CPU模式高效运行模型。
session = ort.InferenceSession(model_path, providers=['CPUExecutionProvider'])虽然速度比GPU慢,但在Intel Xeon或AMD EPYC等高性能CPU上仍能达到每秒1~3帧的速度,适合轻量级OCR服务。
性能优化建议:
- 使用
onnxruntime-silicon(Mac M系列芯片) - 开启多线程:
session_options.intra_op_num_threads = 4 - 减小输入分辨率至
640x640
5.2 移动端部署可行性分析
虽然当前ONNX模型体积约35MB,直接用于移动端略大,但可通过以下方式优化:
| 方法 | 效果 |
|---|---|
| 模型剪枝 | 减少参数量,降低计算量 |
| 量化(INT8) | 模型体积减半,推理提速30%以上 |
| TensorRT转换 | 在安卓+NV GPU设备上极致加速 |
注意:原生ONNX不支持直接在Android/iOS运行,需借助ONNX Runtime Mobile或转换为NCNN/TFLite格式。
5.3 Web前端部署方案
想把模型嵌入网页?可以用ONNX.js实现浏览器内推理:
<script src="https://cdn.jsdelivr.net/npm/onnxjs/dist/onnx.min.js"></script>但由于模型较大且WebGL算力有限,建议仅用于演示。生产环境推荐采用“前端上传 → 后端推理 → 返回结果”的架构。
6. 常见问题与解决方案
6.1 导出失败怎么办?
现象:点击“导出ONNX”后提示“导出失败”
可能原因及解决方法:
| 原因 | 解决方案 |
|---|---|
| 输入尺寸不在范围内 | 修改为320~1536之间的数值 |
| 磁盘空间不足 | 清理日志或扩容存储 |
| PyTorch版本不兼容 | 检查torch.onnx.export是否报错 |
| 模型未正确加载 | 重启服务再试 |
建议查看控制台输出日志定位具体错误。
6.2 推理结果为空或漏检严重
问题:图片中有文字,但模型没检测出来
应对策略:
- 调整检测阈值:在代码中降低
scores的过滤阈值(例如从0.3降到0.1) - 检查图像质量:模糊、过暗、倾斜都会影响效果
- 尝试不同输入尺寸:高分辨率有助于检测小字
- 预处理增强对比度:
# 提升对比度(适用于灰暗图片) clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB) l, a, b = cv2.split(lab) l = clahe.apply(l) merged = cv2.merge([l,a,b]) enhanced = cv2.cvtColor(merged, cv2.COLOR_LAB2BGR)6.3 内存溢出或程序崩溃
常见于批量处理或多进程场景
解决方案:
- 单次处理不超过10张图片
- 使用生成器逐张读取而非一次性加载
- 添加异常捕获防止中断:
try: outputs = session.run(None, {"input": input_blob}) except Exception as e: print(f"推理失败: {e}") continue7. 实际应用场景推荐
7.1 文档扫描与电子化
适用于合同、发票、证件等结构化文档的文字提取。
推荐设置:
- 输入尺寸:
800x800 - 检测阈值:
0.25 - 图片要求:清晰、正视角、光线均匀
7.2 屏幕截图OCR识别
适合从App界面、网页截图中提取信息。
注意事项:
- 字体边缘锯齿较多,建议适当降低阈值(
0.15~0.2) - 可先做锐化处理增强边缘
7.3 复杂背景广告图识别
如海报、宣传单上的文字检测。
挑战:
- 背景干扰多
- 字体艺术化变形
建议做法:
- 提高检测阈值至
0.3~0.4减少误检 - 结合后处理规则过滤非中文字符
8. 总结
8.1 核心要点回顾
本文详细讲解了如何将cv_resnet18_ocr-detection模型从WebUI环境中导出为ONNX格式,并实现跨平台部署:
- 学会了在WebUI中一键导出ONNX模型
- 掌握了ONNX模型的输入输出格式与预处理流程
- 实现了Python环境下的完整推理代码
- 了解了在CPU、移动端、Web等不同平台的应用方式
- 解决了导出失败、结果为空、内存溢出等常见问题
8.2 下一步学习建议
如果你想进一步提升OCR系统的实用性,可以考虑:
- 将检测模型与识别模型串联,实现端到端OCR
- 使用OpenVINO或TensorRT进行高性能推理优化
- 构建REST API接口供其他系统调用
- 训练自定义数据集以适应特定场景(如手写体、车牌等)
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。