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继续朝着多模态交互的方向发展,为用户提…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...