yolov5目标检测推理(opencv的DNN模块)

blobFromImage函数  

 

blobFromImage(InputArray image, 
              double scalefactor=1.0, 
              const Size& size = Size(),
              const Scalar& mean = Scalar(), 
              bool swapRB = false, 
              bool crop = false,
              int ddepth = CV_32F)

image:读取的图片数据
scalefactor: 缩放像素值,如 [0, 255] - [0, 1]
size: 输出blob(图像)的尺寸
mean: 从各通道减均值. 如果输入 image 为 BGR 次序,且swapRB=True,则通道次序为 (mean-R, mean-G, mean-B).
swapRB: 交换 3 通道图片的第一个和最后一个通道,如 BGR - RGB
crop: 图像尺寸 resize 后是否裁剪. 如果crop=True,则,输入图片的尺寸调整resize后,一个边对应与 size 的一个维度,而另一个边的值大于等于 size 的另一个维度;然后从 resize 后的图片中心进行 crop. 如果crop=False,则无需 crop,只需保持图片的长宽比
ddepth: 输出 blob 的 Depth. 可选: CV_32F 或 CV_8U

NMSBoxes函数 

void cv::dnn::NMSBoxes( vector<cv::Rect> _boxes,

                vector<float> _scores,

                float _score_threshold,

                float _nms_threshold,

                vector<int> _indices)
 _boxes: 输入边界框,一般为(x, y, w, h)格式的Rect格式的容器。
_scores: 输入边界框的预测分数,一般为每个边界框的类别概率或类别得分。
_score_threshold: 分数阈值,低于此阈值的边界框将被过滤掉。
_nms_threshold: 非极大值抑制阈值,用于决定哪些边界框之间的重叠度过高,需要抑制。
_indices: 输出参数,包含被选中的边界框的索引。

 

#include<iostream>
#include<opencv2\opencv.hpp>
#include<opencv2\dnn.hpp>
#include<fstream>
using namespace std;
using namespace cv;
using namespace dnn;


const std::vector<cv::Scalar> colors = { cv::Scalar(255, 255, 0), cv::Scalar(0, 255, 0), cv::Scalar(0, 255, 255), cv::Scalar(255, 0, 0) };
const float SCORE_THRESHOLD = 0.2;
const float CONFIDENCE_THRESHOLD = 0.6;
const float NMS_THRESHOLD = 0.4;

struct Detection
{
	int class_id;
	float confidence;
	cv::Rect box;
};

int main() {

	Net net = readNetFromONNX("best.onnx");//加载模型	
	net.setPreferableBackend(DNN_BACKEND_DEFAULT);//setPreferableBackend实际计算后台,defau1t默认是DNNBACKEND_OPENCV作为计算后台,使用此就行(也有加速后台ENGINE)
	net.setPreferableTarget(DNN_TARGET_CUDA);	//设置在什么设备上进行计算

	cv::Mat mat = imread("C:/Users/Administrator/Documents/visual studio 2015/Projects/test/test/box/0002 (2654).jpg");

	cv::Mat blob = cv::dnn::blobFromImage(mat, 1.0 / 255, cv::Size(960, 960), cv::Scalar(0, 0, 0), true);


	net.setInput(blob);
	std::vector<cv::Mat>outputs;

	net.forward(outputs);

	float* data = (float*)outputs[0].data;
	//dimensions为6,[0][1]为中心点xy坐标;[2][3]为wh;[4]为置信度,本模型一个类别,所以为5+1
	const int dimensions = 6;
	//rows为56700,对960*960像素的图片的3个通道分别进行了8、16、32倍采样,所以结果为120*120*3+60*60*3+30*30*3=56700
	const int rows = 56700;

	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;
			cv::Mat scores(1, 3, 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);

				float x = data[0];
				float y = data[1];
				float w = data[2];
				float h = data[3];
				int left = int(x - 0.5 * w);
				int top = int(y - 0.5 * h);
				int width = int(w);
				int height = int(h);
				boxes.push_back(cv::Rect(left, top, width, height));
			}

		}
		data += 8;

	}
	std::vector<int> nms_result;
	cv::dnn::NMSBoxes(boxes, confidences, SCORE_THRESHOLD, NMS_THRESHOLD, nms_result);
	std::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 detections = output.size();
	for (int i = 0; i < detections; ++i)
	{

		auto detection = output[i];
		auto box = detection.box;
		auto classId = detection.class_id;
		auto color = colors[classId % colors.size()];
		cv::rectangle(mat, box, color, 3);

	}
	cv::imshow("output", mat);
	waitKey();

}
  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于将 YOLOv5 转换为 ONNX 格式并使用 DNN 调用的问题,您可以按照以下步骤进行操作: 1. 首先,您需要将 YOLOv5 模型转换为 ONNX 格式。您可以使用官方提供的 `export.py` 脚本来执行此操作。确保您已经安装了 PyTorch 和其他所需的依赖项。 ```bash $ python export.py --weights yolov5s.pt --img 640 --batch 1 ``` 上述命令中的 `--weights` 参数指定了您的 YOLOv5 权重文件的路径,`--img` 参数指定了输入图像的大小,`--batch` 参数指定了批处理大小。您可以根据需要进行调整。 2. 执行上述命令后,将生成一个 `yolov5s.onnx` 文件,这是转换后的 ONNX 模型。 3. 接下来,您可以使用 OpenCVDNN 模块来加载并使用 ONNX 模型。请确保您已经安装了 OpenCV 的正确版本。 ```python import cv2 # 加载模型 net = cv2.dnn.readNetFromONNX('yolov5s.onnx') # 加载图像 image = cv2.imread('image.jpg') # 构建输入 blob blob = cv2.dnn.blobFromImage(image, scalefactor=1/255, size=(640, 640), mean=(0, 0, 0), swapRB=True, crop=False) # 设置输入 blob net.setInput(blob) # 前向推理 outputs = net.forward() # 处理输出 # ... ``` 在上述代码中,您需要将 `'yolov5s.onnx'` 替换为您转换后的 ONNX 模型的路径,并将 `'image.jpg'` 替换为您要进行目标检测的图像。 4. 最后,您可以处理模型的输出以获取检测到的目标信息。具体的处理方式取决于您的应用场景和需求。 请注意,上述步骤仅适用于 YOLOv5,如果您使用的是其他版本的 YOLO,请参考相应版本的文档和代码示例。希望以上信息能对您有所帮助!如果您有任何进一步的问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值