C# OpenCV机器视觉:SoftNMS非极大值抑制

嘿,你知道吗?阿强最近可忙啦!他正在处理一个超级棘手的问题呢,就好像在一个混乱的战场里,到处都是乱糟糟的候选框,这些候选框就像一群调皮的小精灵,有的重叠在一起,让阿强头疼不已。他的任务就是把这些重叠的候选框整理清楚,只留下最优秀的那些,让它们规规矩矩地排好队,为他的图像识别任务服务。

阿强听说了两种神奇的魔法 —— 非极大值抑制(NMS)和软非极大值抑制(SoftNMS),它们可以帮助他解决这个难题。这就像两个神奇的指挥官,能指挥这些候选框小精灵们听从命令,变得井然有序。

一、混乱的候选框战场

想象一下,阿强的图像里有好多候选框,每个候选框都觉得自己是最重要的,都想站在最前面,结果就是它们挤在一起,你压着我,我压着你,就像一堆挤在一起的小方块,乱成了一锅粥。这可不行啊,阿强需要从中挑选出最出色的候选框,不能让它们这样乱哄哄的。

阿强决定使用 OpenCvSharp 来施展魔法,他知道,这两种抑制方法就像两把神奇的扫帚,能把这些混乱的候选框清理干净呢 让我们来看看它们是怎么工作的吧。

二、非极大值抑制(NMS):严格的指挥官

首先登场的是 NMS,这个方法就像一个严格的指挥官,它的原则很简单:只留下最厉害的,把其他重叠的都赶走。

class NMS
{// 定义一个类来存储得分和索引  public class ScoreIndex{public float Score { get; set; }public int Index { get; set; }public ScoreIndex(float score, int index){Score = score;Index = index;}}static List<int> NmsBoxes(List<Rect> boxes, float[] scores, float iouThreshold){List<int> selectedIndices = new List<int>();int n = boxes.Count;// 将得分和索引组合在一起  List<ScoreIndex> indexedScores = new List<ScoreIndex>();for (int i = 0; i < n; i++){indexedScores.Add(new ScoreIndex(scores[i], i));}// 按得分降序排序  indexedScores.Sort((a, b) => b.Score.CompareTo(a.Score));bool[] selected = new bool[n];for (int i = 0; i < n; i++){int currentIndex = indexedScores[i].Index;if (selected[currentIndex]) continue;selectedIndices.Add(currentIndex);selected[currentIndex] = true;for (int j = i + 1; j < n; j++){int compareIndex = indexedScores[j].Index;if (selected[compareIndex]) continue;float iou = ComputeIoU(boxes[currentIndex], boxes[compareIndex]);if (iou > iouThreshold){selected[compareIndex] = true; // 抑制重叠框  }}}return selectedIndices;}static float ComputeIoU(Rect boxA, Rect boxB){// 计算交集  int x1 = Math.Max(boxA.X, boxB.X);int y1 = Math.Max(boxA.Y, boxB.Y);int x2 = Math.Min(boxA.X + boxA.Width, boxB.X + boxB.Width);int y2 = Math.Min(boxA.Y + boxA.Height, boxB.Y + boxB.Height);int interWidth = Math.Max(0, x2 - x1);int interHeight = Math.Max(0, y2 - y1);float interArea = interWidth * interHeight;// 计算并集  float boxAArea = boxA.Width * boxA.Height;float boxBArea = boxB.Width * boxB.Height;float unionArea = boxAArea + boxBArea - interArea;return interArea / unionArea;}
}

代码解析:

  1. 整理候选框和得分:首先,NMS 会把每个候选框的得分和索引组合在一起,就像给每个候选框小精灵贴上一个带有分数的名牌。然后,按照得分的高低给它们排好队,分数高的排在前面,这样最优秀的候选框就站在了最前面啦。接着,创建一个 selected 数组,用来标记哪些候选框已经被选中,哪些要被淘汰。
  2. 挑选最优候选框:从得分最高的候选框开始,把它标记为选中,放入 selectedIndices 列表中。然后,检查其他候选框,如果它们和这个选中的候选框重叠度(通过 ComputeIoU 计算)超过了 iouThreshold,就把它们标记为淘汰,就像指挥官说:“你和最优秀的重叠太多啦,你被淘汰啦!”ComputeIoU 函数会计算两个候选框的交并比(IoU),它是判断两个候选框重叠程度的重要指标哦。先找到两个框重叠部分的面积,再算出它们的并集面积,用重叠面积除以并集面积就得到了 IoU 值啦。如果 IoU 值大,说明它们重叠得多,需要处理一下。

三、软非极大值抑制(SoftNMS):温柔的协调者

接下来是 SoftNMS,它可不像 NMS 那么严格啦,它就像一个温柔的协调者,不会直接把重叠的候选框淘汰,而是会给它们一个机会,让它们的分数慢慢降低,变得不那么 “骄傲”。

class NMS
{// Soft-NMS 部分  static void SoftNMSRun(){// 示例候选框(x1, y1, x2, y2)  List<Rect> boxes = new List<Rect>{new Rect(50, 50, 50, 50),   // 框1  new Rect(55, 55, 50, 50),   // 框2(与框1重叠)  new Rect(200, 200, 50, 50)   // 框3(不重叠)  };// 示例得分  float[] scores = new float[] { 0.9f, 0.95f, 0.8f };// Soft-NMS 实现  List<int> selectedIndices = SoftNMS(boxes, scores, 0.5f, 0.3f);// 输出结果  Console.WriteLine("Selected boxes:");foreach (var index in selectedIndices){Console.WriteLine($"Box {index}: {boxes[index]}");}}static List<int> SoftNMS(List<Rect> boxes, float[] scores, float iouThreshold, float scoreThreshold){List<int> selectedIndices = new List<int>();int n = boxes.Count;// 将得分转换为 List  List<float> scoreList = new List<float>(scores);for (int i = 0; i < n; i++){if (scoreList[i] > scoreThreshold){selectedIndices.Add(i);for (int j = i + 1; j < n; j++){float iou = ComputeIoU(boxes[i], boxes[j]);if (iou > iouThreshold){// 根据 IoU 衰减得分  scoreList[j] *= (float)Math.Exp(-(iou * iou) / 0.5);}}}}return selectedIndices;}static float ComputeIoU(Rect boxA, Rect boxB){// 计算交集  int x1 = Math.Max(boxA.X, boxB.X);int y1 = Math.Max(boxA.Y, boxB.Y);int x2 = Math.Min(boxA.X + boxA.Width, boxB.X + boxB.Width);int y2 = Math.Min(boxA.Y + boxA.Height, boxB.Y + boxB.Height);int interWidth = Math.Max(0, x2 - x1);int interHeight = Math.Max(0, y2 - y1);float interArea = interWidth * interHeight;// 计算并集  float boxAArea = boxA.Width * boxA.Height;float boxBArea = boxB.Width * boxB.Height;float unionArea = boxAArea + boxB.Area() - interArea;return interArea / unionArea;}
}

代码解析:

  1. 准备工作:SoftNMS 也会使用 ComputeIoU 计算候选框之间的重叠度。它把得分存储在 scoreList 中,准备开始调整这些得分。
  2. 温柔的调整:对于每个候选框,如果它的得分超过 scoreThreshold,就先把它加入 selectedIndices 列表。然后,检查其他候选框,如果它们和这个候选框重叠度超过 iouThreshold,不会直接淘汰它们,而是根据重叠程度 iou 来降低它们的得分哦,使用 scoreList[j] *= (float)Math.Exp(-(iou * iou) / 0.5) 这个神奇的公式,就像给它们的分数打个折扣,让它们变得不那么突出啦。

四、实战对比:NMS 和 SoftNMS 的 “战斗”

阿强开始测试啦,他准备了一些候选框,让 NMS 和 SoftNMS 分别施展魔法。

当 NMS 上场时,它会非常严格地挑选候选框,一旦发现重叠的,就毫不留情地淘汰。结果呢,留下来的候选框都是最优秀的,但是有些原本也不错的候选框可能就被彻底淘汰啦,就像一场残酷的淘汰赛。

而 SoftNMS 呢,它会让那些重叠的候选框分数降低,这样它们还有机会哦,也许经过一轮调整,有些候选框虽然分数低了点,但还是能留下来呢。这就像是一场温柔的选拔,给每个候选框一个表现的机会,只是分数会根据它们的表现有所调整。

五、实战检验:谁更厉害?

阿强把两种方法都用在自己的图像识别任务上,发现它们各有千秋哦!

  • NMS:优点:处理速度快,能迅速选出最突出的候选框,非常适合那些需要快速得出结果,对准确性要求不是特别高的场景。就像短跑比赛,只选最快的选手,其他选手都被淘汰啦。缺点:可能会过于严格,有些稍微差一点的候选框可能也被误淘汰啦,可能会丢失一些有用的信息哦。
  • SoftNMS:优点:更灵活,能保留更多的信息,不会一下子把有重叠的候选框都淘汰,对于一些复杂的图像,能给出更丰富的结果,就像一场综合考核,给每个选手打分,根据表现调整分数,不会轻易放弃任何一个。缺点:计算量会大一点,因为要计算得分的衰减,就像多了一些额外的考核项目,速度会慢一些。

阿强根据不同的任务,开始灵活使用这两种方法啦。有时候他需要快速筛选,就用 NMS;有时候需要更细致的结果,就用 SoftNMS。

“哈哈,有了这两个神奇的方法,我再也不怕候选框小精灵们捣乱啦!” 阿强高兴地说。

从那以后,阿强在图像处理的世界里更加得心应手,他的图像识别任务变得越来越出色,大家都对他刮目相看呢。而 NMS 和 SoftNMS 这两个魔法,也成了他手中的秘密武器,帮助他在图像处理的战场上屡战屡胜哦 你是不是也觉得它们很神奇呀?快来和阿强一起,用它们解决你的图像处理难题吧

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

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

相关文章

2025届优秀大数据毕业设计

【2025计算机毕业设计】计算机毕业设计100个高通过率选题推荐&#xff0c;毕业生毕设必看选题指导&#xff0c;计算机毕业设计选题讲解&#xff0c;毕业设计选题详细指导_哔哩哔哩_bilibili 985华南理工大学学长 大厂全栈&#xff0c;大数据开发工程师 专注定制化开发

Visual Studio 进行单元测试【入门】

摘要&#xff1a;在软件开发中&#xff0c;单元测试是一种重要的实践&#xff0c;通过验证代码的正确性&#xff0c;帮助开发者提高代码质量。本文将介绍如何在VisualStudio中进行单元测试&#xff0c;包括创建测试项目、编写测试代码、运行测试以及查看结果。 1. 什么是单元测…

最新消息 | 德思特荣获中国创新创业大赛暨广州科技创新创业大赛三等奖!

2024年12月30日&#xff0c;广州市科技局公开第十三届中国创新创业大赛&#xff08;广东广州赛区&#xff09;暨2024年广州科技创新创业大赛决赛成绩及拟获奖企业名单&#xff0c;德思特获得了智能与新能源汽车初创组【第六名】【三等奖】的好成绩&#xff01; 关于德思特&…

DeepSeek模型架构及优化内容

DeepSeek v1版本 模型结构 DeepSeek LLM基本上遵循LLaMA的设计&#xff1a; 采⽤Pre-Norm结构&#xff0c;并使⽤RMSNorm函数. 利⽤SwiGLU作为Feed-Forward Network&#xff08;FFN&#xff09;的激活函数&#xff0c;中间层维度为8/3. 去除绝对位置编码&#xff0c;采⽤了…

内网ip网段记录

1.介绍 常见的内网IP段有&#xff1a; A类&#xff1a; 10.0.0.0/8 大型企业内部网络&#xff08;如 AWS、阿里云&#xff09; 10.0.0.0 - 10.255.255.255 B类&#xff1a;172.16.0.0/12 中型企业、学校 172.16.0.0 - 172.31.255.255 C类&#xff1a;192.168.0.0/16 家庭…

【图片合并转换PDF】如何将每个文件夹下的图片转化成PDF并合并成一个文件?下面基于C++的方式教你实现

医院在为患者进行诊断和治疗过程中&#xff0c;会产生大量的医学影像图片&#xff0c;如 X 光片、CT 扫描图、MRI 图像等。这些图片通常会按照检查时间或者检查项目存放在不同的文件夹中。为了方便医生查阅和患者病历的长期保存&#xff0c;需要将每个患者文件夹下的图片合并成…

香港中文大学 Adobe 推出 MotionCanvas:开启用户掌控的电影级图像视频创意之旅。

简介&#xff1a; 亮点直击 将电影镜头设计引入图像到视频的合成过程中。 推出了MotionCanvas&#xff0c;这是一种简化的视频合成系统&#xff0c;用于电影镜头设计&#xff0c;提供整体运动控制&#xff0c;以场景感知的方式联合操控相机和对象的运动。 设计了专门的运动条…

129,【2】buuctf [BJDCTF2020]EzPHP

进入靶场 查看源代码 看到红框就知道对了 她下面那句话是编码后的&#xff0c;解码 1nD3x.php <?php // 高亮显示当前 PHP 文件的源代码&#xff0c;通常用于调试和展示代码结构 highlight_file(__FILE__); // 设置错误报告级别为 0&#xff0c;即不显示任何 PHP 错误信息…

MapReduce到底是个啥?

在聊 MapReduce 之前不妨先看个例子&#xff1a;假设某短视频平台日活用户大约在7000万左右&#xff0c;若平均每一个用户产生3条行为日志&#xff1a;点赞、转发、收藏&#xff1b;这样就是两亿条行为日志&#xff0c;再假设每条日志大小为100个字节&#xff0c;那么一天就会产…

LeetCode --- 435周赛

题目列表 3442. 奇偶频次间的最大差值 I 3443. K 次修改后的最大曼哈顿距离 3444. 使数组包含目标值倍数的最少增量 3445. 奇偶频次间的最大差值 II 一、奇偶频次间的最大差值I 统计字母出现次数&#xff0c;然后分别统计出现偶数次的最小值和出现奇数次的最大值&#xff0c;…

chrome-mojo C++ Bindings API

概述 Mojo C 绑定 API 利用C 系统 API提供一组更自然的原语&#xff0c;用于通过 Mojo 消息管道进行通信。结合从Mojom IDL 和绑定生成器生成的代码&#xff0c;用户可以轻松地跨任意进程内和进程间边界连接接口客户端和实现。 本文档通过示例代码片段提供了绑定 API 用法的详…

目标检测数据集合集(持续更新中)

第1期 高压输电线塔鸟巢数据集 第2期 特种工程车辆检测数据集 第3期 金桔目标检测数据集 第4期 金属锈蚀识别检测数据集 第5期 苦瓜目标检测数据集 第6期 石榴目标检测数据集YOLO格式 第7期 光伏电池板缺陷检测数据集YOLO格式 第8期 铁路轨道异物入侵检测数据集YOLO格式…

活动预告 | 为 AI 新纪元做好准备:助力安全的业务转型

课程介绍 随着现代办公模式的不断演变和 AI 技术的迅速发展&#xff0c;企业在享受效率提升的同时&#xff0c;也面临着信息安全与数据保护的严峻挑战。在利用 AI 技术释放业务潜力的同时&#xff0c;如何确保数据质量与安全已成为企业发展的关键议题。 在本次线上课程中&…

语义分割文献阅读——SETR:使用Transformer从序列到序列的角度重新思考语义分割

目录 摘要 Abstract 1 引言 2 Vision Transformer(ViT) 2.1 图片预处理&#xff1a;分块和降维 2.2 Patch Embedding 2.3 位置编码 2.4 Transformer Encoder的前向过程 3 SETR 3.1 图像序列化处理 3.2 Transformer 3.3 解码器 总结 摘要 本周阅读的论文题目是《R…

深度学习入门--python入门1

以前学的python全部还给老师了&#xff0c;所以现在重新开始学习了。目标是每天至少学习一点点吧。 目录 1.1 python是什么 1.2 python安装 1.3 python解释器 1.3.1 算术计算 1.3.2 数据类型 1.3.3 变量 1.3.4 列表&#xff08;数组&#xff09; 1.3.5 字典 1.3.6 布…

【2024最新Java面试宝典】—— SpringBoot面试题(44道含答案)_java spingboot 面试题

37. 如何重新加载 Spring Boot 上的更改&#xff0c;而无需重新启动服务器&#xff1f;Spring Boot项目如何热部署&#xff1f;38. SpringBoot微服务中如何实现 session 共享 ?39. 您使用了哪些 starter maven 依赖项&#xff1f;40. Spring Boot 中的 starter 到底是什么 ?4…

【动态规划】风扫枯杨,满地堆黄叶 - 9. 完全背包问题

本篇博客给大家带来的是完全背包问题之动态规划解法技巧. &#x1f40e;文章专栏: 动态规划 &#x1f680;若有问题 评论区见 ❤ 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 . 王子,公主请阅&#x1f680; 要开心要快乐顺…

python-leetcode-单词搜索

79. 单词搜索 - 力扣&#xff08;LeetCode&#xff09; class Solution:def exist(self, board: List[List[str]], word: str) -> bool:if not board or not board[0]:return Falserows, cols len(board), len(board[0])def backtrack(r, c, index):if index len(word):re…

游戏引擎学习第98天

仓库:https://gitee.com/mrxiao_com/2d_game_2 开始进行一点回顾 今天的目标是继续实现正常贴图的操作&#xff0c;尽管目前我们还没有足够的光照信息来使其完全有用。昨日完成了正常贴图相关的基础工作&#xff0c;接下来将集中精力实现正常贴图的基本操作&#xff0c;并准备…

PH热榜 | 2025-02-10

1. 2pr 标语&#xff1a;人工智能帮你把想法变成LinkedIn爆款 或者更口语化一点&#xff1a; AI帮你把点子变成LinkedIn上的热门帖子 介绍&#xff1a;用AI主持的访谈&#xff0c;把你的想法变成LinkedIn爆款帖子。录制你的想法&#xff0c;让AI帮你创作个性化、引人入胜的…