目标检测之NMS算法

非极大值抑制(Non-Maximum Suppression,NMS),即抑制不是极大值的元素,可以理解为局部最大搜索。

目标检测的piplinne:

NMS在post-processing中起到了筛选最大IOU相似度的类别anchor的作用。

soft-NNMS:在NMS中存在的一个问题:高度重叠的同类目标会被滤除,因此需要对IOU的计算结果做非线性变换,保留IOU较低的值而不是直接滤除,即打分根据f(IOU)来确定。

常用的soft-NMS函数:s_i = s_i \exp(-\dfrac{iou(M,b_i)^2}{\delta})

NMS和soft-NMS的对比:

基于python的nms简单实现:

import numpy as np
boxes = np.array([[100, 100, 210, 210, 0.72],
                  [250, 250, 420, 420, 0.8],
                  [220, 220, 320, 320, 0.92],
                  [230, 240, 325, 330, 0.81],
                  [220, 230, 315, 340, 0.91],
                 ])
def nms(dets, thresh):
    #get left head and right bootlom parameters
    x1 = dets[:, 0]
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]
    
    #calculate area, scores, and keep
    areas = (y2 - y1 + 1) * (x2 - x1 + 1)
    scores = dets[:, 4]
    keep = []
    
    #sort box by score form highest to lowest
    index = scores.argsort()[::-1]
    
    while index.size > 0:
        i = index[0]
        keep.append(i)
        
        #get the overlaps parameters
        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
        
        #claculate IoU
        ious = overlaps / (areas[i] + areas[index[1:]] - overlaps)
        #get the available index
        idx = np.where(ious <= thresh)[0]
        index = index[idx + 1]
        
    return keep

import matplotlib.pyplot as plt
%matplotlib inline
def plot_bbox(dets, c='k', t='after nms'):
    x1 = dets[:, 0]
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]
    
    plt.plot([x1, x2], [y1, y1], c)
    plt.plot([x1, x1], [y1, y2], c)
    plt.plot([x1, x2], [y2, y2], c)
    plt.plot([x2, x2], [y1, y2], c)
    plt.title(t)
plot_bbox(boxes, 'b', 'before nms')
keep = nms(boxes, thresh=0.4)
plot_bbox(boxes[keep], 'r--', 'after nms')

 基于python的soft-NMS简单实现:

import numpy as np
boxes = np.array([[100, 100, 210, 210, 0.72],
                  [250, 250, 420, 420, 0.8],
                  [220, 220, 320, 320, 0.92],
                  [230, 240, 325, 330, 0.81],
                  [220, 230, 315, 340, 0.91],
                 ])
def softnms(dets, thresh, sigma = 0.5):
    #get left head and right bootlom parameters
    x1 = dets[:, 0]
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]
    
    #calculate area, scores, and keep
    areas = (y2 - y1 + 1) * (x2 - x1 + 1)
    scores = dets[:, 4]
    keep = []
    
    #sort box by score form highest to lowest
    index = scores.argsort()[::-1]
    
    while index.size > 0:
        i = index[0]
        keep.append(i)
        
        #get the overlaps parameters
        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
        
        #claculate IoU
        ious = overlaps / (areas[i] + areas[index[1:]] - overlaps)
        weight = np.exp(-(ious * ious)/sigma)
        #get the available index
        idx = np.where(weight > thresh)[0]
        index = index[idx + 1]
        
    return keep

import matplotlib.pyplot as plt
%matplotlib inline
def plot_bbox(dets, c='k', t='after nms'):
    x1 = dets[:, 0]
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]
    
    plt.plot([x1, x2], [y1, y1], c)
    plt.plot([x1, x1], [y1, y2], c)
    plt.plot([x1, x2], [y2, y2], c)
    plt.plot([x2, x2], [y1, y2], c)
    plt.title(t)
plot_bbox(boxes, 'b', 'before nms')
keep = softnms(boxes, thresh=0.4)
plot_bbox(boxes[keep], 'r--', 'after softnms')

实验结论:

       蓝色为原始Anchor,红色为NMS/soft-NMS后的检测框,论文中是对anchor的重新打分,此处简化为直接对weight打分,可以看到同一阈值下,soft-NMS能更有效地保留重叠框。

参考博客:非极大值抑制(Non-Maximum Suppression,NMS)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章