1.非极大值抑制意义
在目标检测任务中,通常会在同一个目标位置产生大量候选框,候选框之间会相互重叠,因此需要使用非极大值抑制算法寻找最佳位置的候选框,消除冗余框。
下图为centerface识别人脸结果,产生很多候选框。
2.非极大值抑制算法流程
- 将所有边界框存入边界框列表,并根据每一个边界框的置信度进行排序;
- 新建一个空的最终输出列表,
- 将置信度最高的边界框从原边界框列表中删除,存入最终输出列表;
- 设定一个IOU阈值(0-1之间);
- 计算置信度最高的边界框与边界框列表中其他边界框的IOU,并删除IOU大于设定阈值的边界框。
- 重复3-5步,直至边界框列表为空。
python代码:
def nms(boxes, scores, nms_thresh):
"""
非极大值抑制
:param boxes: 边界框
:param scores: 边界框的置信度
:param nms_thresh: IOU阈值
:return: 非极大值抑制结果
"""
x1 = boxes[:, 0]
y1 = boxes[:, 1]
x2 = boxes[:, 2]
y2 = boxes[:, 3]
areas = (x2 - x1 + 1) * (y2 - y1 + 1)
order = np.argsort(scores)[::-1] # 根据置信度进行排序
num_detections = boxes.shape[0]
suppressed = np.zeros((num_detections,), dtype=np.bool)
keep = []
for _i in range(num_detections):
i = order[_i]
if suppressed[i]:
continue
keep.append(i)
ix1 = x1[i]
iy1 = y1[i]
ix2 = x2[i]
iy2 = y2[i]
iarea = areas[i]
for _j in range(_i + 1, num_detections):
j = order[_j]
if suppressed[j]:
continue
xx1 = max(ix1, x1[j])
yy1 = max(iy1, y1[j])
xx2 = min(ix2, x2[j])
yy2 = min(iy2, y2[j])
w = max(0, xx2 - xx1 + 1)
h = max(0, yy2 - yy1 + 1)
inter = w * h
ovr = inter / (iarea + areas[j] - inter)
if ovr >= nms_thresh:
suppressed[j] = True
return keep
非极大值抑制结果如下图: