如何使用 opencv 调用 yolov5 onnx 模型 ?

2023-05-16

如何使用 opencv 调用 yolov5 onnx 模型 ?
rtx3090 24G release 90 fps by use yolov5n
请添加图片描述

rtx3090 24G release 20 fps by use yolov5s
请添加图片描述

#include <fstream>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>

/*!
 * use ONNX model
 * */
class YoloV5
{
public:
	struct Data{
		int classIndex;
		float confidence;
		cv::Rect box;
	};

	bool init(const std::string & model,bool isUseGPU = true) {
		try{
			net = cv::dnn::readNetFromONNX(model);
			if(isUseGPU) {
				net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
				net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
				std::cout << "SET DNN_BACKEND_CUDA & DNN_TARGET_CUDA" << std::endl;
			}else {
				net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
				net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
				std::cout << "SET DNN_BACKEND_OPENCV & DNN_TARGET_CPU" << std::endl;
			}
		}catch (const cv::Exception &e){
			std::cerr << e.what() << std::endl;
			return false;
		}
		return true;
	}

	void detect(cv::Mat & frame,const std::vector<std::string> &labels,std::vector<YoloV5::Data> &output,float confidenceThreshold = 0.45,float scoreThreshold = 0.5,float nmsThreshold = 0.45) {
		cv::Mat blob;
		cv::dnn::blobFromImage(frame, blob, 1./255., cv::Size(width, height), cv::Scalar(), true, false);
		net.setInput(blob);
		std::vector<cv::Mat> predictions;
		net.forward(predictions, net.getUnconnectedOutLayersNames());

		float x_factor = frame.cols / static_cast<float>(width);
		float y_factor = frame.rows / static_cast<float>(height);

		float *data = (float *)predictions[0].data;

		const int dimensions = 85;
		const int rows = 25200;

		std::vector<int> predClassIds;
		std::vector<float> predConfidences;
		std::vector<cv::Rect> predBoxes;

		for (int i = 0; i < rows; ++i) {
			float confidence = data[4];
			if (confidence >= confidenceThreshold) {

				float * classes_scores = data + 5;
				cv::Mat scores(1, labels.size(), CV_32FC1, classes_scores);
				cv::Point class_id;
				double max_class_score;
				cv::minMaxLoc(scores, 0, &max_class_score, 0, &class_id);
				if (max_class_score > scoreThreshold) {
					predConfidences.push_back(confidence);
					predClassIds.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) * x_factor);
					int top = int((y - 0.5 * h) * y_factor);
					int width = int(w * x_factor);
					int height = int(h * y_factor);
					predBoxes.push_back(cv::Rect(left, top, width, height));
				}
			}

			data += dimensions;
		}

		std::vector<int> indices;
		cv::dnn::NMSBoxes(predBoxes, predConfidences, scoreThreshold, nmsThreshold, indices);
		for (int i = 0; i < indices.size(); i++) {
			int idx = indices[i];
			output.push_back({predClassIds[idx],predConfidences[idx],predBoxes[idx]});
		}
	}

	void detectWithDrawBox(const std::vector<std::string> &labels,cv::Mat & mat,float confidenceThreshold = 0.45,float scoreThreshold = 0.5,float nmsThreshold = 0.45) {

		std::vector<Data> result;

		auto begin = std::chrono::steady_clock::now();
		detect(mat, labels,result , confidenceThreshold, scoreThreshold,nmsThreshold);
		auto cost = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - begin).count() / 1000.0;

		std::stringstream cost_text;
		cost_text << std::fixed << std::setprecision(2) << "cost:" << cost << " fps:" << 1000.0 / cost << " number:" << result.size();

		cv::rectangle(mat,{10,5,268,20},{255,157,51},-1);
		cv::putText(mat, cost_text.str(), {10, 20}, cv::FONT_HERSHEY_PLAIN, 1, {255, 255, 255});

		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)};

		for (auto i = 0; i < result.size(); ++i) {
			auto &data = result[i];
			const auto color = colors[data.classIndex % colors.size()];

			std::stringstream text;
			text << std::fixed << std::setprecision(2) << "class " << labels[data.classIndex] << " rank " << data.confidence;
			cv::rectangle(mat, data.box, color, 1);
			auto pos = data.box.tl();

			auto fontSize = cv::getTextSize(text.str(),cv::FONT_HERSHEY_PLAIN,1,2, nullptr);
			cv::rectangle(mat,{pos.x, pos.y - fontSize.height,fontSize.width,fontSize.height + 1},color,-1);
			cv::putText(mat, text.str(), {pos.x, pos.y}, cv::FONT_HERSHEY_PLAIN, 1, {0,0,0});

		}
	}
private:
	cv::dnn::Net net;
	int width = 640.0;
	int height = 640.0;
};

int main(int argc, char * argv[]) {

	// input
	std::vector<std::string> _labels{"person", "bicycle", "car", "motorbike", "aeroplane",
									 "bus", "train", "truck", "boat", "traffic light", "fire hydrant", "stop sign",
									 "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow", "elephant",
									 "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase",
									 "frisbee", "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove",
									 "skateboard", "surfboard", "tennis racket", "bottle", "wine glass", "cup", "fork",
									 "knife", "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli", "carrot",
									 "hot dog", "pizza", "donut", "cake", "chair", "sofa", "pottedplant", "bed",
									 "diningtable", "toilet", "tvmonitor", "laptop", "mouse", "remote", "keyboard",
									 "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock",
									 "vase", "scissors", "teddy bear", "hair drier", "toothbrush"};
	std::string _source = R"(sample.mp4)";
	std::string _model = R"(yolov5s.onnx)";

	YoloV5 v5;
	v5.init(_model);

	cv::VideoCapture cap;
	cap.open(_source);
	cv::Mat mat(640, 640, CV_8UC3, {200, 200, 200});

	do {
		cap >> mat;
		if (mat.empty()) {
			break;
		}
		cv::resize(mat, mat, {640, 640});

		v5.detectWithDrawBox(_labels,mat,0.45,0.45,0.5);

		cv::imshow("win | press key q quit", mat);
		if (cv::waitKey(1) == 'q') {
			break;
		}
	} while (true);

	cv::waitKey();
	return 0;
}

https://learnopencv.com/object-detection-using-yolov5-and-opencv-dnn-in-c-and-python/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 opencv 调用 yolov5 onnx 模型 ? 的相关文章

  • I2C调试工具

    1 I2C调试工具 i2c tools工具是开源I2C调试工具 xff0c 具有获取I2C总线挂载的设备列表及设备地址 xff0c 可对指定设备指定寄存器进行读写的功能 ubuntu安装 xff1a apt get install libi
  • Ubuntu18版本安装ROS

    最近不小心把虚拟机里的ROS弄坏了 xff0c 导致Linux都无法使用 也忘了快照导致所以软件重新安装 xff0c 在这里给大家分享一下ubuntu18版本如何安装ros以及我安装中出现的问题如何进行解决 注 xff1a 不同的ubunt
  • ZED相机快速使用指南

    1 安装SDK ZED SDK 3 8 Download Stereolabs 2 安装ros GitHub stereolabs zed ros wrapper ROS wrapper for the ZED SDK 其他教程 xff1a
  • vscode:前进后退快捷键

    1 xff09 后退 xff1a alt 43 2 xff09 前进 xff1a alt 43
  • git: tag 和 branch 的区别

    前言 tag 是什么 tag 翻译过来是标签的意思 xff0c 顾名思义 xff0c 标签是为了标记某种事物 tag 是 Git 版本库的一个快照 xff0c 指向某个 commit 的指针 tag 的好处 tag 的存在 xff0c 是因
  • QApplication a(argc,argv);崩溃

    Microsoft Visual C 43 43 Debug Library Debug Error Program de mytoolkit mytoolkit mytoolkit Win32 Debug mytoolkit exe Mo
  • jetson Xavier nx安装torch和torchvision,并解决解决版本不匹配(报错RuntimeError: Couldn‘t load custom C++ ops)的问题

    目录 1 安装torch 2 安装torchvision 3 验证是否安装成功 4 错误记录 5 torch和torchvision网盘链接 首先 xff0c torch和torchvision都不能直接pip安装 xff0c 以下的演示是
  • C++ 数据结构:DS顺序表--合并操作

    题目描述 建立顺序表的类 xff0c 属性包括 xff1a 数组 实际长度 最大长度 xff08 设定为1000 xff09 已知两个递增序列 xff0c 把两个序列的数据合并到顺序表中 xff0c 并使得顺序表的数据递增有序 输入 第1行
  • ubuntu安装多个版本python

    背景 xff1a 本地环境 Ubuntu 22 04 64 bit xff0c 默认安装python3 10 6 xff0c 未安装pip venv 需求 xff1a 安装python3 8 xff0c 并安装两版本对应pip xff0c
  • socket编程中recv()和read()的使用与区别

    recv和read相似 xff0c 都可用来接收sockfd发送的数据 xff0c 但recv比read多了一个参数 xff0c 也就是第四个参数 xff0c 它可以指定标志来控制如何接收数据 1 recv 原型 xff1a ssize t
  • stm32printf函数的串口输出代码

    stm32f103串口一与串口二printf函数输出 因项目需要特意配置了该段代码 xff0c 不喜勿喷 xff0c 纯属个人笔记 对于串口的代码网上也是很多 xff0c 无非是配置问题 xff0c 该代码是基于stm32f103c8t6来
  • C/C++ —— 小端转大端函数的使用

    函数说明 uint32 t htonl uint32 t hostlong uint16 t htons uint16 t hostshort uint32 t ntohl uint32 t netlong uint16 t ntohs u
  • AntDesign Upload组件上传图片

    技术选型 前端技术选型 xff1a React Hook 43 typescript antd版本 xff1a 3 18 使用Upload上传图片 上传效果截图 预览效果截图 项目中完整写法 xff1a span class token k
  • [LeetCode] 876. Middle of the Linked List

    Given a non empty singly linked list with head node head return a middle node of linked list If there are two middle nod
  • 博客搬家啦

    博客搬家啦 xff0c 新博客地址 https blueleek blue 小伙伴一起嗨学一起来
  • MFC 改变编辑框字体(大小,字体)

    1 在 Dlg h文件中加入 CFont font 字体对象 2 定义一个CEdit控件变量 CEdit m EditAa 61 CEdit GetDlgItem IDC A EDIT A 关联控件A CEdit m EditBb 61 C
  • STM32 中浮点转成字符串,解决 -u_printf_float

    开发偶遇问题 在C 43 43 或其他高级语言中 xff0c 以及C语言在Visual Studio或者linux平台上 xff0c 是可以直接通过sprintf将 xff0c int float转换成string类型的 xff1b 但是
  • 路由器原理(一)

    觉得之前对路由器的了解还不是特别清楚 xff0c 继续来学习 xff0c 是参考了路由器的原理及其配置 xff08 一 xff09 一 xff1a 路由器的基础知识 xff08 1 xff09 路由器的概述 xff1a 作为网络层的网络互连
  • 表单提交及后台数据接收

    用POST请求 xff0c 后台原生接收的一个公式 xff1a span class hljs transposed variable req span addListener span class hljs string 34 data
  • JSON怎样添加注释

    今天在写一个程序的时候发现了一个问题 xff0c 在json文件中添加注释之后 xff0c 程序就出现bug了 于是 xff0c 去搜了一下这个问题的相关解释 xff0c 在这里和大家分享一下 xff1a JSON为什么不能添加注释 xff

随机推荐