OpenCV之YOLOv5目标检测

这篇具有很好参考价值的文章主要介绍了OpenCV之YOLOv5目标检测。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • 💂 个人主页:风间琉璃
  • 🤟 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联系博主
  • 💬 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)订阅专栏

目录

前言

一、YOLOv5简介

二、预处理

1.获取分类名

2.获取输出层名称

3.图像尺度变换

三、模型加载

四、推理和后处理

五、源码


前言

YOLOv5(You Only Look Once version 5)是计算机视觉领域中一种用于目标检测的深度学习模型,它是YOLO(You Only Look Once)系列的最新版本。YOLOv5的目标是实现高效而准确的实时目标检测,其名称"You Only Look Once"意味着它只需一次前向传播(forward pass)即可检测图像中的所有对象,而不需要采用复杂的多步骤流程。

一、YOLOv5简介

yolov5官方给出的目标检测网络中一共有4个版本,分别是Yolov5s、Yolov5m、Yolov5l、Yolov5x四个模型。

其网络结构如下:

opencvsharp yolov5,YOLO,# OpenCV,opencv,YOLO,目标检测

其基本组成由分为输入端、Backbone、Neck、Prediction四个部分组成。

(1)输入端Mosaic数据增强、自适应锚框计算
(2)BackboneFocus结构,CSP结构
(3)NeckFPN+PAN结构
(4)PredictionGIOU_Loss 

yolov5详情参考:深入浅出Yolo系列之Yolov5核心基础知识完整讲解_江大白*的博客-CSDN博客

C++:mirrors / doleron / yolov5-opencv-cpp-python · GitCode

【模型部署】使用opencv C++ 加速YOLO V5_卖报的大地主的博客-CSDN博客 

二、预处理

1.获取分类名

数据集采用的coco数据集,需要将coco.names包含训练模型的所有类名称加载到内存中。

string class_path = "F:/data/CQU/VS/yolov5_onnx/coco.names";

//获取分类名
vector<string> getClassNames(string class_path)
{
	ifstream ifs(class_path);
	if (!ifs.is_open())
	{
		printf("could not load class file...\n");
	}
	vector<string> classnames;
	string line;
	while (getline(ifs, line))
	{
		classnames.push_back(line);
	}
	return classnames;
}

2.获取输出层名称

获取yolov5网络模型输出层的名称,为后面的推理做准备。

//获取网络的不相连输出层名称
vector<string> getOutpusNames(const Net& net)
{
	vector<string> outputsname = net.getUnconnectedOutLayersNames(); 
	//for (int i = 0; i < outputsname.size(); i++)
	//{
		//printf("Outputs Name%d:%s", i, outputsname.at(i).c_str());
	//}
	return outputsname;
}

3.图像尺度变换

神经网络的输入图像需要采用称为blob的特定格式。从输入图像或视频流中读取帧后,将通过blobFromImage函数将其转换为神经网络的输入blob。

在此过程中,它使用比例因子1/255将图像像素值缩放到0到1的目标范围。它还将图像的大小调整为给定大小(640,640)而不进行裁剪。以下是使用Netron打开yolov5s.onnx的网络结构。
 

opencvsharp yolov5,YOLO,# OpenCV,opencv,YOLO,目标检测

//定义相关参数值与阈值
const float INPUT_WIDTH = 640.0;
const float INPUT_HEIGHT = 640.0;


//将输入图像进行预处理
Mat format_yolov5(const Mat& source)
{
	int col = source.cols;
	int row = source.rows;
	int _max = MAX(col, row);

	//以最大的边长重构图像
	Mat result = Mat::zeros(_max, _max,CV_8UC3);
	source.copyTo(result(Rect(0, 0, col, row)));
	return result;
}

//预处理
auto input_image = format_yolov5(image);
Mat blob = blobFromImage(input_image, 1 / 255.0, Size(INPUT_WIDTH, INPUT_HEIGHT), Scalar(), true, false);

三、模型加载

加载网络直接使用readNet,可以根据个人的情况设置是否使用CUDA加速。

//加载网络
Net  loadNet(string model_path, bool is_Cuda)
{
	Net net = readNet(model_path);

	//是否使用cuda
	if (is_Cuda)  //CUDA
	{
		net.setPreferableBackend(DNN_BACKEND_CUDA);
		net.setPreferableTarget(DNN_TARGET_CUDA_FP16);
	}
	else  //cpu
	{
		net.setPreferableBackend(DNN_BACKEND_OPENCV);
		net.setPreferableTarget(DNN_TARGET_CPU);
	}
	return net;
}


//加载网络并使用cuda加速
Net net = loadNet(model, true);

四、推理和后处理

网络模型加载完成后,就可以将图片送入网络进行预测。

//YOLOV5网络的数据预处理以及前向推理(包括NMS处理)
void detect(cv::Mat& image, cv::dnn::Net& net, std::vector<Detection>& output, const std::vector<std::string>& className)
{
	//预处理
	auto input_image = format_yolov5(image);
	Mat blob = blobFromImage(input_image, 1 / 255.0, Size(INPUT_WIDTH, INPUT_HEIGHT), Scalar(), true, false);

	//设置输入
	net.setInput(blob);

	//前向计算
	vector<Mat> outputs;
	vector<string> outputnames = getOutpusNames(net);
	net.forward(outputs, outputnames);

	//计算x_factor和y_factor,用于后面还原bounding box的位置和大小
	float x_factor = input_image.cols / INPUT_WIDTH;
	float y_factor = input_image.rows / INPUT_HEIGHT;

	//yolov5s输出层为一层,通过outputs可获得预测信息
	float* data = (float*)outputs[0].data;

	//yolov5s模型的输出大小为[1,25200.85]
	const int dimensions = 85;
	const int rows = 25200;

	//分类类别索引
	std::vector<int> class_ids;
	//置信度
	std::vector<float> confidences;
	//边框坐标信息
	std::vector<cv::Rect> boxes;

	for (int i = 0; i < rows; ++i )
	{
		//获取自信度
		float confidence = data[4];
		if (confidence >= CONFIDENCE_THRESHOLD) 
		{
			//获取类别概率
			float* classes_scores = data + 5; 
			
			//将概率构造为Mat
			cv::Mat scores(1, className.size(), CV_32FC1, classes_scores);
			cv::Point class_id;
			double max_class_score;

			//获取最大类别分数以及其对应的索引
			minMaxLoc(scores, 0, &max_class_score, 0, &class_id);

			//通过阈值进行筛选,将符合要求的类别、置信度以及框体进行保存
			if (max_class_score > SCORE_THRESHOLD) 
			{
				confidences.push_back(confidence);
				class_ids.push_back(class_id.x);

				//得到边框左上角(x,y)和w,h
				float x = data[0]; //边框中心坐标
				float y = data[1];
				float w = data[2];
				float h = data[3];
				int left = int((x - 0.5 * w) * x_factor);
				int top = int((y - 0.5 * h) * y_factor);
				int width = int(w * x_factor);
				int height = int(h * y_factor);
				boxes.push_back(cv::Rect(left, top, width, height));
			}

		}
		//一个边界框包含85个值:4个坐标信息、1个置信度信息和80个类别得分信息,在遍历一个边界框后,data指向需要向后移动85个位置
		data += 85;
	}

	std::vector<int> nms_result;
	cv::dnn::NMSBoxes(boxes, confidences, SCORE_THRESHOLD, NMS_THRESHOLD, nms_result);

	//将经过NMS处理后的结果加载到const vector<Detection> output中
	for (int i = 0; i < nms_result.size(); i++) 
	{
		int idx = nms_result[i];
		Detection result;  
		result.class_id = class_ids[idx];
		result.confidence = confidences[idx];
		result.box = boxes[idx];
		output.push_back(result);
	}
}

网络输出的结果都存在outputs中。outputs的大小为[1,15200,85]。下面是其输出层信息。

第一维是batch size,为1。


第二维为每张输入图片生成的预测框数,即anchors数量 x (S1 x S1 + S2 x S2 + S3 x S3),这里的S1, S2, S3分别为输出层的三个特征图的大小,取值为{80, 40, 20},anchors数量为3,因此总的预测框数为25200;


 第三维为每个预测框的信息,包括4个坐标信息、1个置信度信息和80个类别得分信息,共85个信息

opencvsharp yolov5,YOLO,# OpenCV,opencv,YOLO,目标检测

opencvsharp yolov5,YOLO,# OpenCV,opencv,YOLO,目标检测 

通过outputs[0]可以获得该输出层的结果,其中包含了该层所有的预测框的信息,包括预测框的位置、大小、置信度和类别概率。这些信息被保存在一个指向连续内存的地址中,可以通过.data来访问。

使用一个指向float类型的连续内存的指针获取outputs[0].data的数据,即该指针指向的是一个float类型的数组,其中包含了该层所有预测框的位置、大小、置信度和类别概率。

因此,将该指针赋值给float* data后,就可以通过data来访问该数组中的每一个元素。同时,由于该数组是连续内存,可以通过指针的算术运算来访问该数组中的每一个元素,即使用data[i]来访问数组中第i个元素。

data[4]:指针所指向的内存中的第5个float类型的数据,存储的是置信度。当置信度大于一定的阈值,检测有效。

data + 5:从第6个float类型的数据开始的一段连续数据,即80个分类类别的概率。我们需要从该80个类别中找到概率最大的类别以及索引值。

在输出信息中每一行代表一个检测到的边界框, 一个边界框包含85个值:4个坐标信息、1个置信度信息和80个类别得分信息。data所指内存地址包含输出层所有预测框的位置、大小、置信度和类别概率,在yolov5s中共有25200个边界框,即data所指内存地址包含25200*85个值。在遍历一个边界框后,data指向需要向后移动85个位置,即 data +85

最后还需要进行非极大值抑制,在目标检测任务中,一个目标可能会被多个边界框检测到,这些边界框可能会有不同的位置和大小,但表示同一个目标。非极大值抑制(Non-Maximum Suppression,NMS)是一种常用的方法,用于抑制这些重叠的边界框,只保留置信度最高的那个边界框,从而得到最终的目标检测结果。

NMS的原理如下:首先,对所有的边界框按照其置信度进行排序,置信度最高的边界框排在最前面。从置信度最高的边界框开始,依次遍历其余边界框。
   

对于当前遍历到的边界框,如果它与前面已经保留的边界框的重叠程度(通过计算IOU值)大于一定阈值(比如0.5),那么就将其抑制掉,不保留。继续遍历下一个边界框,重复上述过程,直到所有的边界框都被处理完毕。


通过这样的处理,NMS可以抑制掉大量重叠的边界框,只保留最好的那个边界框,从而得到最终的目标检测结果。

然后就是将将检测到的目标边框绘制出来。

//画预测的目标bounding box
void drawPred(vector<string> classesnames, int classId, float conf, Rect box, Mat& frame)
{

	//获取类别名称及其置信度
	string label = format("%.2f", conf);
	if (!classesnames.empty())
	{
		CV_Assert(classId < (int)classesnames.size());
		label = classesnames[classId] + ":" + label;
	}

	定义框体颜色:  box 和 text 的颜色
	Scalar rectColor, textColor;
	// 创建随机数生成器
	random_device rd;
	mt19937 generator(rd());
	// 创建均匀分布对象,范围是1到50
	uniform_int_distribution<int> distribution(1, 80);
	// 生成随机数
	int random_number = distribution(generator);

	//设置颜色
	rectColor = Scalar(random_number * 10 % 256, random_number * 20 % 256, random_number * 30 % 256);
	textColor = Scalar(255 - random_number * 10 % 256, 255 - random_number * 20 % 256, 255 - random_number * 30 % 256);


	//绘制边界框
	rectangle(frame, box, rectColor, 3);
	//绘制用于写类别的边框范围,一般就在边框的上面
	rectangle(frame, Point(box.x, box.y - 20), Point(box.x + box.width, box.y), textColor, FILLED);
	//在上面绘制的框界内写出类别以及概率
	putText(frame, label, Point(box.x, box.y - 5), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));
}

运行结果:

YOLOv5:高效实时目标检测的新巅峰

五、源码

资源下载:CSDN

// yolov5_onnx.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <fstream>
#include <random>

#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>

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



//定义相关参数值与阈值
const float INPUT_WIDTH = 640.0;
const float INPUT_HEIGHT = 640.0;
const float SCORE_THRESHOLD = 0.4;
const float NMS_THRESHOLD = 0.4;
const float CONFIDENCE_THRESHOLD = 0.4;


//定义输出结果的结构体类
struct Detection
{
	int class_id;
	float confidence;
	cv::Rect box; 
};


//获取分类名
vector<string> getClassNames(string class_path)
{
	ifstream ifs(class_path);
	if (!ifs.is_open())
	{
		printf("could not load class file...\n");
	}
	vector<string> classnames;
	string line;
	while (getline(ifs, line))
	{
		classnames.push_back(line);
	}
	return classnames;
}

//获取网络的不相连输出层名称
vector<string> getOutpusNames(const Net& net)
{
	vector<string> outputsname = net.getUnconnectedOutLayersNames(); 
	//for (int i = 0; i < outputsname.size(); i++)
	//{
		//printf("Outputs Name%d:%s", i, outputsname.at(i).c_str());
	//}
	return outputsname;
}

//加载网络
Net  loadNet(string model_path, bool is_Cuda)
{
	Net net = readNet(model_path);

	//是否使用cuda
	if (is_Cuda)  //CUDA
	{
		net.setPreferableBackend(DNN_BACKEND_CUDA);
		net.setPreferableTarget(DNN_TARGET_CUDA_FP16);
	}
	else  //cpu
	{
		net.setPreferableBackend(DNN_BACKEND_OPENCV);
		net.setPreferableTarget(DNN_TARGET_CPU);
	}
	return net;
}

//将输入图像进行预处理
Mat format_yolov5(const Mat& source)
{
	int col = source.cols;
	int row = source.rows;
	int _max = MAX(col, row);

	//以最大的边长重构图像
	Mat result = Mat::zeros(_max, _max,CV_8UC3);
	source.copyTo(result(Rect(0, 0, col, row)));
	return result;
}



//画预测的目标bounding box
void drawPred(vector<string> classesnames, int classId, float conf, Rect box, Mat& frame)
{

	//获取类别名称及其置信度
	string label = format("%.2f", conf);
	if (!classesnames.empty())
	{
		CV_Assert(classId < (int)classesnames.size());
		label = classesnames[classId] + ":" + label;
	}

	定义框体颜色:  box 和 text 的颜色
	Scalar rectColor, textColor;
	// 创建随机数生成器
	random_device rd;
	mt19937 generator(rd());
	// 创建均匀分布对象,范围是1到50
	uniform_int_distribution<int> distribution(1, 80);
	// 生成随机数
	int random_number = distribution(generator);

	//设置颜色
	rectColor = Scalar(random_number * 10 % 256, random_number * 20 % 256, random_number * 30 % 256);
	textColor = Scalar(255 - random_number * 10 % 256, 255 - random_number * 20 % 256, 255 - random_number * 30 % 256);


	//绘制边界框
	rectangle(frame, box, rectColor, 3);
	//绘制用于写类别的边框范围,一般就在边框的上面
	rectangle(frame, Point(box.x, box.y - 20), Point(box.x + box.width, box.y), textColor, FILLED);
	//在上面绘制的框界内写出类别以及概率
	putText(frame, label, Point(box.x, box.y - 5), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));
}

//YOLOV5网络的数据预处理以及前向推理(包括NMS处理)
void detect(cv::Mat& image, cv::dnn::Net& net, std::vector<Detection>& output, const std::vector<std::string>& className)
{
	//预处理
	auto input_image = format_yolov5(image);
	Mat blob = blobFromImage(input_image, 1 / 255.0, Size(INPUT_WIDTH, INPUT_HEIGHT), Scalar(), true, false);

	//设置输入
	net.setInput(blob);

	//前向计算
	vector<Mat> outputs;
	vector<string> outputnames = getOutpusNames(net);
	net.forward(outputs, outputnames);

	//计算x_factor和y_factor,用于后面还原bounding box的位置和大小
	float x_factor = input_image.cols / INPUT_WIDTH;
	float y_factor = input_image.rows / INPUT_HEIGHT;

	//yolov5s输出层为一层,通过outputs可获得预测信息
	float* data = (float*)outputs[0].data;

	//yolov5s模型的输出大小为[1,25200.85]
	const int dimensions = 85;
	const int rows = 25200;

	//分类类别索引
	std::vector<int> class_ids;
	//置信度
	std::vector<float> confidences;
	//边框坐标信息
	std::vector<cv::Rect> boxes;

	for (int i = 0; i < rows; ++i )
	{
		//获取自信度
		float confidence = data[4];
		if (confidence >= CONFIDENCE_THRESHOLD) 
		{
			//获取类别概率
			float* classes_scores = data + 5; 
			
			//将概率构造为Mat
			cv::Mat scores(1, className.size(), CV_32FC1, classes_scores);
			cv::Point class_id;
			double max_class_score;

			//获取最大类别分数以及其对应的索引
			minMaxLoc(scores, 0, &max_class_score, 0, &class_id);

			//通过阈值进行筛选,将符合要求的类别、置信度以及框体进行保存
			if (max_class_score > SCORE_THRESHOLD) 
			{
				confidences.push_back(confidence);
				class_ids.push_back(class_id.x);

				//得到边框左上角(x,y)和w,h
				float x = data[0]; //边框中心坐标
				float y = data[1];
				float w = data[2];
				float h = data[3];
				int left = int((x - 0.5 * w) * x_factor);
				int top = int((y - 0.5 * h) * y_factor);
				int width = int(w * x_factor);
				int height = int(h * y_factor);
				boxes.push_back(cv::Rect(left, top, width, height));
			}

		}
		//一个边界框包含85个值:4个坐标信息、1个置信度信息和80个类别得分信息,在遍历一个边界框后,data指向需要向后移动85个位置
		data += 85;
	}

	std::vector<int> nms_result;
	cv::dnn::NMSBoxes(boxes, confidences, SCORE_THRESHOLD, NMS_THRESHOLD, nms_result);

	//将经过NMS处理后的结果加载到const vector<Detection> output中
	for (int i = 0; i < nms_result.size(); i++) 
	{
		int idx = nms_result[i];
		Detection result;  
		result.class_id = class_ids[idx];
		result.confidence = confidences[idx];
		result.box = boxes[idx];
		output.push_back(result);
	}
}

int main()
{
	string model = "F:/data/CQU/VS/yolov5_onnx/yolov5s.onnx";
	string class_path = "F:/data/CQU/VS/yolov5_onnx/coco.names";
	string video_path = "F:/data/CQU/VS/yolov5_onnx/street.mp4";

	//加载网络并使用cuda加速
	Net net = loadNet(model, true);

	//获取标签
	vector<string> classesnames = getClassNames(class_path);


	//获取视频流
	VideoCapture capture;
	capture.open(video_path);
	if (!capture.isOpened())
	{
		printf("could not read video...\n");
	}

	Mat frame;
	while (capture.read(frame))
	{
		vector<Detection> output;
		//获得当前系统的计时间周期数,求FPS
		double t = (double)getTickCount();

		//前向推理
		detect(frame, net, output, classesnames);

		//检测的边界框总数
		int boxs_num = output.size();
		//对每一个边框进行处理
		for (int i = 0; i < boxs_num; ++i)
		{
			auto detection = output[i];
			auto box = detection.box;
			auto classId = detection.class_id;
			auto confidence = detection.confidence;
			drawPred(classesnames, classId, confidence, box, frame);
		}

		//FPS计算
		t = ((double)getTickCount() - t) / getTickFrequency();//求输入帧后经过的周期数/每秒系统计的周期数=一帧用时多少秒
		double fps = 1.0 / t;//求倒数得到每秒经过多少帧,即帧率
		string text = format("FPS:%.2f", fps);
		cv::putText(frame, text, Point(10, 50), FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0), 2, 8, 0);

		imshow("yolov5s", frame);
		int c = waitKey(1);
		if (c == 27)
		{
			break;
		}
	}
	capture.release();
	waitKey(0);
	return 0;
}

结束语
感谢你观看我的文章呐~本次航班到这里就结束啦 🛬

希望本篇文章有对你带来帮助 🎉,有学习到一点知识~

躲起来的星星🍥也在努力发光,你也要努力加油(让我们一起努力叭)。

最后,博主要一下你们的三连呀(点赞、评论、收藏),不要钱的还是可以搞一搞的嘛~

不知道评论啥的,即使扣个666也是对博主的鼓舞吖 💞 感谢 💐

opencvsharp yolov5,YOLO,# OpenCV,opencv,YOLO,目标检测文章来源地址https://www.toymoban.com/news/detail-808740.html

到了这里,关于OpenCV之YOLOv5目标检测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深度学习||YOLO(You Only Look Once)深度学习的实时目标检测算法(YOLOv1~YOLOv5)

    目录 YOLOv1: YOLOv2: YOLOv3: YOLOv4: YOLOv5: 总结: YOLO(You Only Look Once)是一系列基于深度学习的实时目标检测算法。 自从2015年首次被提出以来,YOLO系列不断发展,推出了多个版本,包括YOLOv1, YOLOv2, YOLOv3, YOLOv4, 和YOLOv5等。下面是对YOLO系列的详解: 提出时间 : 2015年。 主要贡献 :

    2024年02月20日
    浏览(41)
  • 涨点神器:Yolov5 加入ODConv+ConvNeXt提升小目标检测能力,适用yolo各个系列

    论文:Omni-Dimensional Dynamic Convolution 论文地址:Omni-Dimensional Dynamic Convolution | OpenReview ODConv通过并行策略引入一种多维注意力机制以对卷积核空间的四个维度学习更灵活的注意力。上图给出CondConv、DyConv以及ODConv的差异图。延续动态卷积的定义,ODConv可以描述成如下形式:其中

    2024年02月04日
    浏览(39)
  • 【问题记录】树莓派+OpenCV+YOLOv5目标检测(Pytorch框架)

     -【学习资料】 子豪兄的零基础树莓派教程 https://github.com/TommyZihao/ZihaoTutorialOfRaspberryPi/blob/master/%E7%AC%AC2%E8%AE%B2%EF%BC%9A%E6%A0%91%E8%8E%93%E6%B4%BE%E6%96%B0%E6%89%8B%E6%97%A0%E7%97%9B%E5%BC%80%E6%9C%BA%E6%8C%87%E5%8D%97.md#%E7%83%A7%E5%BD%95%E9%95%9C%E5%83%8F 第2讲:树莓派新手无痛开机指南【子豪兄的树莓派

    2024年02月02日
    浏览(42)
  • 【解惑笔记】树莓派+OpenCV+YOLOv5目标检测(Pytorch框架)

     -【学习资料】 子豪兄的零基础树莓派教程 https://github.com/TommyZihao/ZihaoTutorialOfRaspberryPi/blob/master/%E7%AC%AC2%E8%AE%B2%EF%BC%9A%E6%A0%91%E8%8E%93%E6%B4%BE%E6%96%B0%E6%89%8B%E6%97%A0%E7%97%9B%E5%BC%80%E6%9C%BA%E6%8C%87%E5%8D%97.md#%E7%83%A7%E5%BD%95%E9%95%9C%E5%83%8F 第2讲:树莓派新手无痛开机指南【子豪兄的树莓派

    2024年02月14日
    浏览(28)
  • YOLOv5改进 | Neck篇 | 利用ASF-YOLO改进特征融合层(适用于分割和目标检测)

    本文给大家带来的改进机制是 ASF-YOLO(发布于2023.12月份的最新机制) ,其是特别设计用于细胞实例分割。这个模型通过结合空间和尺度特征,提高了在处理细胞图像时的准确性和速度。在实验中, ASF-YOLO在2018年数据科学竞赛 数据集上取得了卓越的分割准确性和速度,达到了

    2024年01月15日
    浏览(32)
  • Opencv C++实现yolov5部署onnx模型完成目标检测

    头文件 命名空间 结构体 Net_config 里面存了三个阈值和模型地址,其中 置信度 ,顾名思义,看检测出来的物体的精准度。以测量值为中心,在一定范围内,真值出现在该范围内的几率。 endsWith()函数 判断sub是不是s的子串 anchors_640图像接收数组 根据图像大小,选择相应长度的

    2024年02月13日
    浏览(29)
  • 用opencv的DNN模块做Yolov5目标检测(纯干货,源码已上传Github)

    最近在微信公众号里看到多篇讲解yolov5在openvino部署做目标检测文章,但是没看到过用opencv的dnn模块做yolov5目标检测的。于是,我就想着编写一套用opencv的dnn模块做yolov5目标检测的程序。在编写这套程序时,遇到的bug和解决办法,在这篇文章里讲述一下。 在yolov5之前的yolov3和

    2024年02月02日
    浏览(37)
  • YOLO系列全网首发改进最新:新颖特定任务检测头TSCODE|(适用YOLOv5/v7)创新性Max,即插即用检测头,用于目标检测的特定任务上下文解耦头机制,助力YOLOv7目标检测器高效涨点!

    💡更多改进内容📚可以点击查看:YOLOv5改进、YOLOv7改进、YOLOv8改进、YOLOX改进原创目录🏆 💡 本篇内容 :YOLOv5、YOLOv7改进新型解耦头TSCODE|全网首发最新更新,创新性Max,即插即用检测头|用于目标检测的特定任务上下文解耦头,助力YOLOv7目标检测器高效涨点! @CSDN芒果汁

    2024年02月04日
    浏览(38)
  • 目标检测算法(R-CNN,fast R-CNN,faster R-CNN,yolo,SSD,yoloV2,yoloV3,yoloV4,yoloV5,yoloV6,yoloV7)

    深度学习目前已经应用到了各个领域,应用场景大体分为三类:物体识别,目标检测,自然语言处理。 目标检测可以理解为是物体识别和物体定位的综合 ,不仅仅要识别出物体属于哪个分类,更重要的是得到物体在图片中的具体位置。 为了完成这两个任务,目标检测模型分

    2024年02月02日
    浏览(36)
  • YOLOv5目标检测实验

    最近在用YOLOv5跑一些目标检测的东西,这是自己日常学习的一些总结!后期会继续更新!有问题也欢迎批评指正!如果雷同请见谅! 创建数据集是在detect.py里面的create_dataloader,并在主函数里面调用 yolov5在计算资源的调用上采用了torch.nn.parallel.DistributedDataParallel(DDP,多张显卡

    2024年02月07日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包