【算法介绍】
在C++中使用纯OpenCV部署YOLOv11-seg进行实例分割是一项具有挑战性的任务,因为YOLOv11通常是用PyTorch等深度学习框架实现的,而OpenCV本身并不直接支持加载和运行PyTorch模型。然而,可以通过一些间接的方法来实现这一目标,比如将PyTorch模型转换为ONNX格式,然后使用OpenCV的DNN模块加载ONNX模型。
部署过程大致如下:首先,需要确保开发环境已经安装了OpenCV 4.x(带有DNN模块)和必要的C++编译器。然后,将YOLOv11-seg模型从PyTorch转换为ONNX格式,这通常涉及使用PyTorch的torch.onnx.export函数。接下来,使用OpenCV的DNN模块加载ONNX模型,并准备好模型的配置文件和类别名称文件。
在模型推理阶段,需要预处理输入图像(如调整大小、归一化等)以符合模型的输入要求,将预处理后的图像输入到模型中,并获取分割结果。对结果进行后处理,包括解析输出、应用非极大值抑制(NMS)和绘制分割边界等。
需要注意的是,由于YOLOv11-seg是一个复杂的模型,其输出可能包含多个层的信息,因此需要仔细解析模型输出,并根据YOLOv11-seg的具体实现进行后处理。此外,由于OpenCV的DNN模块对ONNX的支持可能有限,某些YOLOv11-seg的特性可能无法在OpenCV中直接实现,这时可能需要寻找替代方案。
总之,使用纯OpenCV部署YOLOv11-seg需要深入理解模型架构、OpenCV的DNN模块以及ONNX格式。
【效果展示】
【实现部分代码】
#include <iostream>
#include<opencv2/opencv.hpp>
#include<math.h>
#include "yolov11_seg.h"
#include<time.h>
#define VIDEO_OPENCV //if define, use opencv for video.
using namespace std;
using namespace cv;
using namespace dnn;
template<typename _Tp>
int yolov11(_Tp& task, cv::Mat& img, std::string& model_path)
{
cv::dnn::Net net;
if (task.ReadModel(net, model_path, false)) {
std::cout << "read net ok!" << std::endl;
}
else {
return -1;
}
//生成随机颜色
std::vector<cv::Scalar> color;
srand(time(0));
for (int i = 0; i < 80; i++) {
int b = rand() % 256;
int g = rand() % 256;
int r = rand() % 256;
color.push_back(cv::Scalar(b, g, r));
}
std::vector<OutputParams> result;
bool isPose = false;
if (typeid(task) == typeid(Yolov8Pose)) {
isPose = true;
}
PoseParams poseParams;
if (task.Detect(img, net, result)) {
if (isPose)
DrawPredPose(img, result, poseParams);
else
DrawPred(img, result, task._className, color);
}
else {
std::cout << "Detect Failed!" << std::endl;
}
system("pause");
return 0;
}
template<typename _Tp>
int video_demo(_Tp& task, std::string& model_path)
{
std::vector<cv::Scalar> color;
srand(time(0));
for (int i = 0; i < 80; i++) {
int b = rand() % 256;
int g = rand() % 256;
int r = rand() % 256;
color.push_back(cv::Scalar(b, g, r));
}
std::vector<OutputParams> result;
cv::VideoCapture cap("car.mp4");
if (!cap.isOpened())
{
std::cout << "open capture failured!" << std::endl;
return -1;
}
cv::Mat frame;
cv::dnn::Net net;
if (task.ReadModel(net, model_path, true)) {
std::cout << "read net ok!" << std::endl;
}
else {
std::cout << "read net failured!" << std::endl;
return -1;
}
while (true)
{
cap.read(frame);
if (frame.empty())
{
std::cout << "read to end" << std::endl;
break;
}
result.clear();
if (task.Detect(frame, net, result)) {
DrawPred(frame, result, task._className, color,true);
}
int k = waitKey(10);
if (k == 27) { //esc
break;
}
}
cap.release();
system("pause");
return 0;
}
int main() {
string detect_model_path = "./yolo11n-seg.onnx";
Yolov11Seg detector;
video_demo(detector, detect_model_path);
}
【视频演示】
https://download.csdn.net/download/FL1623863129/89848150
【测试环境】
vs2019
cmake==3.24.3
opencv==4.8.0
【运行步骤】
下载模型:https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11n-seg.pt
转换模型:yolo export model=yolo11n-seg.pt format=onnx dynamic=False opset=12
编译项目源码,将模型,视频路径对应到源码即可运行