目標檢測之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)

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