嵌入式AI---如何用C++实现YOLO的NMS(非极大值抑制)算法

文章目录

  • 前言
  • 一、为什么需要NMS算法?
  • 二、什么是NMS算法?
  • 三、如何使用C++编写一个NMS算法
    • 1、预测框定义
    • 2、滤除无效框
  • 总结


前言

YOLO系列的目标检测算法在边缘部署方面展现出了强大的性能和广泛的应用潜力。大部分业务场景是利用PyTorch在服务器端完成检测模型的训练,得到相应的.pt、.onnx检测模型文件。随后,对模型计算量和硬件成本进行综合考量,完成边缘计算设备选型。最后,根据不同的硬件设备,将.pt或onnx模型文件转化成适配对应硬件平台的模型文件再进行推理(如瑞芯微的rknn格式、昇腾的om格式)。
目前网上大多数资料用的是YOLOV5官方源码提供的Python推理版本,然而实际业务场景往往需要基于C++在板子上完成模型推理。这就涉及到了一些模型输入预处理,输出后处理的问题,本文将简单介绍如何利用C++实现YOLOV5的后处理NMS算法。


一、为什么需要NMS算法?

先不思考什么是NMS,先思考为什么需要引入这个算法:
以YOLOV5为例,假设YOLOV5的输入图像大小为320x320x3,那么输出特征图的大小就为40x40、20x20、10x10。输出特征图的每个点都铺设了3个锚框,故最终有(40x40+20x20+10x10)x3个预测框。实际业务场景不可能有这么多的预测目标,我们需要先基于每个框的置信度筛除一批无效预测框(这一步还不是NMS,只是基于置信度进行筛除,因为大多数框都是无效框,利用置信度可以筛除90%以上的预测框)。
在这里插入图片描述
筛除了一批预测框后,由于目标附近可能会有多个预测框的置信度较高(也就是有多个预测框同时选中了目标),因此我们需要从中选取一个作为结果输出,这就需要引入一种滤除算法消除其它预测框,YOLO中用的就是NMS。

二、什么是NMS算法?

非极大值抑制(NMS),如名字所示,目的在于抑制非极大值的预测框。那么什么是极大值呢,其实就是局部区域内可信度得分最高的预测框。NMS算法的作用就是抑制局部区域内得分较低的预测框,最后保留那个极大值预测框。
对于目标检测场景,为了解决同一个目标被多个锚框选中的问题,我们引入了非极大值抑制算法(NMS),局部区域内只保留一个得分最高的目标框。

三、如何使用C++编写一个NMS算法

1、预测框定义

typedef struct Box{float x;	//预测框左上角坐标xfloat y;	//预测框左上角坐标yfloat w;	//框宽float h;	//框高float score;  //得分
}Box;

假设预测框的结构体定义如上所示,Box结构体中包含了预测框的位置、大小以及该框的得分。注意(需提前处理YOLO的输出内容,将输出内容都转化为Box结构体变量,此处省略该代码)

2、滤除无效框

NMS算法的思路如下:
(1)将所有预测框按照得分从高到低进行排序。
(2)从得分最高的预测框开始,依次遍历排序后的预测框列表中的每一个预测框,计算它与列表中后续所有预测框之间的IOU值。在计算IOU后,将那些IOU值大于预设阈值的后续预测框从候选框列表中移除。
(3)完成上述步骤后,继续遍历候选框列表中的下一个预测框,重复执行上述计算IOU和剔除高重叠预测框的过程,直到候选框列表中的所有预测框都被遍历完毕。

因此,我们需要先对预测框进行排序,假设预测框全都存放在vector类对象boxVec中,那么我们需要对boxVec内的全部预测框进行排序。

bool compare(Box b1, Box b2)
{return b1.score>b2.score? true:false;
}
vector<Box> boxVec;
sort(boxVec.begin(), boxVec.end(), compare);

随后编写一个计算两个预测框IOU的函数:

float IOU(Box b1, Box b2)
{  float x1 = max(b1.x, b2.x); 	//重叠框的四个坐标float x2 = min(b1.x + b1.w, b2.x + b2.w); float y1 = max(b1.y, b2.y);float y2 = min(b1.y + b1.h, b2.y + b2.h);float overlap_area = max(0.0f, x2 - x1) * max(0.0f, y2 - y1); //重叠区域大小  if (overlap_area == 0) return 0.0f; // 如果没有重叠,IoU为0  float union_area = b1.w * b1.h + b2.w * b2.h - overlap_area; //联合区域大小// 使用更常见的分母  float iou = overlap_area / union_area ;  return iou;  
}  

在这里插入图片描述

最后,利用排序好的boxVec和IOU函数完成无效框滤除:

size_t i = 0;  
float nms_ratio = 0.5;  
while(i < boxVec.size())  
{  size_t j = i + 1;  while(j < boxVec.size())  {  if(IOU(boxVec[i], boxVec[j]) > nms_ratio)  {  // 删除元素,并且不增加 j 的值  boxVec.erase(boxVec.begin() + j);  }  else  {  // 如果没有删除元素,则增加 j  j++;  }  }  i++;  
}

至此,boxVec中重叠的预测框就被滤除了。


总结

本文基于C++编写了一个简化版的NMS代码,简单介绍了相关的设计思路,实际使用可能仍需优化或存在疏漏,具体需根据业务需求动态调整代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/54322.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【网络安全】-ssrf服务器请求伪造攻击-burp

SSRF攻击服务器请求伪造攻击 CSRF攻击跨站请求伪造攻击也称客户端请求伪造攻击 两种攻击最主要的区别是一个在服务器&#xff0c;一个在客户端。 文章目录 前言 什么是SSRF攻击? 1.分类&#xff1a; 针对服务器的 SSRF 攻击&#xff1a; 针对后端系统的SSRF攻击&#xff1a; …

【Echarts】vue3打开echarts的正确方式

ECharts 是一个功能强大、灵活易用的数据可视化工具&#xff0c;适用于商业报表、数据分析、科研教育等多种场景。那么该如何优雅的使用Echarts呢? 这里以vue3为例。 安装echarts pnpm i echarts封装公用方法 // ts-nocheck import * as echarts from echarts; // 我们这里借…

Linux系统应用之知识补充——OpenEuler(欧拉)的安装和基础配置

前言 这篇文章将会对OpenEuler的安装进行详解&#xff0c;一步一步跟着走下去就可以成功 注意 &#xff1a;以下的指令操作最好在root权限下进行&#xff08;即su - root&#xff09; ☀️工贵其久&#xff0c;业贵其专&#xff01; 1、OpenEuler的安装 这里我不过多介绍&a…

相亲交友系统 现代爱情的导航仪

在这个数字化的时代&#xff0c;人们的生活方式发生了翻天覆地的变化&#xff0c;其中最显著的变化之一便是交友方式的转变。编辑h17711347205随着社会节奏的加快&#xff0c;越来越多的人选择通过相亲交友系统来寻找人生伴侣。相亲交友系统不仅简化了传统的交友流程&#xff0…

Java设计模式——工厂方法模式(完整详解,附有代码+案例)

文章目录 5.3 工厂方法模式5.3.1概述5.3.2 结构5.3.3 实现 5.3 工厂方法模式 针对5.2.3中的缺点&#xff0c;使用工厂方法模式就可以完美的解决&#xff0c;完全遵循开闭原则。 5.3.1概述 工厂方法模式&#xff1a;定义一个创建对象的接口&#xff08;这里的接口指的是工厂&…

第一次安装Pytorch

1、新版本的Anaconda内置的python版本是3.12&#xff0c; 目前 Windows 上的 PyTorch 仅支持 Python 3.8-3.11;不支持 Python 2.x。 1、创建运行环境 在不创建虚拟环境的情况下&#xff0c;不建议使用最新的Python和Anaconda。 在几次失败后&#xff0c;我使用的是Anaconda3-2…

微服务保护学习笔记(五)Sentinel授权规则、获取origin、自定义异常结果、规则持久化

文章目录 前言4 授权规则4.1 基本原理4.2 获取origin4.3 配置授权规则 5 自定义异常结果6 规则持久化 前言 微服务保护学习笔记(一)雪崩问题及解决方案、Sentinel介绍与安装 微服务保护学习笔记(二)簇点链路、流控操作、流控模式(关联、链路) 微服务保护学习笔记(三)流控效果(…

力扣 2529.正整数和负整数的最大计数

文章目录 题目介绍解法 题目介绍 解法 采用红蓝染色体法&#xff0c;具体介绍参考 红蓝染色体法 通过红蓝染色体法可以找到第一个大于大于target的位置&#xff0c;使所以本题可以找第一个大于0的位置&#xff0c;即负整数的个数&#xff1b;数组长度 - 第一个大于1的位置即正…

什么品牌超声波清洗机质量好?四大绝佳超声波清洗机品牌推荐!

在快节奏的现代生活中&#xff0c;个人物品的清洁卫生显得至关重要。眼镜、珠宝饰品、手表乃至日常餐厨用具&#xff0c;这些频繁接触的物品极易累积污渍与细菌。拿眼镜为例&#xff0c;缺乏定期清洁会让油渍与尘埃积累&#xff0c;进而成为细菌的温床&#xff0c;靠近眼睛使用…

2024最新版,人大赵鑫老师《大语言模型》新书pdf分享

本书主要面向希望系统学习大语言模型技术的读者&#xff0c;将重点突出核心概念与 算法&#xff0c;并且配以示例与代码&#xff08;伪代码&#xff09;帮助读者理解特定算法的实现逻辑。由于大语言模型技术的快速更迭&#xff0c;本书无法覆盖所有相关内容&#xff0c;旨在梳理…

《黑神话悟空》开发框架与战斗系统解析

本文主要围绕《黑神话悟空》的开发框架与战斗系统解析展开 主要内容 《黑神话悟空》采用的技术栈 《黑神话悟空》战斗系统的实现方式 四种攻击模式 连招系统的创建 如何实现高扩展性的战斗系统 包括角色属性系统、技能配置文件和逻辑节点的抽象等关键技术点 版权声明 本…

如何查看电脑什么时候被人动过及看过的文件?

一、查看Windows事件查看器 Windows系统具有强大的日志记录功能&#xff0c;通过“事件查看器”可以查看电脑的使用记录。具体步骤如下&#xff1a; 按下Win R组合键打开运行窗口&#xff0c;输入eventvwr.msc命令并回车&#xff0c;打开事件查看器。 在事件查看器中&#x…

C语言 14 结构体 联合体 枚举

之前认识过很多种数据类型&#xff0c;包括整数、小数、字符、数组等&#xff0c;通过使用对应的数据类型&#xff0c;就可以很轻松地将数据进行保存了&#xff0c;但是有些时候&#xff0c;这种简单类型很难去表示一些复杂结构。 结构体 比如现在要保存 100 个学生的信息&am…

黑神话悟空mac可以玩吗

黑神话悟空mac上能不能玩对于苹果玩家来说很重要&#xff0c;那么黑神话悟空mac可以玩吗&#xff1f;目前是玩不了了&#xff0c;没有针对ios系统的版本&#xff0c;只能之后在云平台上找找了&#xff0c;大家可以再观望下看看。 黑神话悟空mac可以玩吗 ‌使用CrossOver‌&…

PyCharm 调试 Xinference 遇到问题及解决方案

本文使用的 PyCharm 2024.2.1 版本&#xff0c;如果使用低版本 PyCharm&#xff0c;那么在调试 Xinference v0.15.1 源码时可能会报错 Connection to Python debugger failed Socket closed。 一.PyCharm 调试 Xinference 源码 由于 Xinference 中的一些依赖包仅支持 Linux&a…

用友U8二次开发工具KK-FULL-*****-EFWeb使用方法

1、安装: 下一步&#xff0c;下一步即可。弹出黑框不要关闭&#xff0c;让其自动执行并关闭。 2、服务配置&#xff1a; 输入服务器IP地址&#xff0c;选择U8数据源&#xff0c;输入U8用户名及账号&#xff0c;U8登录日期勾选系统日期。测试参数有效性&#xff0c;提示测试通过…

【Obsidian】当笔记接入AI,Copilot插件推荐

当笔记接入AI&#xff0c;Copilot插件推荐 自己的知识库笔记如果增加AI功能会怎样&#xff1f;AI的回答完全基于你自己的知识库余料&#xff0c;是不是很有趣。在插件库中有Copilot插件这款插件&#xff0c;可以实现这个梦想。 一、什么是Copilot&#xff1f; 我们知道githu…

FTP管理工具 FileZilla Pro v3.66.5 中文绿色便携版

FileZilla 是一款跨平台的多线程FTP工具&#xff0c;支持SL/TLS (FTPS)协议、SFTP等多种主流的传输协议&#xff0c;软件采用了有条理、简洁的用户界面&#xff0c;支持多站点管理&#xff0c;可以管理多个FTP站点&#xff0c;可以自由新建站点&#xff0c;提供了一个简单化&am…

vue websocket 使用

基于webSocket通信的库主要有 socket.io&#xff0c;SockJS 关于SockJS的使用 先安装 sockjs-client 和 stompjs npm install sockjs-client npm install stompjs import SockJS from sockjs-client; import Stomp from stompjs; export default { data () { …

Android 内置应用裁剪

文章目录 查询目标 APK 的 Android.mk&#xff08;或 Android.bp&#xff09;文件apk裁剪方式1.注释或删除.mk/.bp文件2.将 APK 名称加入“OVERRIDES”配置项中3.自定义“PRODUCT_PACKAGES_REMOVE”配置项 查询目标 APK 的 Android.mk&#xff08;或 Android.bp&#xff09;文件…