NMS原理及代码实现

NMS原理

Non-Maximum-Suppression(非极大值抑制):

当两个box空间位置非常接近,就以score更高的那个作为基准,看IOU即重合度如何,如果与其重合度超过阈值,就抑制score更小的box,因为没有必要输出两个接近的box,只保留score大的就可以了。

应用:在目标检测过程中,(Faster-RCNN / YOLOv2)采用NMS来消除冗余的boxes,最终只留下最好的较少的box。

过程:

1 将各组box按照score降序排列

2 从score最大值开始,置为当前box,保存idex,然后依次遍历后面的box,计算与当前box的IOU值,若大于阈值,则抑制,不会输出

3 完成一轮遍历后,继续选择下一个非抑制的box作为当前box,重复步骤2

4 返回没有被抑制的index即符合条件的box

代码实现(被问过)

def NMS(dects,threshhold):
    """
    detcs:二维数组(n_samples,5)
    5列:x1,y1,x2,y2,score
    threshhold: IOU阈值
    """
    x1=dects[:,0]
    y1=dects[:,1]
    x2=dects[:,2]
    y2=dects[:,3]
    score=dects[:,4]
    ndects=dects.shape[0]#box的数量
    area=(x2-x1+1)*(y2-y1+1)
    order=score.argsort()[::-1] #score从大到小排列的indexs,一维数组
    keep=[] #保存符合条件的index
    suppressed=np.array([0]*ndects) #初始化为0,若大于threshhold,变为1,表示被抑制
    
    for _i in range(ndects):
        i=order[_i]  #从得分最高的开始遍历
        if suppressed[i]==1:
            continue
        keep.append(i) 
        for _j in range(i+1,ndects):
            j=order[_j]
            if suppressed[j]==1: #若已经被抑制,跳过
                continue
            xx1=np.max(x1[i],x1[j])#求两个box的交集面积interface
            yy1=np.max(y1[i],y1j])
            xx2=np.min(x2[i],x2[j])
            yy2=np.min(y2[i],y2[j])
            w=np.max(0,xx2-xx1+1)
            h=np.max(0,yy2-yy1+1)
            interface=w*h
            overlap=interface/(area[i]+area[j]-interface) #计算IOU(交/并)
            
            if overlap>=threshhold:#IOU若大于阈值,则抑制
                suppressed[j]=1
    return keep

猜你喜欢

转载自blog.csdn.net/qq_43243022/article/details/88895057
NMS