1、定义:
非极大值抑制算法NMS广泛应用于目标检测算法,其目的是为了消除多余的候选框,找到最佳的物体检测位置。
2、原理:
使用深度学习模型检测出的目标都有多个框,如下图,针对每一个被检测目标,为了得到效果最好的那一个,需要使用一定的过滤技术把多余的框过滤掉。NMS应运而生。
现,假设有一个候选BOXES的集合B和其对应的SCORES集合S:
1、找出分数最高的那个框M;
2、将M对应的BOX从B中删除;
3、将删除的BOX添加到集合D中;
4、从B中删除与M对应的BOX重叠区域大于阈值Nt的其他框;
5、重复上述步骤1到4。
伪代码如下:
其中Si可表述成:
源代码如下:
1、在FastRCNN中的python实现:
def nms(dets,thresh): x1 = dets[:, 0] y1 = dets[:, 1] x2 = dets[:, 2] y2 = dets[:, 3] scores = dets[:, 4] areas = (x2 - x1 + 1) * (y2 - y1 + 1) 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.,xx2-xx1+1) h=np.maximum(0.,yy2-yy1+1) inter=w*h iou=inter/(areas[i]+areas[order[1:]]-inter) inds=np.where(iou<=thresh)[0] order=order[inds+1] return keep
2、在MaskRCNN中的python实现:
def non_max_suppression(boxes,scores,threshold): ''' 保留boxes的索引 boxes:[N,(y1,x1,y2,x2)],(y2,x2)可能会超过box的边界 scores:box分数的一数组 threshold:Float型,用于过滤IoU的阈值 ''' assert boxes.shape[0]>0 if boxes.dtpye.kind!='f': boxes=boxes.astype(np.float32) #计算box面积 y1=boxes[:,0] x1=boxes[:,1] y2=boxes[:,2] y3=boxes[:,3] area=(y2-y1)*(x2-x1) #获取根据分数排序的boxes的索引(最高的排在对前面) ixs=scores.argsort()[::-] pick=[] while len(ixs)>0: i=ixs[0] pick.append(i) iou=compute_iou(boxes[i],boxes[ixs[1:]],area[i],area[ixs[1:]]) remove_ixs=np.where(iou>threshold)[0]+1 ixs=np.delete(ixs,remove_ixs) ixs=np.delete(ixs,0)
return np.array(pick,dtype=np.int32)