非极大值抑制算法

非极大值抑制(Non-Maximum Suppression,NMS),顾名思义就是抑制不是极大值的元素,可以理解为局部最大搜索。这个局部代表的是一个邻域,邻域有两个参数可变,一是邻域的维数,二是邻域的大小。常用于目标检测,边缘检测中。

  1. 首先边界点不是极值的搜索范围,所以对于一组长度为n的数来说,搜索范围为2~n –1。
  2. 局部极大值满足,该点的值大于相邻的左右两边的点的值。当确定该点是局部最大值时,即可将迭代参数增加2,继续寻找下一个局部极大值。
  3. 迭代参数从左边开始,若不满足该点的值大于右边的值时,则需要将迭代参数依次增加1,直到满足当前点的值大于右边数的值停止,此时得到局部最优值。然后继续第2步,直到遍历所有数为止。

伪代码具体流程如下:

                                                                   

非极大值抑制在目标检测中的应用

最近一直在看Faster RCNN,以此为例,Faster RCNN中的预测出来的box会有重叠部分,即存在同一物体上存在多个重叠的box的问题,这时候就需要利用NMS算法来消除一些冗余的box,保留效果最好的。

例如在R-CNN中对于20000多个(论文中以典型值1000*600大小图片经vgg16的pool5后输出的feature map 大小为40*60,每一点对应生成9个anchor box)region proposals得到特征向量(4096维)后,除去一些和边界相交的box后大约剩下6000多个box。这么多数量的anchorboxes之间肯定是有很多重叠区域,因此需要使用非极大值抑制法(NMS,non-maximum suppression)将IoU>0.7的区域全部合并,最后就剩下约2000个anchor boxes。

将其输入到SVM中进行打分。除了背景以外VOC数据集共有20类。那么2000*4096维特征矩阵与20个SVM组成的权重矩阵4096*20相乘得到结果为6000*20维矩阵。这个矩阵2000行表示有2000个框。20列为每一个框属于这20个类的score(置信度)。也就是每一类有2000个不同的score。那么每一类有这么多候选框肯定大多冗余。NMS不会影响最终的检测准确率,但是大幅地减少了建议框的数量。经过NMS算法之后,我们用建议区域中的top-N个来检测(即排过序后取N个)

 

具体做法

假设一共有n个框,根据分类器分类概率从大到小排列。第一步,从最大的置信度的box开始,分别判断其余的box的与最大置信度的box的IOU值,大于阈值时则丢弃,小于阈值则保留,同时保留最大置信度的box。第二步经过比较后的在剩余的box内再次选置信度最大的并标记保留,与剩下的box做与第一步的相同的操作,就这样直到找到满足条件所有的保留框。

源码:

# --------------------------------------------------------
# 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)  #所有box的面积
    order = scores.argsort()[::-1]   #按照从大到小的顺序来排列

	
    keep = []      #保留的结果框的集合
    while order.size > 0:
        i = order[0]  
        keep.append(i)
		
		#得到两个矩形框的相交区域
        xx1 = np.maximum(x1[i], x1[order[1:]]) 
        yy1 = np.maximum(y1[i], y1[order[1:]])
        xx2 = np.minimum(x2[i], x2[order[1:]])
        yy2 = np.minimum(y2[i], y2[order[1:]])

        w = np.maximum(0.0, xx2 - xx1 + 1)
        h = np.maximum(0.0, yy2 - yy1 + 1)
        inter = w * h      #相交区域的面积
        ovr = inter / (areas[i] + areas[order[1:]] - inter)  #计算IOU值

        inds = np.where(ovr <= thresh)[0] #保留IOU小于阈值的box
        order = order[inds + 1]  #ovr数组比order数组少一位,所以下标加上1

    return keep  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SuperLee188

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值