訂閱
糾錯(cuò)
加入自媒體

目標(biāo)檢測(cè)中的非最大值抑制算法

計(jì)算機(jī)視覺人工智能的一個(gè)重要領(lǐng)域,它可以識(shí)別和理解圖像和場(chǎng)景。

它包括圖像識(shí)別、目標(biāo)檢測(cè)、圖像分割、圖像生成、圖像超分辨率等多個(gè)子領(lǐng)域。由于大量的實(shí)際用例,目標(biāo)檢測(cè)可能應(yīng)用地最廣。

目標(biāo)檢測(cè)

目標(biāo)檢測(cè)是指計(jì)算機(jī)系統(tǒng)定位圖像中的目標(biāo)并識(shí)別每個(gè)目標(biāo)的能力。目標(biāo)檢測(cè)已廣泛應(yīng)用于人臉檢測(cè)、車輛檢測(cè)、行人計(jì)數(shù)、安全系統(tǒng)和自動(dòng)駕駛汽車。

目標(biāo)檢測(cè)模型從端到端學(xué)習(xí)范式的發(fā)展中受益匪淺:建議、特征和分類器成為一個(gè)神經(jīng)網(wǎng)絡(luò),使一般目標(biāo)檢測(cè)的結(jié)果提高了兩倍[1]通常,所有現(xiàn)代目標(biāo)檢測(cè)模型都遵循三個(gè)步驟:

1. 建議窗口的搜索空間(通過滑動(dòng)窗口或使用建議的稀疏窗口)。

2. 使用分類器/回歸器對(duì)窗口評(píng)分。

3. 組合可能屬于同一對(duì)象的窗口。

最后一步稱為“非最大抑制”

邊界框

在目標(biāo)檢測(cè)中,我們通常使用邊界框來描述目標(biāo)在圖像中的空間位置。

邊界框是一個(gè)矩形,使用左上角和右下角坐標(biāo)繪制。另一種常用的邊界框表示法包含矩形的中心以及矩形的高度和寬度。

非最大值算法(NMS)

可以使用以下步驟解釋該算法:

輸入:邊界框列表以及類名稱和檢測(cè)到的每個(gè)對(duì)象的輸出概率。

1. 刪除輸出概率得分小于指定閾值的邊界框。

2. 按輸出概率的降序排列剩余邊界框的列表。

3. 遍歷已排序的邊界框列表,直到至少剩下一個(gè)元素。

4. 從列表中刪除第一個(gè)邊界框,并將其標(biāo)記為“當(dāng)前元素”。此外,檢查交并比(IOU)。如果IOU高于指定的閾值,則從列表中刪除該元素,并將當(dāng)前元素附加到“最終列表”中

5. 重復(fù)步驟3和4。

6. 返回“最終列表”

NMS算法試運(yùn)行

假設(shè)下面的圖像(圖1)包含兩條狗(左一條:Maya,右一條:Zoro),我們有一個(gè)對(duì)象檢測(cè)模型,可以區(qū)分圖像中的Maya和Zoro。

在使用上圖對(duì)我們的目標(biāo)檢測(cè)模型(無NMS)進(jìn)行推斷時(shí),我們將得到如圖2所示的輸出。在這里,我們可以看到,我們?cè)趩蝹(gè)對(duì)象上得到了多個(gè)具有各自概率分?jǐn)?shù)的邊界框。

我們的目標(biāo)是為對(duì)象選擇最合適的邊界框。換句話說,我們必須從概率為0.94、0.68和0.47的三個(gè)框中選擇一個(gè)Maya邊界框。同樣,我們也必須從概率為0.9和0.58的兩個(gè)邊界框中找到Zoro的最佳邊界框。

根據(jù)算法,我們將首先丟棄所有概率分?jǐn)?shù)低于指定閾值的邊界框。例如,如果我們將閾值設(shè)置為0.5,我們將丟棄Maya概率為0.47的邊界框。

此外,我們將找到概率得分最高的邊界框,并將其IOU與同類的所有其他邊界框進(jìn)行檢查。如果IOU高于閾值(表示相同的對(duì)象),則丟棄概率分?jǐn)?shù)較低的邊界框。

同樣,我們將對(duì)圖像中所有檢測(cè)到的對(duì)象執(zhí)行以下步驟。最終輸出如圖3所示。

代碼

首先,我們將初始化概率置信閾值和IOU閾值。例如,如果一個(gè)邊界框的概率低于概率置信閾值,那么我們將丟棄該邊界框。同樣,如果IOU分?jǐn)?shù)高于定義的閾值,我們不會(huì)考慮輸出概率低的邊界框。

import cv2
     class NMS:
            def __init__(self) -> None:
            self.conf = 0.5
            self.iou_threshsold = 0.4

下面截取的代碼中的IOU函數(shù)計(jì)算兩個(gè)區(qū)域的IOU。IOU是兩個(gè)區(qū)域的相交面積與兩個(gè)區(qū)域的并集的比率。在IOU函數(shù)中,bboxes1和bboxes2是一個(gè)包含以下四個(gè)元素的列表:

[ X(top-left), Y(top-left), X(bottom-right), Y(bottom-right) ]

def IOU(self, bboxes1, bboxes2):
           bboxes1 = [int(i) for i in bboxes1]
           bboxes2= [int(i) for i in bboxes2]
 
           xA = max(bboxes1[0], bboxes2[0])
           yA = max(bboxes1[1], bboxes2[1])
           xB = min(bboxes1[2], bboxes2[2])
           yB = min(bboxes1[3], bboxes2[3])
           intersection_area = max(0, xB - xA + 1) * max(0, yB - yA + 1)
           box1_area = (bboxes1[2] - bboxes1[0] + 1) * (bboxes1[3] - bboxes1[1] + 1)
           box2_area = (bboxes2[2] - bboxes2[0] + 1) * (bboxes2[3] - bboxes2[1] + 1)
 
           iou = intersection_area / float(box1_area + box2_area - intersection_area)
   
           return iou

下面的代碼在圖像上繪制邊界框,并將概率分?jǐn)?shù)放在框的頂部。參數(shù)“images”是圖像對(duì)象,“bboxes_list”包含檢測(cè)到的對(duì)象的坐標(biāo)、類和概率輸出。

bboxes_list = [class, X(top-left), Y(top-left), X(bottom-right), Y(bottom-right), output_probability]
     Sample values:
     0 187 90 586 607 0.94
     0 120 116 600 370 0.68
     1 511 185 961 418 0.58
     0 340 145 568 478 0.47
     1 524 70 920 565 0.92

def draw_overlay(self, image, bboxes_list):
            overlay_color = {
                '0' : (0, 255, 0),
                '1' : (255, 0, 0)
            }
            overlay_thickness = 3
            font = cv2.FONT_HERSHEY_SIMPLEX
            for coord in bboxes_list:
                 class_name = coord[0]
                 start_point = (int(coord[1]), int(coord[2]))
                 end_point = (int(coord[3]), int(coord[4]))
                 prob = float(coord[5])
                 text_start_point = (int(coord[1]), int(coord[2]) - 10)
     
                 image = cv2.rectangle(image, start_point, end_point,
                          overlay_color[class_name], overlay_thickness)
                 image = cv2.putText(image, str(prob), text_start_point,
                      font, 0.8, overlay_color[class_name], overlay_thickness - 1, cv2.LINE_AA)
 
            cv2.imshow("im", image)
            cv2.waitKey(0)
            cv2.destroyAllWindows()

以下函數(shù)是上述NMS算法的實(shí)現(xiàn)。此函數(shù)用于在應(yīng)用非最大值抑制算法后返回所需的邊界框。

def nms(self, image, bboxes_list):
         req_bboxes, final_boxes = [], []
         for coord in bboxes_list:
              prob = float(coord[5])
              if prob > self.conf:
                 req_bboxes.a(chǎn)ppend(coord)
      # sorting the bounding boxes based on probability score
       bboxes_sorted = sorted(req_bboxes, reverse=True, key=lambda x: x[5])
       while len(bboxes_sorted) > 0:
          # removing the best probability bounding box
          box = bboxes_sorted.pop(0)
          for b in bboxes_sorted:
         # comparing with the same class
          if box[0] == b[0]:
             iou = self.IOU(box[1:-1], b[1:-1])
             if iou >= self.iou_threshsold:
              # if IOU is large then discard the box with lowest probability
               bboxes_sorted.remove(b)
          print(len(bboxes_sorted))
          final_boxes.a(chǎn)ppend(box)
     return final_boxes

以下是NMS類的驅(qū)動(dòng)程序代碼。我們首先讀取coordinates.txt獲取邊界框的坐標(biāo)和其他詳細(xì)信息;然后,我們應(yīng)用NMS算法來獲得所需的邊界框。

if __name__ == "__main__":
            image = cv2.imread("zoraya.jpg")
            with open("coordinates.txt", 'r') as f:
                  data = f.readlines()
            data = [i[:-1].split(' ') for i in data]
            obj = NMS()
            obj.draw_overlay(image, data)
            final_boxes = obj.nms(image, data)
            obj.draw_overlay(image, final_boxes)

coordinates.txt
      0 187 90 586 607 0.94
      0 120 116 600 370 0.68
      1 511 185 961 418 0.58
      0 340 145 568 478 0.47
      1 524 70 920 565 0.92

結(jié)論

本文概述了對(duì)非最大值抑制算法的需求以及python實(shí)現(xiàn)。此外,我們還使用一個(gè)圖像示例解釋了該算法。

       原文標(biāo)題 : 目標(biāo)檢測(cè)中的非最大值抑制算法

聲明: 本文由入駐維科號(hào)的作者撰寫,觀點(diǎn)僅代表作者本人,不代表OFweek立場(chǎng)。如有侵權(quán)或其他問題,請(qǐng)聯(lián)系舉報(bào)。

發(fā)表評(píng)論

0條評(píng)論,0人參與

請(qǐng)輸入評(píng)論內(nèi)容...

請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字

您提交的評(píng)論過于頻繁,請(qǐng)輸入驗(yàn)證碼繼續(xù)

  • 看不清,點(diǎn)擊換一張  刷新

暫無評(píng)論

暫無評(píng)論

人工智能 獵頭職位 更多
掃碼關(guān)注公眾號(hào)
OFweek人工智能網(wǎng)
獲取更多精彩內(nèi)容
文章糾錯(cuò)
x
*文字標(biāo)題:
*糾錯(cuò)內(nèi)容:
聯(lián)系郵箱:
*驗(yàn) 證 碼:

粵公網(wǎng)安備 44030502002758號(hào)