IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 在Windows环境下调用GPU部署yolov5模型 -> 正文阅读

[人工智能]在Windows环境下调用GPU部署yolov5模型

在win10+opencv4.4.0+opencv_contrib4.4.0+cuda10.2环境下部署yolov5模型

编译过程参考了这一篇博客

https://blog.csdn.net/hai_fellow_Z/article/details/116002203

主要有两个代码yolo.h和main_yolo.cpp

主程序为main_yolo.cpp文件

以下代码main函数可以分别实现图片、视频、摄像头的调用


#include "yolo.h"  
#include <opencv2/opencv.hpp>
using namespace cv;


YOLO::YOLO(Net_config config)
{
	cout << "Net use " << config.netname << endl;
	this->confThreshold = config.confThreshold;
	this->nmsThreshold = config.nmsThreshold;
	this->objThreshold = config.objThreshold;
	strcpy_s(this->netname, config.netname.c_str());

	ifstream ifs(this->classesFile.c_str());
	string line;
	while (getline(ifs, line)) this->classes.push_back(line);

	string modelFile = this->netname;
	modelFile += ".onnx";
	modelFile = "F:\\code\\a14-yolov5-dnn-opencv\\x64\\Release\\yolov5s.onnx";
	
	this->net = readNet(modelFile);
	
	// 调用GPU
	net.setPreferableTarget(DNN_TARGET_CUDA);
	net.setPreferableBackend(DNN_BACKEND_CUDA);

	// 调用CPU
	/*net.setPreferableTarget(DNN_TARGET_CPU);
	net.setPreferableBackend(DNN_BACKEND_OPENCV);*/
	
	

}

void YOLO::drawPred(int classId, float conf, int left, int top, int right, int bottom, Mat & frame)   // Draw the predicted bounding box
{
	//Draw a rectangle displaying the bounding box   蓝色框画左上和右下
	rectangle(frame, Point(left, top), Point(right, bottom), Scalar(0, 0, 255), 3);

	//Get the label for the class name and its confidence
	string label = format("%.2f", conf);
	label = this->classes[classId] + ":" + label;

	//Display the label at the top of the bounding box
	int baseLine;
	Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
	top = max(top, labelSize.height);
	//rectangle(frame, Point(left, top - int(1.5 * labelSize.height)), Point(left + int(1.5 * labelSize.width), top + baseLine), Scalar(0, 255, 0), FILLED);
	putText(frame, label, Point(left, top), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 255, 0), 1);
}

void YOLO::sigmoid(Mat * out, int length)
{
	float* pdata = (float*)(out->data);
	int i = 0;
	for (i = 0; i < length; i++)
	{
		pdata[i] = 1.0 / (1 + expf(-pdata[i]));
	}
}

void YOLO::detect(Mat & frame)
{
	Mat blob;
	blobFromImage(frame, blob, 1 / 255.0, Size(this->inpWidth, this->inpHeight), Scalar(0, 0, 0), true, false);
	this->net.setInput(blob);
	vector<Mat> outs;
	
	std::vector<String> res = this->net.getUnconnectedOutLayersNames();
	this->net.forward(outs, res);

	/generate proposals
	vector<int> classIds;
	vector<float> confidences;
	vector<Rect> boxes;
	float ratioh = (float)frame.rows / this->inpHeight, ratiow = (float)frame.cols / this->inpWidth;
	int n = 0, q = 0, i = 0, j = 0, nout = this->classes.size() + 5, c = 0;
	for (n = 0; n < 3; n++)   ///尺度
	{
		int num_grid_x = (int)(this->inpWidth / this->stride[n]);
		int num_grid_y = (int)(this->inpHeight / this->stride[n]);
		int area = num_grid_x * num_grid_y;
		this->sigmoid(&outs[n], 3 * nout * area);
		for (q = 0; q < 3; q++)    ///anchor数
		{
			const float anchor_w = this->anchors[n][q * 2];
			const float anchor_h = this->anchors[n][q * 2 + 1];
			float* pdata = (float*)outs[n].data + q * nout * area;
			for (i = 0; i < num_grid_y; i++)
			{
				for (j = 0; j < num_grid_x; j++)
				{
					float box_score = pdata[4 * area + i * num_grid_x + j];
					if (box_score > this->objThreshold)
					{
						float max_class_socre = 0, class_socre = 0;
						int max_class_id = 0;
						for (c = 0; c < this->classes.size(); c++)  get max socre
						{
							class_socre = pdata[(c + 5) * area + i * num_grid_x + j];
							if (class_socre > max_class_socre)
							{
								max_class_socre = class_socre;
								max_class_id = c;
							}
						}

						if (max_class_socre > this->confThreshold)
						{
							float cx = (pdata[i * num_grid_x + j] * 2.f - 0.5f + j) * this->stride[n];  ///cx
							float cy = (pdata[area + i * num_grid_x + j] * 2.f - 0.5f + i) * this->stride[n];   ///cy
							float w = powf(pdata[2 * area + i * num_grid_x + j] * 2.f, 2.f) * anchor_w;   ///w
							float h = powf(pdata[3 * area + i * num_grid_x + j] * 2.f, 2.f) * anchor_h;  ///h

							int left = (cx - 0.5 * w) * ratiow;
							int top = (cy - 0.5 * h) * ratioh;   ///坐标还原到原图上

							classIds.push_back(max_class_id);
							confidences.push_back(max_class_socre);
							boxes.push_back(Rect(left, top, (int)(w * ratiow), (int)(h * ratioh)));
						}
					}
				}
			}
		}
	}

	// Perform non maximum suppression to eliminate redundant overlapping boxes with
	// lower confidences
	vector<int> indices;
	NMSBoxes(boxes, confidences, this->confThreshold, this->nmsThreshold, indices);
	for (size_t i = 0; i < indices.size(); ++i)
	{
		int idx = indices[i];
		Rect box = boxes[idx];
		this->drawPred(classIds[idx], confidences[idx], box.x, box.y,
			box.x + box.width, box.y + box.height, frame);
	}
}

//int main()
//{
//	YOLO yolo_model(yolo_nets[0]);
//	string imgpath = "F:/code/yolov5_c++_dnn/yolov5/yolov5/person.jpg";
//	Mat srcimg = imread(imgpath);
//	yolo_model.detect(srcimg);
//
//	static const string kWinName = "Deep learning object detection in OpenCV";
//	namedWindow(kWinName, WINDOW_NORMAL);
//	imshow(kWinName, srcimg);
//	waitKey(0);
//	destroyAllWindows();
//}


int main() 
{
	YOLO yolo_model(yolo_nets[0]);
	//string imgpath = "E:\\code\\a14-yolov5-dnn-opencv\\a14-yolov5-dnn-opencv\\ren.mp4";
	cv::VideoCapture cap;
	//cap = VideoCapture(0, CAP_DSHOW);
	//cap = cv::VideoCapture(0, CAP_DSHOW)
	//cap.open(imgpath);
	cap.open("F:/code/yolov5_c++_dnn/yolov5/yolov5/ren.mp4"); //打开视频,以上两句等价于VideoCapture cap("E://2.avi");
	//cap.open(0);

	//cap.open("http://www.laganiere.name/bike.avi");//也可以直接从网页中获取图片,前提是网页有视频,以及网速够快
	if (!cap.isOpened()) {//如果视频不能正常打开则返回
		std::cout << "打不开"<< std::endl;
		return 0;
	}
	Mat frame;
	while (1)
	{
		cap >> frame;//等价于cap.read(frame);
		if (frame.empty())//如果某帧为空则退出循环
			break;
		yolo_model.detect(frame);
		imshow("video", frame);
		waitKey(1);//每帧延时20毫秒
	}
	cap.release();//释放资源
	return 0;
}

//int main() {
//	YOLO yolo_model(yolo_nets[0]);
//	std::string dir_video = "E:/code/a14-yolov5-dnn-opencv/a14-yolov5-dnn-opencv/ren.mp4";
//	std::string challenge_output = dir_video + "output.mp4";
//	cv::VideoCapture cap(dir_video + "test.mp4");
//	cv::VideoWriter writer;
//	const int fps = 30;
//	const int width = cap.get(cv::CAP_PROP_FRAME_WIDTH);
//	const int height = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
//	cv::Size size(width, height);
//	writer.open(challenge_output,writer.fourcc('M', 'J', 'P', 'G'), fps, size);
//	while (1) {
//		cv::Mat frame;
//		cap >> frame;
//		if (frame.empty()) 
//		std::cout << "打不开" << std::endl;
//		break;
//		cv::Mat result;
//		//yolo_model.detect(frame, result, height, width);
//		yolo_model.detect(frame);
//		writer << result;
//		cv::imshow("result", result);
//		cv::waitKey(30);
//	}
//	cap.release();
//	return 0;
//}

头文件为yolo.h

#include <fstream>
#include <sstream>
#include <iostream>
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

using namespace cv;
using namespace dnn;
using namespace std;

struct Net_config  // 
{
	float confThreshold; // class Confidence threshold
	float nmsThreshold;  // Non-maximum suppression threshold
	float objThreshold;  //Object Confidence threshold
	string netname;
};

class YOLO
{
	public:
		YOLO(Net_config config);
		void detect(Mat& frame);
	private:
		const float anchors[3][6] = {{10.0, 13.0, 16.0, 30.0, 33.0, 23.0}, {30.0, 61.0, 62.0, 45.0, 59.0, 119.0},{116.0, 90.0, 156.0, 198.0, 373.0, 326.0}};
		const float stride[3] = { 8.0, 16.0, 32.0 };
		const string classesFile = "F:\\code\\a14-yolov5-dnn-opencv\\coco.names"; 
		const int inpWidth = 640;
		const int inpHeight = 640;
		float confThreshold;
		float nmsThreshold;
		float objThreshold;
		
		char netname[20];
		vector<string> classes;
		Net net;
		void drawPred(int classId, float conf, int left, int top, int right, int bottom, Mat& frame);
		void sigmoid(Mat* out, int length);
};

static inline float sigmoid_x(float x)
{
	return static_cast<float>(1.f / (1.f + exp(-x)));
}

Net_config yolo_nets[4] = {
	{0.5, 0.5, 0.5, "yolov5s"},
	{0.5, 0.5, 0.5,  "yolov5m"},
	{0.5, 0.5, 0.5, "yolov5l"},
	{0.5, 0.5, 0.5, "yolov5x"}
};

图片测试效果(注:视频资源和摄像头的调用可以自己调试)

在这里插入图片描述
在这里插入图片描述

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-08-17 15:24:00  更:2021-08-17 15:26:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/1 12:33:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码