yolov5 opencv dnn部署自己的模型
yolov5 opencv dnn部署自己的模型
- github开源代码地址
- 使用github源码结合自己导出的onnx模型推理自己的视频
- 推理条件
- c++部署
- c++ 推理结果
github开源代码地址
- yolov5官网还提供的dnn、tensorrt推理链接
- 本人使用的opencv c++ github代码,代码作者非本人,也是上面作者推荐的链接之一
- 如果想要尝试直接运行源码中的yolo.cpp文件和yolov5s.pt推理sample.mp4,请参考这个链接的介绍
使用github源码结合自己导出的onnx模型推理自己的视频
推理条件
windows 10
Visual Studio 2019
Nvidia GeForce GTX 1070
opencv 4.5.5、opencv4.7.0 (注意 4.7.0中也会出现跟yolov5 opencv dnn部署 github代码一样的问题)
yolov5 v6.1版本
c++部署
环境和代码的大致步骤跟yolov5 opencv dnn部署 github代码一样
在将所有前置布置好了之后,运行yolo.cpp的时候可能会出现图1problem的问题。
这个是由于yolov5 v6.1版本的问题,可以参考github源码中的issue的解决方案。当然,也可以按照下面的进行代码进行修改。
#include <fstream>#include <opencv2/opencv.hpp>std::vector<std::string> load_class_list()
{std::vector<std::string> class_list;std::ifstream ifs("./config_files/classes_fire.txt");std::string line;while (getline(ifs, line)){class_list.push_back(line);}return class_list;
}void load_net(cv::dnn::Net &net, bool is_cuda)
{auto result = cv::dnn::readNet("./config_files/yolov5n.onnx");if (is_cuda){std::cout << "Attempty to use CUDA\n";result.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);result.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);}else{std::cout << "Running on CPU\n";result.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);result.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);}net = result;
}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 INPUT_WIDTH = 640.0;
const float INPUT_HEIGHT = 640.0;
const float SCORE_THRESHOLD = 0.2;
const float NMS_THRESHOLD = 0.4;
const float CONFIDENCE_THRESHOLD = 0.4;struct Detection
{int class_id;float confidence;cv::Rect box;
};cv::Mat format_yolov5(const cv::Mat &source) {int col = source.cols;int row = source.rows;int _max = MAX(col, row);cv::Mat result = cv::Mat::zeros(_max, _max, CV_8UC3);source.copyTo(result(cv::Rect(0, 0, col, row)));return result;
}// 所有的代码修改都在这个函数中
void detect(cv::Mat &image, cv::dnn::Net &net, std::vector<Detection> &output, const std::vector<std::string> &className) {cv::Mat blob;auto input_image = format_yolov5(image);cv::dnn::blobFromImage(input_image, blob, 1./255., cv::Size(INPUT_WIDTH, INPUT_HEIGHT), cv::Scalar(), true, false);net.setInput(blob);std::vector<cv::Mat> outputs;// 添加代码,使用opencv4.5.5的时候注释掉,使用opencv4.7.0可以使用net.enableWinograd(false);net.forward(outputs, net.getUnconnectedOutLayersNames());float x_factor = input_image.cols / INPUT_WIDTH;float y_factor = input_image.rows / INPUT_HEIGHT;float *data = (float *)outputs[0].data;const int dimensions = 85;const int rows = 25200;const int max_wh = 768; // 这个值是偏移量,这个酌情选择,不然太大会导致dnn:nms不工作// 添加代码int out_dim2 = outputs[0].size[2]; // 这里的是class+conf+xywh,相当于COCO的指标的85std::vector<int> class_ids;std::vector<float> confidences;std::vector<cv::Rect> boxes;std::vector<cv::Rect> boxes_muti;for (int i = 0; i < rows; ++i) {// 添加代码int index = i * out_dim2; // 每一次循环索引都是下一个pre_box的初始位置float confidence = data[4 + index]; // 修改代码 这样读取的值就是下一个的pre_box的confif (confidence >= CONFIDENCE_THRESHOLD) {// 修改代码 这样读取的值就是下一个的pre_box的classfloat * classes_scores = data + 5 + index;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);max_class_score *= confidence; // conf = obj_conf * cls_confif (max_class_score > SCORE_THRESHOLD) {confidences.push_back(max_class_score);class_ids.push_back(class_id.x);// 修改代码,这样读取的值就是下一个的pre_box的xywhfloat x = data[0 + index];float y = data[1 + index];float w = data[2 + index];float h = data[3 + index];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));// 实现多分类NMS,如果不需要实现,就直接删掉该部分// 在这里添加的是类似yolov5nms的class_id位置偏移int left_muti = int((x - 0.5 * w) * x_factor + class_id.x * max_wh);int top_muti = int((y - 0.5 * h) * y_factor + class_id.x * max_wh);int width_muti = int(w * x_factor + class_id.x * max_wh);int height_muti = int(h * y_factor + class_id.x * max_wh);boxes_muti.push_back(cv::Rect(left_muti, top_muti, width_muti, height_muti));}}}std::vector<int> nms_result;cv::dnn::NMSBoxes(boxes_muti, confidences, SCORE_THRESHOLD, NMS_THRESHOLD, nms_result);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(int argc, char **argv)
{std::vector<std::string> class_list = load_class_list();cv::Mat frame;cv::VideoCapture capture("sample_fire2.mp4");// 如果想要将结果保存为视频/*cv::VideoWriter writer;int coder = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');double fps_w = 25.0;//设置视频帧率std::string filename = "fire.avi";//保存的视频文件名称writer.open(filename, coder, fps_w, cv::Size(640, 360));//创建保存视频文件的视频流 Size(640, 360)是smaple_fire2.mp4的分辨率*/if (!capture.isOpened()){std::cerr << "Error opening video file\n";return -1;}// 因为是window系统,且直接使用VStudio运行代码的,如果想使用cuda,直接将is_cuda = true即可bool is_cuda = argc > 1 && strcmp(argv[1], "cuda") == 0;cv::dnn::Net net;load_net(net, is_cuda);auto start = std::chrono::high_resolution_clock::now();int frame_count = 0;float fps = -1;int total_frames = 0;while (true){capture.read(frame);if (frame.empty()){std::cout << "End of stream\n";break;}std::vector<Detection> output;detect(frame, net, output, class_list);frame_count++;total_frames++;int detections = output.size();for (int i = 0; i < detections; ++i){auto detection = output[i];auto box = detection.box;auto classId = detection.class_id;const auto color = colors[classId % colors.size()];cv::rectangle(frame, box, color, 3);cv::rectangle(frame, cv::Point(box.x, box.y - 20), cv::Point(box.x + box.width, box.y), color, cv::FILLED);cv::putText(frame, class_list[classId].c_str(), cv::Point(box.x, box.y - 5), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));}if (frame_count >= 30){auto end = std::chrono::high_resolution_clock::now();fps = frame_count * 1000.0 / std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();frame_count = 0;start = std::chrono::high_resolution_clock::now();}if (fps > 0){std::ostringstream fps_label;fps_label << std::fixed << std::setprecision(2);fps_label << "FPS: " << fps;std::string fps_label_str = fps_label.str();cv::putText(frame, fps_label_str.c_str(), cv::Point(10, 25), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 0, 255), 2);}cv::imshow("output", frame);// writer.write(frame); // 如果想要将结果保存为视频if (cv::waitKey(1) != -1){capture.release();// writer.release(); // 如果想要将结果保存为视频std::cout << "finished by user\n";break;}}std::cout << "Total frames: " << total_frames << "\n";return 0;
}
c++ 推理结果
opencv 4.5.5
yolov5 v6.1 导出的是yolov5n.onnx
yolov5_deploy_fire
opencv 4.7.0
yolov5 v6.1 导出的是yolov5n.onnx
yolov5_deploy_fire2
相关文章:

yolov5 opencv dnn部署自己的模型
yolov5 opencv dnn部署自己的模型 github开源代码地址使用github源码结合自己导出的onnx模型推理自己的视频推理条件c部署c 推理结果 github开源代码地址 yolov5官网还提供的dnn、tensorrt推理链接本人使用的opencv c github代码,代码作者非本人,也是上面作者推荐的…...
Cortex-M4处理器 电源管理
Cortex-M4处理器的休眠模式可以降低功耗。 模式可以是以下一种或两种: 休眠模式停止处理器时钟深度睡眠模式停止系统时钟,关闭锁相环和闪存。 如果设备实现了两种提供不同级别省电的睡眠模式,那么SCR的SLEEPDEEP位将选择使用哪种睡眠模式。…...

Linux 驱动开发基础知识——编写LED驱动程序(三)
个人名片: 🦁作者简介:一名喜欢分享和记录学习的在校大学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755qq.com 🦉个人WeChat:V…...
YOLOv8 视频识别
YOLOv8 是一种目标检测算法,用于识别视频中的物体。要控制视频识别中的帧,可以通过以下方式来实现: 设置帧率:可以通过设置视频的帧率来控制视频的播放速度,从而影响视频识别的速度。 跳帧处理:可以通过跳…...

elementplus Dialog 对话框设置距离页面顶部的距离
默认为 15vh,当弹窗过于高的时候,这个距离其实是不合适的 <el-dialogv-model"dialogVisible"title"Tips"width"30%":before-close"handleClose"top"6vh"><span>This is a message</s…...

便捷接口调测:API 开发工具大比拼 | 开源专题 No.62
hoppscotch/hoppscotch Stars: 56.1k License: MIT Hoppscotch 是一个开源的 API 开发生态系统,主要功能包括发送请求和获取实时响应。该项目具有以下核心优势: 轻量级:采用简约的 UI 设计。快速:实时发送请求并获得响应。支持多…...
openssl3.2/test/certs - 008 - root-nonca trust variants: +serverAuth +anyEKU
文章目录 openssl3.2/test/certs - 008 - root-nonca trust variants: serverAuth anyEKU概述笔记END openssl3.2/test/certs - 008 - root-nonca trust variants: serverAuth anyEKU 概述 openssl3.2 - 官方demo学习 - test - certs 笔记 // \file my_openssl_win_log_doc…...

cg插画设计行业怎么样,如何学习插画设计
插画设计行业是一个充满创意和艺术性的行业,随着数字化时代的不断发展,cg插画的应用范围越来越广泛,市场需求也在逐年增长。以下是一些关于acg插画设计行业的现状和发展趋势: 市场需求不断增长:随着广告、媒体、影视、…...

1.25学习总结
今天学习了二叉树,了解了二叉树的创建和遍历的过程 今天所了解的遍历过程主要分为三种,前序中序和后序,都是DFS的想法 前序遍历:先输出在遍历左节点和右节点(输出->左->右) 中序遍历:先…...

C语言每日一题(48)回文链表
力扣 234 回文链表 题目描述 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。 示例 1: 输入:head [1,2,2,1] 输出:true示例 2࿱…...
提高代码效率的5个Python内存优化技巧
大家好,当项目变得越来越大时,有效地管理计算资源是一个不可避免的需求。Python与C或c等低级语言相比,似乎不够节省内存。 但是其实有许多方法可以显著优化Python程序的内存使用,这些方法可能在实际应用中并没有人注意࿰…...

基于一款热门大屏可视化设计器使用教程
乐吾乐大屏可视化设计器是一个用于创建和定制大屏幕数据可视化展示的工具,支持零代码实现物联网、工业智能制造等领域的可视化大屏、触摸屏端UI以及工控可视化的解决方案。同时也是一个Web组态工具,支持2D、3D等多种形式,用于构建具有实时数据…...
梯度下降法、模拟训练、拟合二次曲线、最小二乘法、MSELoss、拟合:f(x)=ax^2+bx+c
本文目标: 以这个公式为例,设计一个算法,用梯度下降法来模拟训练过程,最终得出参数a,b,c 原理介绍 目标函数: 损失函数:,就是mse 损失函数展开: 损失函数对a,b,c求导数: 导数就是梯度…...

Web3.0投票如何做到公平公正且不泄露个人隐私
在当前的数字时代,社交平台举办投票活动已成为了一种普遍现象。然而,随之而来的是一些隐私和安全方面的顾虑,特别是关于个人信息泄露和电话骚扰的问题。期望建立一个既公平公正又能保护个人隐私的投票系统。Web3.0的出现为实现这一目标提供了…...

灰度图像的自动阈值分割
第一种:Otsu (大津法) 一、基于cv2的API调用 1、代码实现 直接给出相关代码: import cv2 import matplotlib.pylab as pltpath r"D:\Desktop\00aa\1.png" img cv2.imread(path, 0)def main2():ret, thresh1 cv2.…...

利用Maven获取jar包
我有一个习惯,就是程序不在线依赖网络的任何包。以前用C#时候虽然用Nuget找包,但是添加引用后又马上把Nuget引用删了,再把Nuget下载的dll拷贝到工程再引用dll。 这样做的好处是: 1.别人得到程序代码可以直接编译,不用…...

将vue组件发布成npm包
文章目录 前言一、环境准备1.首先最基本的需要安装nodejs,版本推荐 v10 以上,因为需要安装vue-cli2.安装vue-cli 二、初始化项目1.构建项目2.开发组件/加入组件3. 修改配置文件 三、调试1、执行打包命令2、发布本地连接包3、测试项目 四、发布使用1、注册…...

江科大STM32 中
目录 6、TIM(Timer)定时器基本定时器通用定时器高级定时器示例程序(定时器定时中断&定时器外部时钟)TIM输出比较示例程序(PWM驱动LED呼吸灯&PWM驱动舵机&PWM驱动直流电机)TIM输入捕获示例程序&…...

vue+draggable+el-upload上传图片拖拽重排方法
vuedraggableel-upload上传图片拖拽重排方法 1.html <el-row><el-col><el-form-item label"添加视频/图片" prop"device_id"><div class"image-upload"><draggable v-model"fileList" update"dataDr…...

微信的新版canvas绘制的图案发生变形和偏移的问题
一,现象 this.context.beginPath(); this.context.moveTo(10, 10); this.context.lineTo(10, 100); this.context.lineTo(100, 100); this.context.lineTo(100, 10); this.context.lineTo(10, 10); this.context.stroke();本来绘制的是正方形,结果绘制出来是个矩形,边的宽度也…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...