1. 程式人生 > >【目標檢測】NMS(Non-maximum suppression,非極大值抑制)演算法

【目標檢測】NMS(Non-maximum suppression,非極大值抑制)演算法

NMS廣泛應用於目標檢測演算法中。其目的是為了消除多餘的候選框,找到最佳的物體檢測位置。

現在假設有有一個候選的boxes的集合B和其對應的scores集合S:

1. 找出分數最高的M;

2. 將M對應的box從B中刪除;

3. 將刪除的box新增到集合D中;

4. 從B中刪除與M對應的box重疊區域大於閾值Nt的其他框;

5. 重複上述步驟1-4。

虛擬碼如下:

其中si可表述為:

Mask RCNN中的python實現:

def non_max_suppression(boxes, scores, threshold):
    """執行non-maximum suppression並返回保留的boxes的索引.
    boxes: [N, (y1, x1, y2, x2)].注意(y2, x2)可以會超過box的邊界.
    scores: box的分數的一維陣列.
    threshold: Float型. 用於過濾IoU的閾值.
    """
    assert boxes.shape[0] > 0
    if boxes.dtype.kind != "f":
        boxes = boxes.astype(np.float32)

    #計算box面積
    y1 = boxes[:, 0]
    x1 = boxes[:, 1]
    y2 = boxes[:, 2]
    x2 = boxes[:, 3]
    area = (y2 - y1) * (x2 - x1)

    #獲取根據分數排序的boxes的索引(最高的排在對前面)
    ixs = scores.argsort()[::-1]

    pick = []
    while len(ixs) > 0:
        #選擇排在最前的box,並將其索引加到列表中
        i = ixs[0]
        pick.append(i)
        #計算選擇的box與剩下的box的IoU
        iou = compute_iou(boxes[i], boxes[ixs[1:]], area[i], area[ixs[1:]])
        #確定IoU大於閾值的boxes. 這裡返回的是ix[1:]之後的索引,
        #所以為了與ixs保持一致,將結果加1
        remove_ixs = np.where(iou > threshold)[0] + 1
        #將選擇的box和重疊的boxes的索引刪除.
        ixs = np.delete(ixs, remove_ixs)
        ixs = np.delete(ixs, 0)
    return np.array(pick, dtype=np.int32)