当前位置: 首页 > news >正文

使用C++版本的opencv dnn 部署onnx模型

使用OpenCV的DNN模块在C++中部署ONNX模型涉及几个步骤,包括加载模型、预处理输入数据、进行推理以及处理输出。

构建了yolo类,方便调用

yolo.h 文件

#ifndef YOLO_H
#define YOLO_H
#include <fstream>
#include <sstream>
#include <iostream>
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>struct yoloDetectionResult_detection_thread
{cv::Point2f DetectionResultLocation; // 目标中心点像素位置cv::Point2d DetectionResultClassAndConf; //类型、置信度cv::Rect DetectionResultRect; //目标矩形框cv::Mat DetectionResultIMG;   //目标像素unsigned char object_no = -1;  //目标序号unsigned char object_mission = -1; //目标任务状态int frame_no;  //图像帧号
};
class detect_result
{
public:int classId;float confidence;cv::Rect_<float> box;};class YOLO
{
public:YOLO();~YOLO();void init(std::string onnxpath);void detect(cv::Mat& frame, std::vector<detect_result>& result);void draw_frame(cv::Mat& frame, std::vector<detect_result>& results);private:cv::dnn::Net net;const float confidence_threshold_ = 0.4f;const float nms_threshold_ = 0.4f;const int model_input_width_ = 640;const int model_input_height_ = 640;double HighWidthHeightRatio = 25;double LowWidthHeightRatio = 0.05;
};#endif // !YOLO_H

yolo.cpp

#include "yolo.h"YOLO::YOLO()
{}YOLO::~YOLO()
{}void YOLO::init(std::string onnxpath)
{this->net = cv::dnn::readNetFromONNX(onnxpath);
}void YOLO::detect(cv::Mat& frame, std::vector<detect_result>& results)
{int w = frame.cols;int h = frame.rows;int _max = std::max(h, w);cv::Mat image = cv::Mat::zeros(cv::Size(_max, _max), CV_8UC3);if(frame.channels()==1){cv::cvtColor(frame, frame, cv::COLOR_GRAY2BGR);}  cv::Rect roi(0, 0, w, h);frame.copyTo(image(cv::Rect(0, 0, w, h)));float x_factor = static_cast<float>(image.cols) / model_input_width_;float y_factor = static_cast<float>(image.rows) / model_input_height_;cv::Mat blob = cv::dnn::blobFromImage(image, 1 / 255.0, cv::Size(model_input_width_, model_input_height_), cv::Scalar(0, 0, 0), true, false);this->net.setInput(blob);cv::Mat preds = this->net.forward("output0");//outputname,使用Netron看一下输出的名字,一般为output0或者outputcv::Mat det_output(preds.size[1], preds.size[2], CV_32F, preds.ptr<float>());std::vector<cv::Rect> boxes;std::vector<int> classIds;std::vector<float> confidences;for (int i = 0; i < det_output.rows; i++){float box_conf = det_output.at<float>(i, 4);if (box_conf < nms_threshold_){continue;}cv::Mat classes_confidences = det_output.row(i).colRange(5, 6);cv::Point classIdPoint;double cls_conf;cv::minMaxLoc(classes_confidences, 0, &cls_conf, 0, &classIdPoint);if (cls_conf > confidence_threshold_){float cx = det_output.at<float>(i, 0);float cy = det_output.at<float>(i, 1);float ow = det_output.at<float>(i, 2);float oh = det_output.at<float>(i, 3);int x = static_cast<int>((cx - 0.5 * ow) * x_factor);int y = static_cast<int>((cy - 0.5 * oh) * y_factor);int width = static_cast<int>(ow * x_factor);int height = static_cast<int>(oh * y_factor);cv::Rect box;box.x = x;box.y = y;box.width = width;box.height = height;boxes.push_back(box);classIds.push_back(classIdPoint.x);confidences.push_back(cls_conf * box_conf);}}std::vector<int> indexes;cv::dnn::NMSBoxes(boxes, confidences, confidence_threshold_, nms_threshold_, indexes);for (size_t i = 0; i < indexes.size(); i++){detect_result dr;int index = indexes[i];int idx = classIds[index];dr.box = boxes[index];dr.classId = idx;dr.confidence = confidences[index];results.push_back(dr);}std::vector<cv::Rect>().swap(boxes);std::vector<int>().swap( classIds);std::vector<float>().swap( confidences);std::vector<int>().swap( indexes);
}void YOLO::draw_frame(cv::Mat& frame, std::vector<detect_result>& results)
{for (auto dr : results){cv::rectangle(frame, dr.box, cv::Scalar(0, 0, 255), 2, 8);cv::rectangle(frame, cv::Point(dr.box.tl().x, dr.box.tl().y - 20), cv::Point(dr.box.br().x, dr.box.tl().y), cv::Scalar(255, 0, 0), -1);std::string label = cv::format("%.2f", dr.confidence);label = dr.classId + ":" + label;cv::putText(frame, label, cv::Point(dr.box.x, dr.box.y + 6), 1, 2, cv::Scalar(0, 255, 0), 2);}}

下面是调用函数编写部分

#include<string>
#include"yolo.h"
#include<opencv2\opencv.hpp>
#include<iostream>
int main(){YOLO* yolo = new YOLO;std::string modelPath =  "C:\\Resource\\model\\XXX.onnx";//模型的地址std::string imgPath=  "C:\\Resource\\model\\XXX.jpg";//模型的地址//clock_t start_times{},end_times{};yolo->init(modelPath);std::vector<detect_result> output;cv::Mat yoloImages = cv::imread(imgPath);if(!yoloImages.empty()){  //start_times= clock();yolo->detect(yoloImages, output);yolo->draw_frame(yoloImages, output);//end_times = clock();//double FPS = 1 / ((double)(end_times - start_times) / CLOCKS_PER_SEC);cv::imshow("images", yoloImages);cv::waitKey(1);std::vector<detect_result>().swap(output);std::string().swap(model);if(yolo!=NULL){delete yolo;yolo =NULL;}}
}	

相关文章:

使用C++版本的opencv dnn 部署onnx模型

使用OpenCV的DNN模块在C中部署ONNX模型涉及几个步骤&#xff0c;包括加载模型、预处理输入数据、进行推理以及处理输出。 构建了yolo类&#xff0c;方便调用 yolo.h 文件 #ifndef YOLO_H #define YOLO_H #include <fstream> #include <sstream> #include <io…...

python中实现队列功能

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 python中实现队列功能 选择题 以下代码最后一次输出的结果是&#xff1f; from collections import deque queue deque() queue.append(1) queue.append(2) queue.append(3) print(【显示】…...

自然资源-关于城镇开发边界局部优化的政策思路梳理

自然资源-关于城镇开发边界局部优化的政策思路梳理 国土空间规划的核心之一是要统筹划定“三区三线”&#xff0c;三条控制线中的城镇开发边界的划定与优化工作&#xff0c;一直是国土空间规划改革的重要组成部分&#xff0c;其有助于遏制城市盲目扩张&#xff0c;强化底线约束…...

ElementUI的Table组件在无数据情况下让“暂无数据”文本居中显示

::v-deep .el-table__empty-block {width: 100%;min-width: 100%;max-width: 100%; }...

SAP-BASIS14-安装语言包

...

ant design的upload组件踩坑记录

antd版本 v4.17.0 1.自定义了onpreview和onchange事件&#xff0c;上传文件后&#xff0c;文件显示有preview的icon但是被禁用&#xff0c;无法调用onpreview事件。 问题展现&#xff1a; 苦苦查找原因&#xff0c;问题出在了这里&#xff0c;当文件没有url的时候&#xff0c…...

Python私教张大鹏 Vue3整合AntDesignVue之按钮组件

何时使用 标记了一个&#xff08;或封装一组&#xff09;操作命令&#xff0c;响应用户点击行为&#xff0c;触发相应的业务逻辑。 在 Ant Design Vue 中我们提供了五种按钮。 主按钮&#xff1a;用于主行动点&#xff0c;一个操作区域只能有一个主按钮。默认按钮&#xff1…...

【小海实习日记】PHP安装

## PHP环境搭建(Mac) ### php安装 使用brew需要安装homebrew >brew tap shivammathur/php >brew install shivammathur/php/php7.3 >brew link php7.3 这里可以需要homebrew使用代理进行下载&#xff0c;如果代理下载速度还是太慢&#xff0c;建议直接更该国内镜像…...

C++ Primer Chapter 4 Expressions

Chapter 4 Expressions 4.11 类型转换 4.11.2 其他隐式类型转换 数组转换成指针&#xff1a; 在大多数用到数组的表达式中&#xff0c;数组自动转换成指向数组首元素的指针&#xff1a; int ia[10]; int* ipa;♜ 当数组被用作decltype关键字的参数&#xff0c;或者作为取地…...

[leetcode hot 150]第一百三十七题,只出现一次的数字Ⅱ

题目&#xff1a; 给你一个整数数组 nums &#xff0c;除某个元素仅出现 一次 外&#xff0c;其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。 由于需要常数级空间和线性时间复杂度…...

wpf工程中加入Hardcodet.NotifyIcon.Wpf生成托盘

1、在项目中用nuget引入Hardcodet.NotifyIcon.Wpf。如下图所示。 2、在App.xaml中创建托盘界面&#xff0c;代码是写在 App.xaml 里面 注意在application中一定要加入这一行代码&#xff1a; xmlns:tb"http://www.hardcodet.net/taskbar" 然后在<Application.R…...

keil下载及安装(社区版本)

知不足而奋进 望远山而前行 目录 文章目录 前言 Keil有官方版本和社区版本&#xff0c;此文章为社区版本安装&#xff0c;仅供参考。 1.keil MDK 2.keil社区版介绍 3.keil下载 (1)打开进入登录界面 (2)点击下载,跳转到信息页面 (3)填写个人信息,点击提交 (4)点击下载…...

python书上的动物是啥

Python的创始人为Guido van Rossum。1989年圣诞节期间&#xff0c;在阿姆斯特丹&#xff0c;Guido为了打发圣诞节的无趣&#xff0c;决心开发一个新的脚本解释程序&#xff0c;做为ABC语言的一种继承。之所以选中Python作为程序的名字&#xff0c;是因为他是一个叫Monty Python…...

数据库管理-第198期 升级Oracle ACE Pro,新赛季继续努力(20240605)

数据库管理198期 2024-06-05 数据库管理-第198期 升级ACE Pro&#xff0c;新赛季继续努力&#xff08;20240605&#xff09;1 惊喜2 变化3 Oracle ACE总结 数据库管理-第198期 升级ACE Pro&#xff0c;新赛季继续努力&#xff08;20240605&#xff09; 作者&#xff1a;胖头鱼的…...

华为坤灵交换机S300, S500, S210,S220, S200, S310 如何WEB抓包

通过S系列交换机配置端口镜像实现抓包 1、应用场景 端口镜像是指将经过指定端口(源端口或者镜像端口)的报文复制一份到另一个指定端口(目的端口或者观察端口)。 在网络运营与维护的过程中&#xff0c;为了便于业务监测和故障定位&#xff0c;网络管理员时常要获取设备上的业务…...

【亚马逊云科技 CSDN 联合巨献】 「对话AI 构建者:从基础到应用的 LLM 全景培训」 限时免费!

&#x1f680;&#x1f31f;【亚马逊云科技 & CSDN 联合巨献】 &#x1f4da;「对话AI 构建者&#xff1a;从基础到应用的 LLM 全景培训」&#x1f525; 限时免费&#xff01; &#x1f4c6; 抓紧时间&#xff01;6月7日前注册&#xff0c;原价 399&#xff0c;现在仅需 0…...

【AI大模型】Function Calling

目录 什么是Function Calling 示例 1&#xff1a;调用本地函数 Function Calling 的注意事项 支持 Function Calling 的国产大模型 百度文心大模型 MiniMax ChatGLM3-6B 讯飞星火 3.0 通义千问 几条经验总结 什么是Function Calling Function Calling 是一种函数调用机…...

零钱兑换 - LeetCode 热题 85

大家好&#xff01;我是曾续缘&#x1f92a; 今天是《LeetCode 热题 100》系列 发车第 85 天 动态规划第 5 题 ❤️点赞 &#x1f44d; 收藏 ⭐再看&#xff0c;养成习惯 零钱兑换 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &…...

基于web的垃圾分类回收系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;用户管理&#xff0c;公告管理&#xff0c;运输管理&#xff0c;基础数据管理 用户账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;运输管理&#xff0c;公告…...

优化你的WordPress网站:内链建设与Link Whisper Pro插件的利用

文章目录 内链的重要性WordPress SEO插件&#xff1a;Link Whisper Pro主要功能使用指南下载与安装 结语 在数字营销和网站管理领域&#xff0c;SEO内部优化是提升网站排名、增加流量和提高用户参与度的核心策略。在众多SEO技巧中&#xff0c;内链建设是构建良好网站结构和提升…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...