opencv dnn模块 示例(20) 目标检测 object_detection 之 yolor
文章目录
- 1、论文介绍
- 1.1、YOLOR思想动机
- 1.2、隐式知识学习
- 1.2.1、隐式知识如何工作
- 1.2.2、隐式知识统一网络建模
- 1.3、实验
- 1.4、总结
- 2、测试
- 2.1、opencv dnn
- 2.1.1、代码
- 2.1.2、结果
- 2.2、测试效率
YOLOR出自论文You Only Learn One Representation: Unified Network for Multiple Tasks,受人类学习方式(使用五官,通过常规和潜意识学习,总结丰富的经验并编码存储,进而处理已知或未知的信息)的启发,论文提出了一个统一的网络来同时编码显式知识和隐式知识,在网络中执行了kernel space alignment(核空间对齐)、prediction refinement(预测细化)和 multi-task learning(多任务学习),同时对多个任务形成统一的表示。结果表明神经网络中引入隐式知识有助于所有任务的性能提升,进一步的分析发现隐式表示之所以能带来性能提升,是因为其具备了捕获不同任务的物理意义的能力。
1、论文介绍
paper: https://arxiv.org/abs/2105.04206
code: https://github.com/WongKinYiu/yolor
1.1、YOLOR思想动机
如图1所示,人可以从多个角度来分析同一个目标,然而通常训练CNN时只给予了一个角度,也就是说针对某一个任务得到的CNN特征很难适用于其他问题。作者认为造成上述问题的原因主要是模型只提取了神经元特征而丢弃了隐式知识的学习运用,然而就像人脑一样隐式知识对分析各种各样的任务是非常有用的。
人类对隐式知识的学习通常通过潜意识,然而并没有系统的定义怎样学习和获得隐式知识。对于神经网络而言,一般将浅层特征定义为显式知识,深层特征定义为隐式知识。本文将直接可观察的知识定义为显式知识,隐藏在神经网络中且无法观察的知识定义为隐式知识。
如图2所示,提出了一个统一的网络来集成显式知识和隐式知识,通过学习统一的表达,使得各个子表示能够适用于不同任务。基于前人工作的理论基础,本文结合压缩感知和深度学习来构建统一网络。
本文主要贡献如下:
-
提出了一个可同时完成多种任务的统一网络,它通过融合显式知识和隐式知识学习一个可以完成多个任务的统一表征,提出的网络可以有效的提升模型的表现,仅增加千分之一不到的计算成本;
-
通过 kernel space alignment(核空间对齐)、prediction refinement(预测细化)和 multi-task learning(多任务学习)来完成隐式知识的学习,并验证了其有效性;
-
分别讨论了隐式知识的建模方式,包括向量、神经网络、矩阵分解,并验证了这些方式的有效性;
-
证实了所提出的内隐表征学习方法能够准确地对应于特定的物理特征,并以视觉的方式进行了呈现;还证实了如果算子符合目标的物理意义,它可以用来整合隐式知识和显式知识,并会产生乘数效应;
-
与SOTA比较,YOLOR能够实现和目标检测Scaled-YOLOv4-P7一样的精度,但是推理速度快了88%。
1.2、隐式知识学习
1.2.1、隐式知识如何工作
流形空间约简
核空间对齐
更多功能和处理方式
1.2.2、隐式知识统一网络建模
隐式知识的表示
Unified Networks:
隐式知识的建模
向量/矩阵/张量
矩阵分解
训练
推理
1.3、实验
3.1 实验设置
3.2 FPN特征对齐
3.3 目标检测预测细化
3.4 多任务规范表征
3.5 隐式知识建模不同算子比较
3.6 隐式知识建模不同方式比较
3.7 隐式知识模型分析
3.8 隐式知识提升目标检测
1.4、总结
2、测试
这里以 yolor-p6-640-640 进行测试。网络模型可以看到,输出一共有4个,实际是4个尺度上的结果,最终通过reshape和concat合并成一个输出(输出格式与yolov5一致)。

2.1、opencv dnn
2.1.1、代码
使用和yolov5相同的测试代码。
#pragma once#include "opencv2/opencv.hpp"#include <fstream>
#include <sstream>#include <random>using namespace cv;
using namespace dnn;float inpWidth;
float inpHeight;
float confThreshold, scoreThreshold, nmsThreshold;
std::vector<std::string> classes;
std::vector<cv::Scalar> colors;bool letterBoxForSquare = true;cv::Mat formatToSquare(const cv::Mat &source);void postprocess(Mat& frame, cv::Size inputSz, const std::vector<Mat>& out, Net& net);void drawPred(int classId, float conf, int left, int top, int right, int bottom, Mat& frame);std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dis(100, 255);int testYoloR()
{// 根据选择的检测模型文件进行配置 confThreshold = 0.25;scoreThreshold = 0.45;nmsThreshold = 0.5;float scale = 1 / 255.0; //0.00392Scalar mean = {0,0,0};bool swapRB = true;inpWidth = 640;inpHeight = 640;String modelPath = R"(E:\DeepLearning\yolor\yolor-p6-640-640.onnx)";String configPath;String framework = "";//int backendId = cv::dnn::DNN_BACKEND_OPENCV;//int targetId = cv::dnn::DNN_TARGET_CPU;int backendId = cv::dnn::DNN_BACKEND_CUDA;int targetId = cv::dnn::DNN_TARGET_CUDA; String classesFile = std::string(R"(\data\coco.names)");// Open file with classes names.if(!classesFile.empty()) {const std::string& file = classesFile;std::ifstream ifs(file.c_str());if(!ifs.is_open())CV_Error(Error::StsError, "File " + file + " not found");std::string line;while(std::getline(ifs, line)) {classes.push_back(line);colors.push_back(cv::Scalar(dis(gen), dis(gen), dis(gen)));}}// Load a model.Net net = readNet(modelPath, configPath, framework);net.setPreferableBackend(backendId);net.setPreferableTarget(targetId);//std::vector<String> outNames = net.getUnconnectedOutLayersNames();std::vector<String> outNames{"output"};{int dims[] = {1,3,inpHeight,inpWidth};cv::Mat tmp = cv::Mat::zeros(4, dims, CV_32F);std::vector<cv::Mat> outs;net.setInput(tmp);for(int i = 0; i<10; i++)net.forward(outs, outNames); // warmup}// Create a windowstatic const std::string kWinName = "Deep learning object detection in OpenCV";cv::namedWindow(kWinName, 0);// Open a video file or an image file or a camera stream.VideoCapture cap;cap.open(R"(E:\DeepLearning\yolov5\data\images\bus.jpg)");cv::TickMeter tk;// Process frames.Mat frame, blob;while(waitKey(1) < 0) {//tk.reset();//tk.start();cap >> frame;if(frame.empty()) {waitKey();break;}// Create a 4D blob from a frame.cv::Mat modelInput = frame;if(letterBoxForSquare && inpWidth == inpHeight)modelInput = formatToSquare(modelInput);blobFromImage(modelInput, blob, scale, cv::Size2f(inpWidth, inpHeight), mean, swapRB, false);// Run a model.net.setInput(blob);std::vector<Mat> outs;//tk.reset();//tk.start();auto tt1 = cv::getTickCount();net.forward(outs, outNames);auto tt2 = cv::getTickCount();tk.stop();postprocess(frame, modelInput.size(), outs, net);//tk.stop(); Put efficiency information.//std::vector<double> layersTimes;//double freq = getTickFrequency() / 1000;//double t = net.getPerfProfile(layersTimes) / freq;//std::string label = format("Inference time: %.2f ms (%.2f ms)", t, /*tk.getTimeMilli()*/ (tt2 - tt1) / cv::getTickFrequency() * 1000);std::string label = format("Inference time: %.2f ms", (tt2 - tt1) / cv::getTickFrequency() * 1000);cv::putText(frame, label, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));cv::imshow(kWinName, frame);}return 0;
}cv::Mat formatToSquare(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 postprocess(Mat& frame, cv::Size inputSz, const std::vector<Mat>& outs, Net& net)
{// yolov5 has an output of shape (batchSize, 25200, 85) (Num classes + box[x,y,w,h] + confidence[c])auto tt1 = cv::getTickCount();float x_factor = inputSz.width / inpWidth;float y_factor = inputSz.height / inpHeight;std::vector<int> class_ids;std::vector<float> confidences;std::vector<cv::Rect> boxes;int rows = outs[0].size[1];int dimensions = outs[0].size[2];float *data = (float *)outs[0].data;for(int i = 0; i < rows; ++i) {float confidence = data[4];if(confidence >= confThreshold) {float *classes_scores = data + 5;cv::Mat scores(1, classes.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 > scoreThreshold) {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) * 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));}}data += dimensions;}std::vector<int> indices;NMSBoxes(boxes, confidences, scoreThreshold, nmsThreshold, indices);auto tt2 = cv::getTickCount();std::string label = format("NMS time: %.2f ms", (tt2 - tt1) / cv::getTickFrequency() * 1000);cv::putText(frame, label, Point(0, 30), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));for(size_t i = 0; i < indices.size(); ++i) {int idx = indices[i];Rect box = boxes[idx];drawPred(class_ids[idx], confidences[idx], box.x, box.y,box.x + box.width, box.y + box.height, frame);}
}void drawPred(int classId, float conf, int left, int top, int right, int bottom, Mat& frame)
{rectangle(frame, Point(left, top), Point(right, bottom), Scalar(0, 255, 0));std::string label = format("%.2f", conf);Scalar color = Scalar::all(255);if(!classes.empty()) {CV_Assert(classId < (int)classes.size());label = classes[classId] + ": " + label;color = colors[classId];}int baseLine;Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);top = max(top, labelSize.height);rectangle(frame, Point(left, top - labelSize.height),Point(left + labelSize.width, top + baseLine), color, FILLED);cv::putText(frame, label, Point(left, top), FONT_HERSHEY_SIMPLEX, 0.5, Scalar());
}
2.1.2、结果
测试如图,发现误识别了一个 traffic light。对比源py测试脚本,修改 bool letterBoxForSquare = false; 将等比缩放关闭后检测正常。

2.2、测试效率
RTX-1080ti,i7-7700k
opencv cpu:630ms
opencv gpu :52ms
opencv gpu (fp16):793ms
以下统计时间包含: 预处理+推理+后处理
openvino(cpu):274ms
onnxruntime(gpu):30ms
tensorrt:23ms
相关文章:
opencv dnn模块 示例(20) 目标检测 object_detection 之 yolor
文章目录 1、论文介绍1.1、YOLOR思想动机1.2、隐式知识学习1.2.1、隐式知识如何工作1.2.2、隐式知识统一网络建模 1.3、实验1.4、总结 2、测试2.1、opencv dnn2.1.1、代码2.1.2、结果 2.2、测试效率 YOLOR出自论文You Only Learn One Representation: Unified Network for Mult…...
【队列的顺序表示,链式表示】
文章目录 队列的表示和实现相关术语队列的表示链队的表示链队的定义链队的初始化销毁链队列 链队列的入队出栈 队列的表示和实现 相关术语 队列(Queue)是仅在表尾进行插入操作,在表头进行删除操作的线性表。表尾即an端,称为队尾…...
Pydantic 实践
1. 简介 pydantic 库是一种常用的用于数据接口 schema 定义与检查的库。 通过 pydantic 库,我们可以更为规范地定义和使用数据接口,这对于大型项目的开发将会更为友好。 当然,除了 pydantic 库之外,像是 valideer 库、marshmallo…...
获取pandas中的众数
pandas.DataFrame 也有一个 mode() 方法。 以下面的 pandas.DataFrame 为例。 df pd.DataFrame({‘col1’: [‘X’, ‘X’, ‘Y’, ‘X’], ‘col2’: [‘X’, ‘Y’, ‘Y’, ‘X’]}, index[‘row1’, ‘row2’, ‘row3’, ‘row4’]) print(df) col1 col2 row1 X X row2…...
SOLIDWORKS Simulation2024仿真10大新功能
SOLIDWORKS Simulation新增功能 1. 增强型轴承接头 •通过指定压缩、拉伸和弯曲的刚度,轻松创建自定义轴承接头。•通过向非线性和大型位移算例添加自定义条件,提高模拟精度。 优点:使用功能强大的接口,更轻松 、 更 准 确 地 设…...
Java程序设计2023-第二次上机练习
这里要用到一些面向对象的基本知识 目录 7-1 伪随机数 输入格式: 输出格式: 输入样例: 输出样例: 7-2 jmu-Java-03面向对象基础-01-构造方法与toString 1.编写无参构造函数: 2.编写有参构造函数 3.覆盖toString函数: 4.对每个属性生成setter…...
如何在 uniapp 里面使用 pinia 数据持久化 (pinia-plugin-persistedstate)
想要在 uniapp 里面使用 pinia-plugin-persistedstate 会遇到的问题就是 uniapp里面没有浏览器里面的 sessionStorage localStorage 这些 api。 我们只需要替换掉 pinia-plugin-persistedstate 默认的储存 api 就可以了。使用 createPersistedState 重新创建一个实例, 把里面的…...
智慧矿山AI算法助力护帮板支护监测,提升安全与效率
在智慧矿山AI算法系列中,护帮板支护监测是保障矿山安全和提高生产效率的重要环节。护帮板作为矿山支护体系中的重要组成部分,在矿山生产中起到了关键的作用。那么,护帮板在哪种状态下是正常打开的呢?本文将对此进行介绍。 护帮板的…...
shell中的运算
目录 1.运算符号 2.运算指令 练习 1.运算符号 运算符号意义加法-减法*乘法/除法%除法后的余数**乘方自加一- -自减一<小于<小于等于>大于>大于等于等于ji ->jji*j*i->jj*i/j/i->jj/i%j%i->jj%i 2.运算指令 (()) //((a12))let //let a12 …...
【Java 进阶篇】解决Java Web应用中请求参数中文乱码问题
在Java Web应用开发中,处理请求参数时经常会遇到中文乱码的问题。当浏览器向服务器发送包含中文字符的请求参数时,如果不正确处理,可能会导致乱码问题,使得参数无法正确解析和显示。本文将详细探讨Java Web应用中请求参数中文乱码…...
51单片机-点阵屏led
代码配置 这样就能选择每一列哪个亮了 进行位选,段清零,这样就不会影响多列同时了 实现动画 1、使用文字摸提取文件,提取图案的16进制表示数组 offest作为偏移量,count作为计时。count10,偏移量加1,就相当于得到下一…...
Angular-03:组件模板
各种学习后的知识点整理归纳,非原创! 组件模板 ① 数据绑定② 属性绑定③ 类名绑定④ 样式绑定⑤ 事件绑定⑥ 获取原生DOM对象6.1 在组件模板中获取6.2 在组件类中获取 ⑦ 双向数据绑定⑧ 内容投影8.1 select选择器8.2 单槽投影8.3 多槽投影 ⑨ 安全操作…...
mysql 操作慢查询日志
1、mysql 批量插入300w数据 CREATE PROCEDURE test_insert_200w() BEGINDECLARE i INT;SET i1;WHILE i<3000000 DOINSERT INTO shop_user (password, telephone, username) VALUES (admin, 15510304125, concat(admin, i));SET ii1;END WHILE; END; //执行sql call test_in…...
illuminate/database 使用 二
上一篇文章写怎么单独使用illuminate/database,这回讲下怎么整合到项目里使用。为此特意看了下laravel对其使用。本篇文章,参照laravel的使用,简单实现。 一 原理 laravel 里使用illuminate/config。 illuminate/config composer 地址&…...
二叉树的概念
文章目录 二叉树一、树的概念1.树形结构1.1. 树的特点:1.2 概念:1.3 树的表示形式 2.树的应用 二、二叉树1.二叉数的概念2.满二叉树3.完全二叉树4.二叉树的性质练习: 二叉树 一、树的概念 1.树形结构 1.1. 树的特点: 1.根节点没…...
SpringCloud之Eureka的学习【详细】
目录 服务架构演变 单体架构 分布式架构 分布式架构需要考虑的问题 微服务 架构比较 微服务技术对比 服务拆分注意事项 案例 服务远程调用 RestTemplate Eureka注册中心 RestTemplate存在的问题 服务调用考虑的问题 Eureka的作用 搭建EurekaServer 服务注册 …...
学习ftp
文章目录 一、FTP介绍二、两种模式(主动模式和被动模式)三、FTP配置文件详解四、实际场景举例五、黑白名单六、网络限制 一、FTP介绍 1.FTP(File Transfer Protocol)是一种应用广泛且古老的互联网文件传输协议。 2.主要应用于互联…...
Android笔记(九):Compose组件的状态(一)
在使用Compose定义UI界面时,可以发现界面的变换往往与Compose组件内部的状态相关,当状态值发生变化时,Compose构成的可组合的界面也会刷新发生相应的变化。将在本笔记中将对可组合项的状态的定义、状态提升、状态丢失和状态的保存进行简单介绍…...
3.2. onnx export multi_batch
前言 将onnx bs=1 修改为多batch操作 参考链接: https://www.cnblogs.com/tangjunjun/p/16500116.html https://blog.csdn.net/weixin_43863869/article/details/128638397?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault…...
探索低代码PaaS平台的优势与选择原因
PaaS是一种云产品,它为应用程序的开发和部署提供基础结构。它提供中间件、开发工具和人工智能来创建功能强大的应用程序,大多数PaaS服务都与存储和网络基础架构捆绑在一起,就像基础架构即服务(IaaS)一样,可…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
