nms和softnms的代码

2023-05-16

文章目录

  • 前言
  • 预测框筛选的方法
    • 1.nms
    • 2.softnms
  • 总结

前言

nms和softnms的原理及相关简单代码总结

预测框筛选的方法

预测框的筛选,是检测模块后处理阶段的一个十分重要的过程。因为我们预测输出的预测框,几乎大部分都不是一一对应的(DETR里的是一一对应的),所以一个目标我们可能预测许多框,这些框的分类分数和位置都不同,进行验证和 推理的时候,我们就要使用相应的方法去进行我们预测框的筛选。

1.nms

nms:非极大值抑制。

1> 根据检测框的分类分数(置信度得分)进行降序排序,选取同类分数最高的检测框;
2> 分别计算检测框与相邻检测框的重叠度IOU,对大于阈值Nt的检测框得分直接置零,也就是舍去,并标记将检测框保留下来;
3> 重复这个过程,找到所有被保留下来的检测框;
在这里插入图片描述
把iou值大于所给的阈值的框给置为0筛选掉
这里提供cpu版本的简单的nms实现,现在pytorch里提供的都是使用GPU的nms算子,速度要快的多

import numpy as np
import matplotlib.pyplot as plt

def nms_cpu(dets,iou_thres):
    # 计算交集和并集,准备计算IOU
    x1 = dets[:,0]   # 二维的变成一维的了
    y1 = dets[:,1]
    x2 = dets[:,2]
    y2 = dets[:,3]
    scores = dets[:,4] 

    areas = (x2-x1+1)*(y2-y1+1)  # +1 是为了避免一些小数计算
    # print(areas) 
    keep = [] # 定义一个列表,用来存放NMS后剩余的方框  
    index = scores.argsort()[::-1] # 取出分数从大到小排列的索引    
    # index
    while index.size>0:
        # 取出第一个方框和其他方框进行比对,看又没有
        i = index[0]
        keep.append(i) # keep先保留的是索引值,不是具体的分数
        
        # IOU计算
        x_l = np.maximum(x1[i],x1[index[1:]])   # 会减少一个框坐标
        y_l = np.maximum(y1[i], y1[index[1:]])  # 当index只有一个值的时候,order[1]会报错说index out of range,而index[1:]会是[],不报错
        x_r = np.minimum(x2[i],x2[index[1:]])
        y_r = np.maximum(y2[i], y2[index[1:]])
        # 注意,如果两个方框相交,计算为正,不相交计算为负,负的设置为0
        h = np.maximum(0,y_r-y_l+1)
        w = np.maximum(0,x_r-x_l+1)       
        # 计算交集
        intersection = h*w
        union = areas[i]+areas[index[1:]]-intersection
        ious = intersection/union+1e-8   # 1e-8考虑分母可能为0的情况     
        # 使用iou阈值,把iou值大于所给的阈值的框给筛选掉
        idx = np.where(ious<=iou_thres)[0]  # 只有条件 (condition),没有x和y,则输出满足条件 (即非0) 元素的坐标,
        # 把留下的框再次进行NMS操作     # 坐标以tuple的形式给出,通常原数组有多少维,输出的tuple中就包含几个数组,分别对应符合条件元素的各维坐标。
        index = index[idx + 1]
    return keep

画图,可视化下看看:
参考:https://blog.csdn.net/EMIvv/article/details/122484524

# 画图展示过程
def draw_boxes(boxes,color):
    x1 = boxes[:,0]   # 二维的变成一维的了
    y1 = boxes[:,1]
    x2 = boxes[:,2]
    y2 = boxes[:,3]
    s = boxes[:,4]
    print(s)
    plt.plot([x1,x1],[y1,y2],color)
    plt.plot([x1,x2],[y1,y1],color)
    plt.plot([x1,x2],[y2,y2],color)
    plt.plot([x2,x2],[y1,y2],color)
    for i in range(len(s)):
        plt.text(float(x1[i]), float(y2[i]), str(round(s[i],3)),ha='center', fontdict=None,bbox=dict(facecolor='red', alpha=0.5))

boxes = np.array([[100, 100, 210, 210, 0.72],
                  [250, 250, 420, 420, 0.8],
                  [220, 220, 320, 330, 0.92],
                  [200, 210, 300, 300, 0.81],
                  [220, 230, 315, 340, 0.9]])

keep = nms_cpu(boxes,0.6)
plt.figure()
ax1 = plt.subplot(121)
ax2 = plt.subplot(122)
plt.sca(ax1)
draw_boxes(boxes,'b')
plt.sca(ax2)
draw_boxes(boxes[keep],'r')
plt.show()

在这里插入图片描述

2.softnms

softnms:是对nms的重叠框处理的方法的改进,认为直接舍去可能不太好,有可能存在同一类的两个目标靠的比较近的情况。所以提出用温和的手段去处理重叠的框,给重叠的框乘以一个与Iou值有关的因子,来控制iou大的分类分数。与nms不同的是,最后是根据所给的分数阈值取框,而不是iou阈值。

1> 根据检测框的置信度得分进行降序排序,选取分数最高的检测框A,
2> 分别计算检测框与相邻检测框的重叠度IOU,对大于阈值的检测框设置一个惩罚函数,降低这些检测框的置信度得分
3> 重复这个过程,找到所有被保留下来的检测框

  • 1.线性因子,大于阈值的部分乘以(1-iou):这样重叠度高的,si会变小,比如最大的分类分数为0.9,iou=0.7大于阈值的一个框si=0.6,这样0.6*(1-0.7)=0.18,这样一下降低了分数,后续要根据重新计算的分数阈值筛选。
    在这里插入图片描述
  • 2.高斯置信度降低策略,所有原来的分数乘以一个与iou有关的高斯变量。因为高斯变量符合均值为0,所以这样没有重叠的分类分数还是si,重叠的iou值越大,相乘后分数越低。但是没线性一下降低这么多,相对来说更加平缓。
    在这里插入图片描述
def softnms_cpu(dets,iou_thres,score_thres,sigma=0.5,method=1):
    # 计算交集和并集,准备计算IOU
    x1 = dets[:,0]   # 二维的变成一维的了
    y1 = dets[:,1]
    x2 = dets[:,2]
    y2 = dets[:,3]
    scores = dets[:,4] # 没有新开辟
    areas = (x2-x1+1)*(y2-y1+1)  # +1 是为了避免一些小数计算
    # print(areas) 
    keep = [] # 定义一个列表,用来存放NMS后剩余的方框  
    index = scores.argsort()[::-1] # 取出分数从大到小排列的索引 
    # index
    while index.size>0:
        # 取出第一个方框和其他方框进行比对,看又没有
        i = index[0]
        keep.append(i) # keep先保留的是索引值,不是具体的分数
        
        # IOU计算
        x_l = np.maximum(x1[i],x1[index[1:]])   # 会减少一个框坐标
        y_l = np.maximum(y1[i], y1[index[1:]])  # 当order只有一个值的时候,order[1]会报错说index out of range,而order[1:]会是[],不报错
        x_r = np.minimum(x2[i],x2[index[1:]])
        y_r = np.maximum(y2[i], y2[index[1:]])
        # 注意,如果两个方框相交,计算为正,不相交计算为负,负的设置为0
        h = np.maximum(0,y_r-y_l+1)
        w = np.maximum(0,x_r-x_l+1)
        
        # 计算交集
        intersection = h*w
        union = areas[i]+areas[index[1:]]-intersection
        ious = intersection/union+1e-8   # 1e-8考虑分母可能为0的情况
        
        # 不同的地方
        if method==0:  # 线性惩罚
            weights = np.ones(ious.shape)
            weights[ious>=iou_thres] = weights[ious>=iou_thres]-ious[ious>=iou_thres] 
        elif method==1:
            weights = np.exp(-ious*ious/sigma)
            
        # 更新分数
        scores[index[1:]] *= weights
        # 更新索引
        update_index = scores[index[1:]].argsort()[::-1]+ 1 # 因为是在index里排序,所以后面再取索引时,到原来的index里取就行了
        print(update_index)
        index = index[update_index]   # 取索引时,到原来的index里取
        # 这里不同的是用置信度分数作为筛选的依据了
        keep_idx = np.where(scores[index]>score_thres)[0]
        index = index[keep_idx]
    return keep

画图:

def draw_boxes(boxes,color):
    x1 = boxes[:,0]   # 二维的变成一维的了
    y1 = boxes[:,1]
    x2 = boxes[:,2]
    y2 = boxes[:,3]
    s = boxes[:,4]
    print(s)
    plt.plot([x1,x1],[y1,y2],color)
    plt.plot([x1,x2],[y1,y1],color)
    plt.plot([x1,x2],[y2,y2],color)
    plt.plot([x2,x2],[y1,y2],color)
    for i in range(len(s)):
        plt.text(float(x1[i]), float(y2[i]), str(round(s[i],3)),ha='center', fontdict=None,bbox=dict(facecolor='red', alpha=0.5))

# !!! 这样输入boxes会在函数里改变里面scores的值,返回后一样改变了值,列表是可变的
#keep_sf = softnms_cpu(boxes,iou_thres=0.5,score_thres=0.3,sigma=0.5,method=1)
box1 = boxes.copy()
keep_sf = softnms_cpu(box1,iou_thres=0.5,score_thres=0.1,sigma=0.5,method=1)
# 画图
plt.figure()
ax1 = plt.subplot(121)
ax2 = plt.subplot(122)
plt.sca(ax1)
draw_boxes(box1,'b')   # box1->boxes...box1:表示经过softnms后的
plt.sca(ax2)
draw_boxes(box1[keep_sf],'r')
plt.show()

高斯方法的图
在这里插入图片描述
实际上是返回索引,然后在原来的boxes里取相应的框和分数,这里是为了看看softnms后的分数变化。实际上还是下图:只有目标比较密集的时候效果才比较明显,常用的是高斯方法的softnms。而且由上面的图可知用softnms时,分数阈值可以设置的小点
在这里插入图片描述
线性方法的图
在这里插入图片描述

总结

softnms相对于nms的改进,其实就是一种对原来部分加权进行一种软处理的一种方法,这种方法的思想其实在很多论文里的创新点都有看到过类似的身影。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

nms和softnms的代码 的相关文章

  • NMS

    NMS 非极大值抑制 def NMS dects threshold dects x1 y1 x2 y2 score x1 61 dects 0 y1 61 dects 1 x2 61 dects 2 y2 61 dects 3 score
  • 深度学习_NMS代码详解YOLOv3及Fast R-CNN例子

    先放Fast R CNN的NMS代码 这部分是关于 nms 实现的代码 后续再加下其他的版本 流程 xff1a 首先对检测结果的 score 取出最大的元素 xff0c 然后将置信度最高的框与其他框取交集 xff0c 计算 iou xff0
  • 深度剖析问题:Could not run ‘torchvision::nms‘ with arguments from the ‘CUDA‘ backend.

    问题 xff1a 使用YOLOv5进行测试的时候 xff0c 报错 xff1a Could not run 39 torchvision nms 39 with arguments from the 39 CUDA 39 backend x
  • ssd.pytorch源码分析(三)— 非极大值抑制NMS

    NMS源码 SSD论文链接 NMS介绍 吴恩达对于NMS xff08 非极大值抑制 xff09 的介绍 xff1a 说白了 xff0c NMS的作用就是去掉目标检测任务重复的检测框 例如 xff0c 一个目标有多个选择框 xff0c 现在要
  • pytorch框架下faster rcnn使用softnms

    pytorch faster rcnn softnms frcnn使用softnms方法一 xff1a pytorch复现版本的cpu版softnms xff08 本方法可以跑通 xff09 0 首先overview一波 xff1a inf
  • NMS和softnms代码

    NMS的python代码 import numpy as np def py cpu nms dets thresh 34 34 34 Pure Python NMS baseline 34 34 34 x1 61 dets 0 y1 61
  • 在faster rcnn中使用soft nms,faster rcnn的改进(一)

    1 背景介绍 我的项目是利用faster rcnn检测kiiti数据集 xff0c 用原始nms xff0c iters 61 10000的情况下 xff0c 得到的mAP 61 0 586 在改用soft nms后 xff0c 其他参数均
  • nms和softnms的代码

    文章目录 前言预测框筛选的方法1 nms2 softnms 总结 前言 nms和softnms的原理及相关简单代码总结 预测框筛选的方法 预测框的筛选 xff0c 是检测模块后处理阶段的一个十分重要的过程 因为我们预测输出的预测框 xff0
  • NMS

    NMS 非极大值抑制 def NMS dects threshold dects x1 y1 x2 y2 score x1 61 dects 0 y1 61 dects 1 x2 61 dects 2 y2 61 dects 3 score
  • soft-nms(softnms)(pytorch实现)& softer nms

    softnms和softer nms是nms的两个改进算法 传统nms存在的问题 传统的NMS方法是基于分类分数的 xff0c 只有最高分数的预测框能留下来 xff0c 但是大多数情况下IoU和分类分数不是强相关 xff0c 很多分类标签置
  • NMS详解及pytorch实现:hard-nms(diou\overlap\merge\batched),soft-nms

    文章目录 NMS详解及pytorch实现 hard nms diou overlap merge batched soft nms1 简介2 原理3 实现3 1 伪代码3 2 pytorch源码3 3 知识点 参考资料 NMS详解及pyto
  • yolo论文中IOU/AP/MAP/NMS概念详解

    之前在只看了一遍吴恩达神经网络下写了一篇Darknet yolov2的综述 xff0c 最近接着往下学时发现很多基础的概念不是很懂 xff0c 所以这篇解决一下寸疑问题 1 卷积滑动窗口 滑动窗口大家都了解的 xff0c 从图片的左上角开始
  • nms-python和C

    代码 import numpy as np def nms bboxes iou threshold x1 bboxes 0 y1 bboxes 1 x2 bboxes 2 y2 bboxes 3 score bboxes 4 area x
  • 【使用TensorRT自带的plugin】

    0 背景 在之前的文章TensorRT的plugin实现中介绍了 如何从零实现一个TensorRT的plugin 这篇文章来介绍如何使用TensorRT自带的plugin 将其添加到Network Definition中加速我们的模型 自T
  • 如何监控ActiveMQ Artemis

    我正在 Windows NET 环境中使用 RabbitMQ ActiveMQ Classic 和 ActiveMQ Artemis 进行一些测试 RabbitMQ 和 ActiveMQ 经典 附带一个 Web 界面 您可以在其中查看有关代
  • 如何访问.net中的activemq统计插件

    我正在尝试访问 activemq 统计信息http activemq apache org statisticsplugin html in c 这就是我到目前为止所拥有的 我无法得到消费者的回复 我可以在监控网站上查看队列的计数增加 pu
  • 目标检测中的损失函数:IOU_Loss、GIOU_Loss、DIOU_Loss和CIOU_Loss

    文章目录 前言 1 IOU Loss Intersection over Union Loss 2 GIOU Loss Generalized Intersection over Union Loss 3 DIOU Loss Distanc
  • android 13.0 framework禁用系统所有通知

    1 概述 在13 0的系统rom产品开发中最近公司项目要求 禁用系统所有通知 不需要在下拉状态栏显示通知功能实现 要控制系统通知的开关功能 需要屏蔽系统通知 而系统通知都是由NoticationManagerServices java来管理
  • net-snmp解析代码,如何解析MIB?

    我在学习代码库 解析MIB In parse c and parse h代码保留一个哈希桶 indexed bucket tree list 还有一个树结构 其中包含一个指向的next指针Next node in hashed list o
  • ActiveMQ NMS:当代理关闭时,connection.start() 会因故障转移协议而挂起

    我有使用 nms activemq 1 5 0 的 C 应用程序 当我的应用程序启动时 它尝试使用故障转移协议连接到代理 我有两个主从配置的代理 如果两个经纪人都关闭了 我的应用程序就会因为以下原因而陷入等待状态 connection st

随机推荐

  • 修改Mysql root密码

    最近新装好的mysql在进入mysql工具时 xff0c 总是有错误提示 mysql uroot p Enter password ERROR 1045 28000 Access denied for user 39 root 39 64
  • 示例:PX4——添加msg、uORB

    git clone https github com PX4 Firmware cd Firmware git submodule update init recursive git checkout v1 11 0 beta1 make
  • PX4飞控读取UART串口信息通过Mavlink传给QGC地面站显示

    详细代码地址 xff1a https github com XXXUUUXXX PX4 2 QGC 目的 xff1a 通过UART串口给PX4飞控发送信息 xff0c 通过Mavlink协议在QGC界面上显示出来 显示信息包括 xff1a
  • QGC地面站连接多机飞控PX4

    环境 xff1a QGC4 1飞控1飞控2 首先 xff0c 连接飞控1 xff0c 修改参数MAV SYS ID 61 1 然后 xff0c 断开飞控1 xff0c 连接飞控2 xff0c 修改参数MAV SYS ID 61 2 关闭自动
  • PX4 mavros可以切换的模式

    catkin ws src mavros mavros src lib uas stringify cpp PX4 custom mode gt string static const cmode map px4 cmode map px4
  • Jetson的mavros使用offboard模式,终端按键控制无人机飞行

    基于Promethues根据wiki配置好之后可以实现使用终端控制 xff0c 起飞 xff1b 降落 xff1b 前后左右飞行 xff1b 上升下降左转右转 xff1b 开始我基于仿真测试实机不成功 xff0c 是因为某个运行节点没有打开
  • 安装Mavros——二进制方法

    sudo apt get install ros melodic mavros ros melodic mavros extras wget https raw githubusercontent com mavlink mavros ma
  • 【LADRC】线性自抗扰控制

    目录 LADRC算法 LADRC算法推导二阶线性系统为例 LADRC算法n阶 LADRC离散化 零阶保持法 一阶系统 二阶系统 LADRC参数整定方法 参考文献 LADRC算法 自抗扰控制 xff08 ADRC xff0c Active D
  • 控制笔记(自控+现控)

    目录 主流控制方法优缺点 干扰观测器 水床效应 PID 积分分离 饱和区 积分饱和 微分使用条件 死区 中性区 不作用区 动态性能指标 主流控制方法优缺点 PID 优点 xff1a 实现简单 不依赖模型缺点 xff1a 在系统平衡点附近设计
  • MapReduce系列-eclipse运行MapReduce

    1 eclipse安装hadoop的插件 下载 hadoop eclipse plugin 2 6 0 jar xff0c 将其放入 eclipse 的 plugins 目录 xff0c 并重启 eclipse xff0c 项目视图 xff
  • python爬取淘宝网

    from selenium import webdriver import re from bs4 import BeautifulSoup import time def url open driver content 爬取源代码 ele
  • SUMO仿真数据输出的配置方法

    1 概述 1 1 目的 说明SUMO仿真结束后可以输出的数据及其设置方法 1 2 参考文档 http sumo dlr de wiki Simulation Output 2 SUMO的输出数据概述 SUMO可以输出的数据概述如下表 xff
  • LQR 控制学习-LQR控制 MATLAB官方教程-LQR 控制器_状态空间系统Matlab/Simulink建模分析

    LQR 控制 本blog主要记录LQR 线性二次调制系统的 xff0c 学习教程为两个B站的教学视频 状态空间4 LQR控制 MATLAB官方教程 视频链接 xff1a 原创翻译 状态空间4 LQR控制 MATLAB官方教程 原创翻译 状态
  • 多传感器融合定位 第一章 概述

    多传感器融合定位 第一章 概述 本记录深蓝学院多传感器定位融合第四期学习笔记 xff0c 官方推荐使用docker进行开发 xff0c 为了方便之后移植部署 xff0c 故本次在次在本地环境进行开发 代码下载 xff1a https git
  • 记一次CSDN的资源加载失败的问题的解决方法

    前段时间 xff0c 某天突然发现CSDN加载不了 xff0c 我还以为网站出现故障了 xff0c 但是没想到第二天还是访问不了 xff0c 问了下同事 xff0c 他的好像没有什么问题 xff08 大概长这样 xff09 找到加载失败的u
  • github release 功能的使用及问题解决

    对很多初学者来说 xff0c 要自己架设一个服务器来提供app更新 xff0c 别说是配置服务器了 xff0c 光是买个主机都很棘手 所幸的是github提供了release功能 xff0c 并有相关api支持 下面就来说说如何使用gith
  • Ubuntu 下如何测试 USB 摄像头支持的分辨率、压缩格式,并使用 OpenCV 按正确的格式读取出来?

    介绍 本篇博客介绍了如何使用v4l utils工具来查看所购买的USB摄像头支持的分辨率等信息 xff0c 并使用一个短小的 opencv 脚本将图像读取出来 测试 USB 摄像头支持的分辨率和压缩格式 需要的工具 xff1a apt in
  • 程序上下文切换,什么是上下文?

    1 什么是上下文 xff1f Linux是一个多任务的操作系统 xff0c 它支持远大于CPU数量的任务同时运行 xff0c 当然 xff0c 这些任务实际上并不是真正的在同时运行 xff0c 而是系统在很短的时间内 xff0c 将CPU轮
  • PHP计算今天、昨天、本周、本月、上月开始时间和结束时间

    start 61 date 39 Y m d H i s 39 mktime 0 0 0 date 39 m 39 date 39 d 39 date 39 Y 39 end time 61 date 39 Y m d H i s 39 m
  • nms和softnms的代码

    文章目录 前言预测框筛选的方法1 nms2 softnms 总结 前言 nms和softnms的原理及相关简单代码总结 预测框筛选的方法 预测框的筛选 xff0c 是检测模块后处理阶段的一个十分重要的过程 因为我们预测输出的预测框 xff0