NMS(non maximum suppression),中文名非极大值抑制,顾名思义就是抑制不是极大值的元素,可以理解为局部最大搜索。在很多计算机视觉任务中都有广泛应用,如:边缘检测、目标检测等。

人脸检测的一些概念

(1) 绝大部分人脸检测器的核心是分类器,即给定一个尺寸固定图片,分类器判断是或者不是人脸;

(2)将分类器进化为检测器的关键是:在原始图像上从多个尺度产生窗口,并resize到固定尺寸,然后送给分类器做判断。最常用的方法是滑动窗口。

以下图为例,由于滑动窗口,同一个人可能有好几个框(每一个框都带有一个分类器得分)

NMS--非极大值抑制

而我们的目标是一个人只保留一个最优的框:

于是我们就要用到非极大值抑制,来抑制那些冗余的框: 抑制的过程是一个迭代-遍历-消除的过程。

(1)将所有框的得分排序,选中最高分及其对应的框:

NMS--非极大值抑制

(2)遍历其余的框,如果和当前最高分框的重叠面积(IOU)大于一定阈值,我们就将框删除。

NMS--非极大值抑制

(3)从未处理的框中继续选一个得分最高的,重复上述过程。

NMS--非极大值抑制

下面说一下IOU规则。其实就是两个框重叠率。IOU=重叠面积/基准面积

基准面积有三种计算规则,

(1)Union,也就是两个框的并集所圈定的面积。

(2)Min,面积较小的框所圈定的面积。

(3)Max,面积较大的框所圈定的面积。

比如下图中,红框和蓝框有交集,交集面积很大,所以IOU就大,如果红框是擂台主,那么蓝框就被和谐牺牲了。而绿框因为没有交集,IOU都小到没有,侥幸逃过一劫。
NMS--非极大值抑制

NMS python实现代码:

def cpu_nums(dets, thresh=0.7):
    x1 = dets[:,0]
    y1 = dets[:,1]
    x2 = dets[:,2]
    y2 = dets[:,3]
    scores = dets[:,4]

    areas = (x2 - x1 + 1)*(y2 - y1 + 1) # 检测框box的面积

    index = scores.argsort()[::-1]  #将每个box的置信度由高到低排序,并返回其在原列表中的索引
    keep = []   # 保留经nms后的box的索引

    while index.size > 0: 

        i = index[0]

        keep.append(i)

        #  求检测框之间的交集的面积
        x11 = np.maximum(x1[i], x1[index[1:]])
        y11 = np.maximum(y1[i], y1[index[1:]])
        x22 = np.minimum(x2[i], x2[index[1:]])
        y22 = np.minimum(y2[i], y2[index[1:]])

        w = np.maximum(0, x22-x11+1)
        h = np.maximum(0, y22-y11+1)
        overlaps = w*h

        ious = overlaps/(areas[i] + areas[index[1:]] - overlaps)   # 检测框的交并比

        idx = np.where(ious < thresh)[0]  # 保留IoU小于阈值的box

        index = index[idx+1]  # idx的长度 比index的长度小1, 所以+1

    return keep

参考文章:

https://blog.csdn.net/fuwenyan/article/details/77556085

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

https://blog.csdn.net/bingbingxie1/article/details/86571112

 

 

相关文章: