NMS(non maximum suppression),中文名非极大值抑制,顾名思义就是抑制不是极大值的元素,可以理解为局部最大搜索。在很多计算机视觉任务中都有广泛应用,如:边缘检测、目标检测等。
人脸检测的一些概念
(1) 绝大部分人脸检测器的核心是分类器,即给定一个尺寸固定图片,分类器判断是或者不是人脸;
(2)将分类器进化为检测器的关键是:在原始图像上从多个尺度产生窗口,并resize到固定尺寸,然后送给分类器做判断。最常用的方法是滑动窗口。
以下图为例,由于滑动窗口,同一个人可能有好几个框(每一个框都带有一个分类器得分)
而我们的目标是一个人只保留一个最优的框:
于是我们就要用到非极大值抑制,来抑制那些冗余的框: 抑制的过程是一个迭代-遍历-消除的过程。
(1)将所有框的得分排序,选中最高分及其对应的框:
(2)遍历其余的框,如果和当前最高分框的重叠面积(IOU)大于一定阈值,我们就将框删除。
(3)从未处理的框中继续选一个得分最高的,重复上述过程。
下面说一下IOU规则。其实就是两个框重叠率。IOU=重叠面积/基准面积
基准面积有三种计算规则,
(1)Union,也就是两个框的并集所圈定的面积。
(2)Min,面积较小的框所圈定的面积。
(3)Max,面积较大的框所圈定的面积。
比如下图中,红框和蓝框有交集,交集面积很大,所以IOU就大,如果红框是擂台主,那么蓝框就被和谐牺牲了。而绿框因为没有交集,IOU都小到没有,侥幸逃过一劫。
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