目標(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è)中的非最大值抑制算法
發(fā)表評(píng)論
請(qǐng)輸入評(píng)論內(nèi)容...
請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字
最新活動(dòng)更多
-
即日-11.13立即報(bào)名>>> 【在線會(huì)議】多物理場(chǎng)仿真助跑新能源汽車
-
11月28日立即報(bào)名>>> 2024工程師系列—工業(yè)電子技術(shù)在線會(huì)議
-
12月19日立即報(bào)名>> 【線下會(huì)議】OFweek 2024(第九屆)物聯(lián)網(wǎng)產(chǎn)業(yè)大會(huì)
-
即日-12.26火熱報(bào)名中>> OFweek2024中國(guó)智造CIO在線峰會(huì)
-
即日-2025.8.1立即下載>> 《2024智能制造產(chǎn)業(yè)高端化、智能化、綠色化發(fā)展藍(lán)皮書》
-
精彩回顧立即查看>> 【限時(shí)免費(fèi)下載】TE暖通空調(diào)系統(tǒng)高效可靠的組件解決方案
推薦專題
- 1 【一周車話】沒有方向盤和踏板的車,你敢坐嗎?
- 2 特斯拉發(fā)布無人駕駛車,還未迎來“Chatgpt時(shí)刻”
- 3 特斯拉股價(jià)大跌15%:Robotaxi離落地還差一個(gè)蘿卜快跑
- 4 馬斯克給的“驚喜”夠嗎?
- 5 打完“價(jià)格戰(zhàn)”,大模型還要比什么?
- 6 馬斯克致敬“國(guó)產(chǎn)蘿卜”?
- 7 神經(jīng)網(wǎng)絡(luò),誰是盈利最強(qiáng)企業(yè)?
- 8 比蘋果偉大100倍!真正改寫人類歷史的智能產(chǎn)品降臨
- 9 諾獎(jiǎng)進(jìn)入“AI時(shí)代”,人類何去何從?
- 10 Open AI融資后成萬億獨(dú)角獸,AI人才之爭(zhēng)開啟
- 高級(jí)軟件工程師 廣東省/深圳市
- 自動(dòng)化高級(jí)工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級(jí)銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市