使用OpenCV推理Yolov8模型(C++)
概述
众所周知,Yolo模型的推理和训练往往依托于PyTorch框架,语言为python,那么如果你使用的是opencv-python的版本,就完全不需要关心该如何配置模型的推理,因为我们完全可以使工程环境中同时包含opencv-pyhon和torch,使用PyTorch框架负责.pt模型进行推理,然后使用OpenCV去完成其他的工作,如根据模型的输出去绘制目标框和标签。
那么在C++环境下,我们如何用OpenCV去使用Yolo模型,如何用GPU去做到对模型推理的加速,请见本文。
yolov8官方文档
https://github.com/ultralytics/ultralytics/
仅以yolov8为例,事实上官方给予了我们在C++环境下使用opencv对yolov8模型推理的源码,就在工程源码当中:

ONNXRuntime也是一种常见的支持cpu或者gpu加速通用模型推理框架,是由微软开发的,可以对模型进行优化加快推理速度,.onnx格式是通用模型格式,值得注意的是该框架目前还并不支持RAM架构的处理器,支持x64架构等,因此还没办法将该架构应用于工控机。
我们需要使用的就是YOLOv8-CPP-Inference中的程序。
导出ONNX格式模型
当我们使用Yolov8在PyTorch框架上完成对模型的训练,我们将在run/weights目录下得到了best.pt和last.pt,而这个格式是PyTorch框架的模型格式。
在OpenCV的C++版本的dnn模块支持多种格式模型的推理(包括.onnx格式但不包括.pt格式),因此我们在使用之前,首先要将.pt格式模型转换成.onnx格式模型。
【方式一】
我们可以在我们的Yolov8环境中使用该脚本对模型格式进行转换:
from ultralytics import YOLO
# Load a model
model = YOLO(r"替换为模型位置") # load a pretrained model (recommended for training)
success = model.export(format="onnx") # export the model to ONNX format #转换为onnx模型
print('model.export success')运行此脚本,假如我有boxs_bsaket.pt,可得:

【方式二】
如果你是使用pip指令安装的Yolov8环境,也可以在终端使用以下指令,导出.onnx格式模型:
yolo`` export model=best.pt imgsz=640 format=onnx opset=12
YOLOv8-CPP-Inference程序
这里只说使用时需要修改的地方(红色标注),还有必要的知识(蓝色标注):
【main.cpp】

【Inference.h】

【Inference.cpp】

测试
我使用官方模型和图片进行测试,运行程序获得:


这里是推理的图片,如果你希望推理视频流,仅需要将main.cpp稍微修改就好。
上述部分是使用C++环境下OpenCV使用CPU进行推理的,如果你希望进行OpenCV使用GPU推理见下部分。
OpenCV_CUDA部署
OpenCV不默认支持GPU运行,也就说,如果你是在官网使用releases下载安装包安装,则默认不支持使用英伟达显卡加速。
如果你想进行GPU推理并且你的设备有INVIDA独显可以尝试,但是如果你的设备首次下载并不是在官网下载源码手动编译的话,就需要将您的OpenCV卸载,去到官网下载源码,进行手动编译安装,并在CMake安装过程中勾选CUDA选项。
Windows具体教程见:
手动编译非常耗时,并且坑极多,如果要配置,请有耐心并能积极自主解决问题!!!
再此补充一个BUG,在CUDA Toolkit >= 12.2.0以上,OpenCV4.8及以下,会出现 error C2666: 'operator !=': overloaded functions have similar conversions 解决方法请参考这里
Linux上部署OpenCV_CUDA教程 :
请详看下方文档中的部署显卡驱动、CUDA、cuDNN、OpenCV等内容。
显卡驱动、CUDA、cuDNN部署教程:Linux教程
OpenCV_CUDA部署教程:OpenCV CUDA环境搭建
GPU推理注意事项
如果你此时已经部署好了OpenCV_CUDA,那么当你部署模型的时候,需要注意以下几个地方是和CPU部署不同的:
.onnx模型导出bug
如果你想使用OpenCV进行Yolov8模型的gpu推理,将不再能使用第二部分中【方法二】的方式导出模型,你只能Git yolov8的源码到工程中使用【方法一】,并且你需要更改Yolov8的源码,具体更改位置如下:

main.cpp中参数
bool runOnGPU = true;


