文章介绍
本文是篇基于yolov5模型的一个工程,主要是利用c++将yolov5模型进行调用并测试,从而实现目标检测任务 任务过程中主要重点有两个,第一 版本问题,第二配置问题
一,所需软件及版本
yolo的模型需要转换为C++模式 运行 yolov5 6.0版本以上的转化后就没有 .pt 后缀 只有
训练部分 pytorch==1.13.0 opencv==3.4.1 其他的直接pip即可
c++部署
vs2019或者vs2022
libtorch-1.13.0 去官网上面下载就行
opencv==3.4.1 链接:https://pan.baidu.com/s/1XPWUNfS7PTFiDkHTG8yvcQ
提取码:d9g4
有的可能需要cmake反正我没用 链接:https://pan.baidu.com/s/1-eLo7ecgQg94Mjtw-pQcXw
提取码:rg0x
二,安装vs
官网地址:
Visual Studio 较旧的下载 - 2019、2017、2015 和以前的版本
上诉链接可能为2017推荐安装 Visual Studio Installer 2019或者2022
环境配置以及任务准备可以借鉴我上一篇文章
libtorch-yolov5部署pytorch版本_该醒醒了~的博客-CSDN博客
好的屁话不多说,正文开始
首先在vs中创建新文件
在源文件中新建一个cpp文件,在头文件新建一个.h 头文件
下载yolov5 libtorch
文件链接:https://pan.baidu.com/s/1oIP1btJd10gQddxAHijg7w
提取码:lntf
- 粘贴 src/YoloV5.cpp 中的代码到上面的 YoloV5.cpp 文件中
- 粘贴 nclude/YoloV5.h 中的代码到上面的 YoloV5.h 文件中
- 更改 YoloV5.cpp 中头文件引入方式为 "YoloV5.h
- "
改为
在源文件里新建一个main.cpp 文件 此文件是用来调用yolov5的
将代码复制到main.cpp中
这是读取摄像头实时监测的
#include "YoloV5.h"
int main()
{
// 第二个参数为是否启用 cuda 详细用法可以参考 YoloV5.h 文件
YoloV5 yolo("C:/Users/hwx/Documents/Github/YoloV5-LibTorch/test/yolov5s.cuda.pt", true);
// 读取分类标签(我们用的官方的所以这里是 coco 中的分类)
// 其实这些代码无所谓哪 只是后面预测出来的框没有标签罢了
std::ifstream f("C:/Users/hwx/Documents/Github/YoloV5-LibTorch/test/coco.txt");
std::string name = "";
int i = 0;
std::map<int, std::string> labels;
while (std::getline(f, name))
{
labels.insert(std::pair<int, std::string>(i, name));
i++;
}
// 用 OpenCV 打开摄像头读取文件(你随便咋样获取图片都OK哪)
cv::VideoCapture cap = cv::VideoCapture(0);
// 设置宽高 无所谓多宽多高后面都会通过一个算法转换为固定宽高的
// 固定宽高值应该是你通过YoloV5训练得到的模型所需要的
// 传入方式是构造 YoloV5 对象时传入 width 默认值为 640,height 默认值为 640
cap.set(cv::CAP_PROP_FRAME_WIDTH, 1000);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 800);
cv::Mat frame;
while (cap.isOpened())
{
// 读取一帧
cap.read(frame);
if (frame.empty())
{
std::cout << "Read frame failed!" << std::endl;
break;
}
// 预测
// 简单吧,两行代码预测结果就出来了,封装的还可以吧 嘚瑟
std::vector<torch::Tensor> r = yolo.prediction(frame);
// 画框根据你自己的项目调用相应的方法,也可以不画框自己处理
frame = yolo.drawRectangle(frame, r[0], labels);
// show 图片
cv::imshow("", frame);
if (cv::waitKey(1) == 27) break;
}
return 0;
}
这个是读取文件夹内所有的图片
#if 0
#include "YOLOv5.h"
#include"Ex.h"
#include<opencv2\opencv.hpp>
#include<io.h>
#include<iostream>
int main()
{
YoloV5 yolo("D:\\Besktop\\best.torchscript.pt", true);
// 读取分类标签
std::ifstream f("D:\\Besktop\\voc.txt");
std::string name = "";
int i = 0;
std::map<int, std::string> labels;
while (std::getline(f, name))
{
labels.insert(std::pair<int, std::string>(i, name));
std::cout << labels << std::endl;
i++;
}
//cv::Mat frame = cv::imread("D:\\Besktop\\000\\划伤_2023032218553818.bmp");
string path = "D:\\Besktop\\000\\";
String dest = "D:\\Besktop\\1\\";
String savedfilename;
int len = path.length();
vector<cv::String> filenames;
cv::glob(path, filenames);
for (int i = 0; i < filenames.size(); i++)
{
Mat frame;
frame = imread(filenames[i], i);
//frame = 255 - frame; //对每一张图片取反
savedfilename = dest + filenames[i].substr(len);
cout << savedfilename << endl;
// 预测
std::vector<torch::Tensor> r = yolo.prediction(frame);
std::cout << r << std::endl;
// 画框
frame = yolo.drawRectangle(frame, r[0], labels);
//bool is = yolo.existencePrediction(r);
//std::cout << is << std::endl;
// show 图片
//cv::imshow("", frame);
//imwrite(fileName, frame);
imwrite(savedfilename, frame);
cv::waitKey(0);
//if (cv::waitKey(1) == 27);
}
return 0;
}
#endif // 0
读取一张图片
#if 1
#include "YoloV5.h"
int main()
{
YoloV5 yolo("../dataset/best.torchscript.pt", true);
// 读取分类标签
std::ifstream f("../dataset/voc.txt");
std::string name = "";
int i = 0;
std::map<int, std::string> labels;
while (std::getline(f, name))
{
labels.insert(std::pair<int, std::s