博客專欄

EEPW首頁 > 博客 > CVPR2021目標檢測佳作 | Weighted boxes fusion

CVPR2021目標檢測佳作 | Weighted boxes fusion

發(fā)布人:CV研究院 時間:2021-03-21 來源:工程師 發(fā)布文章

目標檢測是計算機視覺系統(tǒng)中的一項關鍵任務,在自動駕駛、醫(yī)學成像、零售、安全、人臉識別、機器人技術等領域都有廣泛的應用。目前,基于神經網絡的模型被用于對特定類目標的實例進行定位和分類。

1、動機&摘要

當不需要實時推理時,模型的整合就有助于獲得更好的結果。在這項工作中,研究者提出了一種新的方法來結合目標檢測模型的預測:加權邊界框融合。新提出的算法利用所有提出的邊界框的置信度分數來構造平均的邊界框。 

2、背景

目標檢測是一種計算機視覺技術,它處理圖像和視頻中特定類別的語義目標的實例。檢測是一系列實際應用的基本任務,包括自主駕駛、醫(yī)學成像、機器人、安全等。該任務將定位與分類相結合。目標檢測模型通常會返回目標的候選位置、類標簽和置信度分數。使用非極大抑制(NMS)方法選擇預測框。首先,它會根據它們的置信度分數對所有的檢測框進行分類。然后,選擇具有最大置信值的檢測框。同時,所有其他有明顯重疊的檢測框都會被過濾掉。它依賴于一個硬編碼的閾值來丟棄冗余的邊界框。最近的一些工作使用了一個可微分的模型來學習NMS,并引入了soft-NMS來提高過濾性能。

3、相關工作

Non-maximum suppression (NMS)

1.jpg

回顧下NMS和Soft-NMS

經典NMS最初第一次應用到目標檢測中是在RCNN算法中,其實現嚴格按照搜索局部極大值,抑制非極大值元素的思想來實現的,具體的實現步驟如下:

設定目標框的置信度閾值,常用的閾值是0.5左右

根據置信度降序排列候選框列表

選取置信度最高的框A添加到輸出列表,并將其從候選框列表中刪除

計算A與候選框列表中的所有框的IoU值,刪除大于閾值的候選框

重復上述過程,直到候選框列表為空,返回輸出列表

2.png

其中IoU(Intersection over Union)為交并比,如上圖所示,IoU相當于兩個區(qū)域交叉的部分除以兩個區(qū)域的并集部分得出的結果。下圖是IoU為各個取值時的情況展示,一般來說,這個score > 0.5 就可以被認為一個不錯的結果了。

3.png

下面,通過一個具體例子來說明經典NMS究竟做了什么。下圖的左圖是包含一個檢測目標(王鬧海)的實例圖片。其中的綠色矩形框代表了經過目標檢測算法后,生成的大量的帶置信度的Bounding box,矩形框左下角的浮點數即代表該Bounding box的置信度。在這里,使用Python對經典NMS算法實現,并應用到該實例中去。當NMS的閾值設為0.2時,最后的效果如下圖中右圖所示。

4.png

def nms(bounding_boxes, Nt):
    if len(bounding_boxes) == 0:
        return [], []
    bboxes = np.array(bounding_boxes)
    # 計算 n 個候選框的面積大小
    x1 = bboxes[:, 0]
    y1 = bboxes[:, 1]
    x2 = bboxes[:, 2]
    y2 = bboxes[:, 3]
    scores = bboxes[:, 4]
    areas = (x2 - x1 + 1) * (y2 - y1 + 1)
    # 對置信度進行排序, 獲取排序后的下標序號, argsort 默認從小到大排序
    order = np.argsort(scores)
    picked_boxes = []  # 返回值
    while order.size > 0:
        # 將當前置信度最大的框加入返回值列表中
        index = order[-1]
        picked_boxes.append(bounding_boxes[index])
        # 獲取當前置信度最大的候選框與其他任意候選框的相交面積
        x11 = np.maximum(x1[index], x1[order[:-1]])
        y11 = np.maximum(y1[index], y1[order[:-1]])
        x22 = np.minimum(x2[index], x2[order[:-1]])
        y22 = np.minimum(y2[index], y2[order[:-1]])
        w = np.maximum(0.0, x22 - x11 + 1)
        h = np.maximum(0.0, y22 - y11 + 1)
        intersection = w * h
        # 利用相交的面積和兩個框自身的面積計算框的交并比, 將交并比大于閾值的框刪除
        ious = intersection / (areas[index] + areas[order[:-1]] - intersection)
        left = np.where(ious < Nt)
        order = order[left]
    return picked_boxes

soft-NMS

經典NMS是為了去除重復的預測框,這種算法在圖片中只有單個物體被檢測的情況下具有很好的效果。然而,經典NMS算法存在著一些問題:對于重疊物體無法很好的檢測。當圖像中存在兩個重疊度很高的物體時,經典NMS會過濾掉其中置信度較低的一個。如下圖所示,經典NMS過濾后的結果如下下圖所示:

5.png

而我們期望的結果是兩個目標都被算法成功檢測出來。

為了解決這類問題,Jan Hosang,等人提出了Soft-NMS算法。Soft-NMS的算法偽代碼如圖5所示。其中紅色框為經典NMS的步驟,而綠色框中的內容為Soft-NMS改進的步驟??梢钥闯?,相對于經典NMS算法,Soft-NMS僅僅修改了一行代碼。當選取了最大置信度的Bounding box之后,計算其余每個Bounding box與Bounding box的I ou值,經典NMS算法的做法是直接刪除Iou大于閾值的Bounding box;而Soft-NMS則是使用一個基于Iou的衰減函數,降低Iou大于閾值Nt的Bounding box的置信度,IoU越大,衰減程度越大。

def soft_nms(bboxes, Nt=0.3, sigma2=0.5, score_thresh=0.3, method=2):
    # 在 bboxes 之后添加對于的下標[0, 1, 2...], 最終 bboxes 的 shape 為 [n, 5], 前四個為坐標, 后一個為下標
    res_bboxes = deepcopy(bboxes)
    N = bboxes.shape[0]  # 總的 box 的數量
    indexes = np.array([np.arange(N)])  # 下標: 0, 1, 2, ..., n-1
    bboxes = np.concatenate((bboxes, indexes.T), axis=1)  # concatenate 之后, bboxes 的操作不會對外部變量產生影響
    # 計算每個 box 的面積
    x1 = bboxes[:, 0]
    y1 = bboxes[:, 1]
    x2 = bboxes[:, 2]
    y2 = bboxes[:, 3]
    scores = bboxes[:, 4]
    areas = (x2 - x1 + 1) * (y2 - y1 + 1)
    for i in range(N):
        # 找出 i 后面的最大 score 及其下標
        pos = i + 1
        if i != N - 1:
            maxscore = np.max(scores[pos:], axis=0)
            maxpos = np.argmax(scores[pos:], axis=0)
        else:
            maxscore = scores[-1]
            maxpos = 0
        # 如果當前 i 的得分小于后面的最大 score, 則與之交換, 確保 i 上的 score 最大
        if scores[i] < maxscore:
            bboxes[[i, maxpos + i + 1]] = bboxes[[maxpos + i + 1, i]]
            scores[[i, maxpos + i + 1]] = scores[[maxpos + i + 1, i]]
            areas[[i, maxpos + i + 1]] = areas[[maxpos + i + 1, i]]
        # IoU calculate
        xx1 = np.maximum(bboxes[i, 0], bboxes[pos:, 0])
        yy1 = np.maximum(bboxes[i, 1], bboxes[pos:, 1])
        xx2 = np.minimum(bboxes[i, 2], bboxes[pos:, 2])
        yy2 = np.minimum(bboxes[i, 3], bboxes[pos:, 3])
        w = np.maximum(0.0, xx2 - xx1 + 1)
        h = np.maximum(0.0, yy2 - yy1 + 1)
        intersection = w * h
        iou = intersection / (areas[i] + areas[pos:] - intersection)
        # Three methods: 1.linear 2.gaussian 3.original NMS
        if method == 1:  # linear
            weight = np.ones(iou.shape)
            weight[iou > Nt] = weight[iou > Nt] - iou[iou > Nt]
        elif method == 2:  # gaussian
            weight = np.exp(-(iou * iou) / sigma2)
        else:  # original NMS
            weight = np.ones(iou.shape)
            weight[iou > Nt] = 0
        scores[pos:] = weight * scores[pos:]
    # select the boxes and keep the corresponding indexes
    inds = bboxes[:, 5][scores > score_thresh]
    keep = inds.astype(int)
    return res_bboxes[keep]

6.png

后期我們詳細給大家說說NMS一系列知識!

4、Weighted Boxes Fusion

在這里,我們描述了新的邊界框融合方法:加權邊界框融合(WBF)。假設,我們已經綁定了來自N個不同模型的相同圖像的框預測?;蛘?,我們對相同圖像的原始和增強版本(即垂直/水平反射,數據增強)有相同模型的N個預測)。WBF工作如下步驟:

7.png8.png

NMS和Soft-NMS都排除了一些框,而WBF則使用了所有框。因此,它可以修復所有模型都預測不準確的情況。本案例如下圖所示。NMS/Soft-NMS將只留下一個不準確的框,而WBF將使用所有預測的框來融合它。

9.png

5、實驗結果

10.png11.png12.png

[46]: ZFTurbo. Coco wbf benchmark. https://github. com/ZFTurbo/Weighted-Boxes-Fusion/tree/master/benchmark, 2020.

13.png14.png

*博客內容為網友個人發(fā)布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。



關鍵詞:

相關推薦

技術專區(qū)

關閉