使用opencv的onnxruntime推理
时间: 2025-05-03 22:45:32 浏览: 26
### YOLOv8 结合 OpenCV 和 ONNXRuntime 的模型推理教程
#### 1. 环境准备
为了成功运行基于 OpenCV 和 ONNXRuntime 的模型推理,需满足以下环境需求[^3]:
- **OpenCV**: 版本 >= 4.7.0。此版本引入了更强大的 `cv::dnn` 模块功能,可以更好地支持 ONNX 模型加载和推理。
- **ONNXRuntime**: 推荐使用版本 >= 1.9.0,该版本优化了对 ONNX 模型的支持。
可以通过以下命令安装所需依赖项(以 Linux 平台为例):
```bash
sudo apt-get install libopencv-dev python3-opencv
pip install onnxruntime-gpu
```
---
#### 2. 加载 ONNX 模型
在 C++ 中,借助 OpenCV 的 `cv::dnn::readNetFromONNX()` 函数可以直接加载 ONNX 格式的模型文件。以下是具体代码示例:
```cpp
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace dnn;
// 加载 ONNX 模型
Net model = readNetFromONNX("yolov8.onnx");
if (model.empty()) {
std::cerr << "Error: Model not loaded." << std::endl;
}
```
上述代码片段展示了如何通过指定路径加载 `.onnx` 文件,并验证模型是否成功加载[^2]。
---
#### 3. 图像预处理
YOLOv8 需要输入特定尺寸的张量数据,在实际应用中通常会将图片调整到固定大小(如 640x640)。下面是一段完整的图像预处理逻辑:
```cpp
Mat frame = imread("input_image.jpg"); // 读取原始图像
if (frame.empty()) {
std::cerr << "Error: Image could not be read." << std::endl;
}
// 调整图像大小至网络输入要求
Mat blob;
Size input_size(640, 640); // 输入分辨率
blobFromImage(frame, blob, 1 / 255.0, input_size, Scalar(), true, false);
```
这里的关键函数是 `blobFromImage()`,它负责完成如下操作:
- 将像素值归一化到 `[0, 1]` 范围;
- 缩放图像至目标尺寸;
- 添加通道维度以便适配神经网络输入格式。
---
#### 4. 执行前向传播
一旦完成了模型加载与数据预处理工作,则可调用 `forward()` 方法来获取预测结果:
```cpp
std::vector<String> outputNames = {"output"};
model.setInput(blob);
Mat detections = model.forward(outputNames[0]);
```
此处需要注意的是,不同框架导出的 ONNX 模型可能具有不同的输出层名称列表。因此建议先查阅官方文档确认具体的输出节点名[^1]。
---
#### 5. 后处理阶段
最后一步是从返回的结果矩阵提取有用信息并绘制边界框。假设每条记录包含类别索引、置信度分数以及坐标位置等字段,则对应的解码过程大致如下所示:
```cpp
float confidenceThreshold = 0.5f; // 设置阈值过滤低质量检测
for(int i=0;i<detections.rows;++i){
float* dataPtr=(float*)detections.ptr<float>(i);
int classId=int(dataPtr[0]); // 类别ID
float conf=dataPtr[1]; // 置信度得分
Rect box(Rect((int)dataPtr[2],(int)dataPtr[3],
(int)(dataPtr[4]-dataPtr[2]),
(int)(dataPtr[5]-dataPtr[3]))); // 边界框区域
if(conf >confidenceThreshold ){
rectangle(frame,box,Scalar(0,255,0),2); // 绘制矩形边框
putText(frame,std::to_string(classId),
Point(box.x,box.y-5),FONT_HERSHEY_SIMPLEX,
0.5,Scalar(0,255,0)); // 显示标签文字
}
}
imshow("Detection Results",frame); // 展现最终效果图
waitKey();
destroyAllWindows();
```
以上即为整个流程的核心部分说明。
---
阅读全文
相关推荐














