非极大值抑制(NMS,Non-Maximum Suppression)的原理与代码详解

非极大值抑制(Non-maximum suppression,NMS)是一种去除非极大值的算法,常用于计算机视觉中的边缘检测、物体识别等。

算法流程:

给出一张图片和上面许多物体检测的候选框(即每个框可能都代表某种物体),但是这些框很可能有互相重叠的部分,我们要做的就是只保留最优的框。假设有N个框,每个框被分类器计算得到的分数为Si, 1<=i<=N。

0、建造一个存放待处理候选框的集合H,初始化为包含全部N个框;

     建造一个存放最优框的集合M,初始化为空集。

1、将所有集合 H 中的框进行排序,选出分数最高的框 m,从集合 H 移到集合 M;

2、遍历集合 H 中的框,分别与框 m 计算交并比(Interection-over-union,IoU),如果高于某个阈值(一般为0~0.5),则认为此框与 m 重叠,将此框从集合 H 中去除。

3、回到第1步进行迭代,直到集合 H 为空。集合 M 中的框为我们所需。

需要优化的参数:

IoU 的阈值是一个可优化的参数,一般范围为0~0.5,可以使用交叉验证来选择最优的参数。

示例:

比如人脸识别的一个例子:

已经识别出了 5 个候选框,但是我们只需要最后保留两个人脸。

首先选出分数最大的框(0.98),然后遍历剩余框,计算 IoU,会发现露丝脸上的两个绿框都和 0.98 的框重叠率很大,都要去除。

然后只剩下杰克脸上两个框,选出最大框(0.81),然后遍历剩余框(只剩下0.67这一个了),发现0.67这个框与 0.81 的 IoU 也很大,去除。

至此所有框处理完毕,算法结果:

1、NMS的原理

NMS(Non-Maximum Suppression)算法本质是搜索局部极大值,抑制非极大值元素。NMS就是需要根据score矩阵和region的坐标信息,从中找到置信度比较高的bounding box。NMS是大部分深度学习目标检测网络所需要的,大致算法流程为:

1.对所有预测框的置信度降序排序

2.选出置信度最高的预测框,确认其为正确预测,并计算他与其他预测框的IOU

3.根据2中计算的IOU去除重叠度高的,IOU>threshold就删除

4.剩下的预测框返回第1步,直到没有剩下的为止

需要注意的是:Non-Maximum Suppression一次处理一个类别,如果有N个类别,Non-Maximum Suppression就需要执行N次。

2、NMS的实现代码详解(来自Fast-RCNN)

# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------

import numpy as np

def py_cpu_nms(dets, thresh):
    """Pure Python NMS baseline."""
    x1 = dets[:, 0]
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]
    scores = dets[:, 4]

    areas = (x2 - x1 + 1) * (y2 - y1 + 1)
    order = scores.argsort()[::-1]  #[::-1]表示降序排序,输出为其对应序号

    keep = []                     #需要保留的bounding box
    while order.size > 0:
        i = order[0]              #取置信度最大的(即第一个)框
        keep.append(i)            #将其作为保留的框
        
        #以下计算置信度最大的框(order[0])与其它所有的框(order[1:],即第二到最后一个)框的IOU,以下都是以向量形式表示和计算
        xx1 = np.maximum(x1[i], x1[order[1:]]) #计算xmin的max,即overlap的xmin
        yy1 = np.maximum(y1[i], y1[order[1:]]) #计算ymin的max,即overlap的ymin
        xx2 = np.minimum(x2[i], x2[order[1:]]) #计算xmax的min,即overlap的xmax
        yy2 = np.minimum(y2[i], y2[order[1:]]) #计算ymax的min,即overlap的ymax

        w = np.maximum(0.0, xx2 - xx1 + 1)      #计算overlap的width
        h = np.maximum(0.0, yy2 - yy1 + 1)      #计算overlap的hight
        inter = w * h                           #计算overlap的面积
        ovr = inter / (areas[i] + areas[order[1:]] - inter) #计算并,-inter是因为交集部分加了两次。

        inds = np.where(ovr <= thresh)[0]          #本轮,order仅保留IOU不大于阈值的下标
        order = order[inds + 1]                    #删除IOU大于阈值的框

    return keep

 参考链接:

https://blog.csdn.net/shuzfan/article/details/52711706

https://www.cnblogs.com/houjun/p/10454117.html

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值