1.交并比IoU (intersection over union)
在目标检测的评价体系中,有一个参数IoU,即模型产生的目标窗口与原来标记窗口的交叠率。可以简单理解为:检测结果(detection result)与真实值(Ground Truth)的交集并上它们的并集。公式可以简单记为:
2. 非极大值抑制NMS(Non-maximum suppression)
NMS顾名思义就是抑制不是极大值的元素,可以理解为局部最大搜索。这个局部代表的是一个邻域,邻域有两个参数可变,一是邻域的维数,二是邻域的大小。NMS在计算机视觉中应用广泛,我们以行人检测为例,滑动窗口经提取特征,经分类器分类识别后,每个窗口都会得到一个分数。但是滑动窗口会导致很多窗口与其他窗口存在包含或者大部分交叉的情况。这时就需要用到NMS来选取那些邻域里分数最高(是行人的概率最大),并且抑制那些分数低的窗口。
目地:消除多余的检测框,保留最好的一个
原理:使用极大概率的备选框抑制其他与它位置接近的备选框
输入:一些备选框,每个备选框包含备选框的坐标和属于相应类别的概率(注意:这里所有类共享这些备选框);
一个重叠度的阈值,常见的阈值是0.3~0.5
输出:每个类别的备选框
方法:
对于第一个类别
step 1:先选一个概率极大框加入最终结果(保证至少有一个),然后计算其他框和这个最大框的交并比 IoU,把IoU值大的框剔除掉(我是这样理解的,IoU值越大,越说明两个框的重叠度越高,既然现在选定的框的概率较大,那么剔除的哪些框的概率就相对较小,也就是没有选定的框的识别效果好)
然后在重复step 1(因为一副图片中可能有多个物体属于第一类别),选出剩下的里面概率极大框加入最终结果,然后计算,剔除 ... ... ... 直到某一次剔除后,没有剩下的框了,那么这个类别的框就找全了。
开始第二个类别
....
import numpy as np
def nms(boxes, threshold):
# 得到每一个box的左上和右下的坐标值,以及每一个box的概率值
x1 = boxes[:, 0]
y1 = boxes[:, 1]
x2 = boxes[:, 2]
y2 = boxes[:, 3]
scores = boxes[:, 4]
# 计算每一个box的面积
areas = (x2 - x1 + 1) * (y2 - y1 + 1)
# 对每一个box按照score降序排列
order = scores.argsort()[::-1]
# 最后保留box的集合
keep = []
while order.size > 0:
i = order[0]
keep.append(i) # 保留该类box中概率值最大的一个
# 相交区域的左上和右下的坐标值
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
# 计算IoU值
over = inter / (areas[i] + areas[order[1:]] - inter)
# 保留IoU小于阈值的box
index = np.where(over <= threshold)[0]
# np.where(condition)返回索引
order = order[index + 1]
return keep