C++手写NMS
文章目录
- 前言
- 一、NMS是什么?
- 二、代码展示
- 三、代码实现思路
- 总结
前言
目标检测模型推理后,一般都需要进行NMS操作进行多余框去重,板端部署一般不用opencv自带的NMS,所以记录下手写NMS的代码。
一、NMS是什么?
非极大值抑制(Non-Maximum Suppression,NMS)算法,用于在一组边界框(BoundingBoxes)中去除高度重叠的边界框,只保留最具代表性的一个。
二、代码展示
#include <iostream>
#include <vector>
#include <algorithm>// 边界框结构
struct BoundingBox {float x, y, w, h, confidence;// 计算边界框的面积float area() const {return w * h;}
};// 计算两个边界框之间的IoU
float iou(const BoundingBox& a, const BoundingBox& b) {const float area_a = a.area();const float area_b = b.area();// 计算重叠区域的坐标范围const float x1 = std::max(a.x, b.x);const float y1 = std::max(a.y, b.y);const float x2 = std::min(a.x + a.w, b.x + b.w);const float y2 = std::min(a.y + a.h, b.y + b.h);// 计算重叠区域的面积const float intersection_area = std::max(0.0f, x2 - x1) * std::max(0.0f, y2 - y1);// 计算并集区域的面积const float union_area = area_a + area_b - intersection_area;// 计算IoUreturn union_area > 0 ? intersection_area / union_area : 0;
}// 非极大值抑制函数
std::vector<BoundingBox> nms(std::vector<BoundingBox>& boxes, float threshold) {// 根据置信度排序std::sort(boxes.begin(), boxes.end(),[](const BoundingBox& a, const BoundingBox& b) { return a.confidence > b.confidence; });std::vector<BoundingBox> result;for (size_t i = 0; i < boxes.size(); ++i) {bool keep = true;for (size_t j = 0; j < result.size(); ++j) {if (iou(boxes[i], result[j]) > threshold) {keep = false;break;}}if (keep) {result.push_back(boxes[i]);}}return result;
}int main() {std::vector<BoundingBox> boxes;// 添加一些示例边界框数据boxes.push_back({10, 10, 20, 20, 0.9});boxes.push_back({15, 15, 25, 25, 0.8});boxes.push_back({30, 30, 20, 20, 0.7});boxes.push_back({40, 40, 15, 15, 0.85});// 运行非极大值抑制算法,保留不重叠的边界框float threshold = 0.5;std::vector<BoundingBox> result = nms(boxes, threshold);// 输出保留下来的边界框std::cout << "保留的边界框:" << std::endl;for (const BoundingBox& box : result) {std::cout << "x: " << box.x << ", y: " << box.y << ", w: " << box.w << ", h: " << box.h << ", confidence: " << box.confidence << std::endl;}return 0;
}
三、代码实现思路
iou(const BoundingBox& a, const BoundingBox& b): 这个函数计算两个边界框a和b之间的交并比(IoU,Intersection over Union)。它首先计算每个边界框的面积,然后计算它们的交集区域的坐标范围和面积。最后,它将交集区域的面积除以并集区域的面积,得到IoU值,即重叠度。
nms(std::vector<BoundingBox>& boxes, float threshold): 这个函数实现了非极大值抑制算法。它接受一个包含边界框的向量 boxes 和一个阈值 threshold 作为参数。首先,它按照边界框的置信度(confidence)对边界框进行降序排序,以便首先处理置信度最高的边界框。
然后,它遍历每个边界框,并检查它是否应该被保留。对于每个边界框,它将其与已经被保留的边界框进行比较,计算它们之间的IoU。如果IoU大于阈值 threshold,则说明两个边界框高度重叠,当前边界框不被保留;否则,当前边界框被保留。
最终,函数返回一个向量 result,其中包含经过非极大值抑制后被保留下来的边界框。
总结
NMS通常用于目标检测中,以去除重叠的检测结果,只保留最具代表性的结果,以提高检测的准确性。
如果阅读本文对你有用,欢迎点赞收藏呀!!!
2023年9月27日15:58:10

相关文章:
C++手写NMS
文章目录 前言一、NMS是什么?二、代码展示三、代码实现思路总结 前言 目标检测模型推理后,一般都需要进行NMS操作进行多余框去重,板端部署一般不用opencv自带的NMS,所以记录下手写NMS的代码。 一、NMS是什么? 非极大…...
第9讲:VUE中监听器WATCH使用详解
目录 监听器介绍 监听普通属性 监听对象属性 监听路由属性监听器watch 监听器:它是侦听属性值或者计算属性的变化,一旦发生变化可以在函数中进行相应的操作,从而达到change事件监听的效果!监听器是一个对象,以 key-value 的形式表示。key 是需要监听的表达式,value 是对…...
微信小程序开发基础(一)认识小程序
微信小程序,小程序的一种,英文名Wechat Mini Program,是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下即可打开应用。微信小程序是一种不用下载就能使用的应用,也是…...
LeetCode 1049. 最后一块石头的重量 II
1049. 最后一块石头的重量 II - 力扣(LeetCode) 有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y&am…...
Golang中的类型转换介绍
Golang中存在4种类型转换,分别是:断言、显式、隐式、强制。下面我将一一介绍每种转换使用场景和方法 一、断言类型转换 主要是判断变量是否可以转换成某一类型。断言主要用于变量是interface{}类型(接口类型)的情况,…...
本人碰到的RN项目的坑
1.路径问题 路径不能含有中文 2.下载jar\aar包超时问题 手动下载:任意位置新建个文件夹,然后点击超时的jar包链接跳转到浏览器后下载到这个文件夹内,返回报错的地方找到报错的包名(com或者org开头的),然后去这个路径下找到对应的包名 C:\Users\22560\.gradle\caches\module…...
EcmaScript标准-导入与导出-js
ECMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会,European Computer Manufacturers Association)通过ECMA-262标准化的脚本程序设计语言。这种语言在万维网上应用广泛,它往往被称为JavaScript或JScript,所以它…...
如何将matlab中的mat矩阵文件在python中读取出来
先安装hdf5storage这个包 pip3 install hdf5storage 然后在当前目录下放入要读取的mat文件 # 将matlab中的mat文件读取出来 import hdf5storagedata hdf5storage.loadmat(inputWeights.mat) print(data[inputWeights])...
解释C语言中 6.18f (浮点数常量后缀)
在C语言中,例如6.18f ,这是一个浮点数常量。 6.18 是一个浮点数,而后缀 f 表示该浮点数是单精度浮点数。 在C语言中,默认的浮点数常量类型是双精度浮点数,如果希望使用单精度浮点数,可以在常量后面加上 f…...
Pandas 2.1中的新改进和新功能
大家好,Pandas 2.1于2023年8月30日发布,跟随本文一起看看这个版本引入了哪些新内容,以及它如何帮助用户改进Pandas的工作负载,包含了一系列改进和一组新的弃用功能。 Pandas 2.1在Pandas 2.0中引入的PyArrow集成基础上进行了大量…...
c#static(静态)关键字
在C#中,static关键字有多种用途,可以用于声明静态成员、静态类和静态方法。 静态成员:使用static关键字声明的成员属于类,而不是类的实例。静态成员在类第一次被使用之前就被初始化,且只有一个副本存在于内存中&#x…...
GitHub配置SSH key
GitHub配置SSH key Git配置信息并生成密钥 设置用户名和密码 设置用户名 git config --global user.name "用户名" 设置邮箱 git confir --global user.email "邮箱" 生成密钥 ssh-keygen -t rsa -C "邮箱" 查看密钥 到密钥所保存的位置 复…...
文件审计及文件完整性监控
什么是文件审核 对文件服务器中发生的所有事件的检查称为文件审核。这包括监视文件访问,其中包含谁访问了什么文件、何时以及从何处访问的详细信息;对访问最多和修改的文件的分析;成功和失败的文件访问尝试;等等。文件服务器审核过程的主要目标是跟踪在配置的服务器…...
华为智能企业远程办公安全解决方案(1)
华为智能企业远程办公安全解决方案(1) 课程地址方案背景需求分析企业远程办公业务概述企业远程办公安全风险分析企业远程办公环境搭建需求分析 方案设计组网架构设备选型方案亮点 课程地址 本方案相关课程资源已在华为O3社区发布,可按照以下…...
k8s中常用命令总结
文章目录 进入pod容器的命令pod中只有1个用户容器pod中只有2个(含)以上用户容器 yaml中的字段不清楚后面跟什么,通过explain来查看查看pod内指定容器的日志Pod内各个容器的服务端口不能相同资源对象的创建方式一方式二 查看pod的详细信息查看…...
Logistic map混沌掩盖信号
开学接触了一些有关混沌知识的学习,阅读量一些混沌通信的论文,对于混沌掩盖信号以确保加密通信有一定的兴趣。混沌的产生我选用的是logistic map映射产生混沌,主要就是一个递推公式: 对于这样一个式子,可以看出&#x…...
外包干了2个月,技术有明显退步...
先说一下自己的情况,本科生,18年通过校招进入广州某软件公司,干了接近3年的功能测试,今年国庆,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!可我已经在一个企业干了3年的功能测试&…...
顺序表和链表
顺序表和链表 一.线性表二.顺序表三.链表链表的分类单链表的实现双链表的实现 四.顺序表和链表的区别和联系 一.线性表 常见的线性表:顺序表、链表、栈、队列、字符串 线性表在逻辑上是线性结构,也就说是连续的一条直线,但是在物理结构上并不…...
k8s--架构基础--云控制器管理器
具体来说,云控制器管理器允许用户将集群与云服务提供商的 API 进行连接,以获取与云平台相关的信息和资源。通过这种连接,Kubernetes 可以利用云服务提供商的功能和特性,例如虚拟机、负载均衡器、对象存储等。与此同时,…...
OpenAI 更新 ChatGPT:支持图片和语音输入【附点评】
一、消息正文 9月25日消息,近日OpenAI宣布其对话AI系统ChatGPT进行升级,添加了语音输入和图像处理两个新功能。据OpenAI透露,这些新功能将在未来两周内面向ChatGPT Plus付费用户推出,免费用户也将很快可以使用这些新功能。这标志着ChatGPT继续朝着多模态交互的方向发展,为用户提…...
LLM-PDF开源工具:高质量文档解析与结构化处理实战指南
1. 项目概述:当LLM遇上PDF,一个开源工具如何重塑文档处理流程最近在折腾一个项目,需要让大语言模型(LLM)去理解一批技术规格书和合同文档。这事儿听起来简单,不就是把PDF扔给模型,让它读吗&…...
5分钟掌握猫抓浏览器扩展:免费视频下载和媒体嗅探终极指南
5分钟掌握猫抓浏览器扩展:免费视频下载和媒体嗅探终极指南 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 猫抓(cat-catch)是一款专业的…...
Python统一调用多AI模型:python-tgpt库实战指南
1. 项目概述:一个让Python与AI对话更简单的工具 如果你最近在尝试用Python调用各种大语言模型(LLM)的API,比如OpenAI的GPT、Google的Gemini,或者开源的Llama、Mistral,那你大概率经历过这样的场景…...
嵌入式固件开发知识体系构建:从硬件交互到系统级设计
1. 固件开发者知识体系构建:从“会写代码”到“懂系统”干了十几年嵌入式,我越来越觉得,固件开发这行,光会调库、写业务逻辑是远远不够的。你写的每一行代码,最终都要在真实的物理世界里跑起来,要和传感器、…...
跨工具技能同步:构建统一操作习惯的中间层架构与实践
1. 项目概述:一个跨工具技能同步的构想在数字工具爆炸式增长的今天,我们每个人几乎都活在一个“工具丛林”里。作为一名长期与各种生产力工具、开发环境、设计软件打交道的从业者,我深刻体会到一种割裂感:在A工具里熟练无比的快捷…...
C++多线程编程:深入剖析std::thread的使用方法
一、线程std::thread简介std::thread 是 C11 中引入的一个库,用于实现多线程编程。它允许程序创建和管理线程,从而实现并发执行。std::thread 在 #include<thread>头文件中声明,因此使用 std::thread 时需要包含 #include<thread>…...
中国词元与世界AI元语:模力方舟和口袋龙虾的协同进化
在AI产业从技术突破转向生态竞争的今天,一个核心命题日益凸显:如何让顶尖的AI能力跨越技术鸿沟,真正触达每一个开发者与终端用户?开源中国以“模力方舟”与“口袋龙虾”为双核驱动,构建了一条从底层资源聚合到上层应用…...
【独家首发】DeepSeek-V2模型GPU利用率可视化方案:仅需3个自定义Metrics,告别盲调参数
更多请点击: https://intelliparadigm.com 第一章:DeepSeek Grafana可视化 DeepSeek 是一款高性能、低延迟的开源时序数据引擎,其原生支持 Prometheus 兼容指标暴露。将 DeepSeek 与 Grafana 集成,可实现对模型推理吞吐、GPU 显存…...
ARM LDM指令原理与应用详解
1. ARM LDM指令架构解析LDM(Load Multiple)指令是ARM架构中用于批量加载数据的核心指令之一。作为一位长期从事ARM底层开发的工程师,我经常需要在中断处理、上下文切换等场景中使用LDM指令。与单寄存器加载指令相比,LDM指令通过单条指令即可实现从连续内…...
AI浪潮下,普通程序员如何避免沦为“提示词工程师”?
一、从“提示词执行者”到“质量架构师”:重新定义测试的价值锚点AI之所以能替代大量重复性测试工作,是因为它擅长处理“已知的已知”——那些规则明确、边界清晰的测试场景。然而,软件测试的真正价值,从来不在执行层面࿰…...
