深度學習|目標檢測評價指標&NMS


1.目標檢測

目標檢測(Object Detection)的任務是找出圖像中所有感興趣的目標,並確定它們的類別和位置。
目標檢測的位置信息一般由兩種格式(以圖片左上角為原點(0,0)):
1、極坐標表示:(xmin, ymin, xmax, ymax)

  • xmin,ymin:x,y坐標的最小值
  • xmin,ymin:x,y坐標的最大值

2、中心點坐標:(x_center, y_center, w, h)

  • x_center, y_center:目標檢測框的中心點坐標
  • w,h:目標檢測框的寬、高

image

那么按中心坐標如下:
image

2.常用的評價指標

2.1 Iou

在目標檢測算法中,IoU(intersection over union,交並比)是目標檢測算法中用來評價2個矩形框之間相似度的指標:
IoU = 兩個矩形框相交的面積 / 兩個矩形框相並的面積
通過一個例子看下在目標檢測中的應用:
image
其中上圖藍色框框為檢測結果,紅色框框為真實標注。
一般我們會設置應該閾值,一旦IoU大於閾值,我們就認為檢測到目標物體。
代碼實現:

import numpy as np
def Iou(box1,box2,wh=False):
	# 判斷是否按中心坐標
	 if wh == False:
	 	# 使用極坐標
	 	xmin1,ymin1,xmax1,ymax1 = box1
	 	xmin2,ymin2,xmax2,ymax2 = box2
	 else:
	 	# 使用中心坐標
	 	xmin1,ymin1 = int(box1[0]-box1[2]/2),int(box1[1]-box1[3]/2)
	 	xmax1,ymax1 = int(box1[0]+box1[2]/2),int(box1[1]+box1[3]/2)

		xmin2,ymin2 = int(box2[0]-box2[2]/2),int(box2[1]-box2[3]/2)
	 	xmax2,ymax2 = int(box2[0]+box2[2]/2),int(box2[1]+box2[3]/2)

	# 獲取交集的左上和右下的坐標
	xx1 = np.max([xmin1,xmin2])
	yy1 = np.max([ymin1,ymin2])

	xx2 = np.min([xmax1,xmax2])
	yy2 = np.min([ymax1,ymax2])
	# 計算兩個矩形的面積
	area1 = (xmax1-xmin1) * (ymax1-ymin1)
	area2 = (xmax2-xmin2) * (ymax2-ymin2)
	# 計算交集的面積
	inter_area = (np.max([0.0,xx2-xx1]))*(np.max([0.0,yy2-yy1]))
	# 計算Iou
	iou = inter_area/(area2+area1-inter_area+1e-6)
	return iou

2.2 mAP

目標檢測問題中的每個圖片都可能包含一些不同類別的物體,需要評估模型的物體分類和定位性能。因此,用於圖像分類問題的標准指標precision不能直接應用於此。 在目標檢測中,mAP是主要的衡量指標。
mAP是多個分類任務的AP的平均值,而AP(average precision)是PR曲線下的面積,所以在介紹mAP之前我們要先得到PR曲線。
TP、FP、FN、TN

  • TP:Iou大於閾值的檢測框數量
  • FP:Iou小於閾值的檢測框數量,或者是檢測到同一個GT(Ground Truth,真實框)的多余檢測框的數量
  • FN:沒有被檢測到的GT的數量
  • TN:在mAP沒有用到,無實際意義

查准率、查全率

  • 查准率:TP/(TP+FP)
  • 查全率:TP/(TP+NP)

查全率(Recall)做橫坐標,查准率(Precision)做縱坐標
image
AP 是計算某一類 P-R 曲線下的面積,mAP 則是計算所有類別 P-R 曲線下面積的平均值。
使用例子幫助理解
假設我們有 7 張圖片(Images1-Image7),這些圖片有 15 個目標(綠色的框,GT 的數量,上文提及的 all ground truths)以及 24 個預測邊框(紅色的框,A-Y 編號表示,並且有一個置信度值):
image
根據上圖以及說明,我們可以列出以下表格,其中 Images 代表圖片的編號,Detections 代表預測邊框的編號,Confidences 代表預測邊框的置信度,TP or FP 代表預測的邊框是標記為 TP 還是 FP(認為預測邊框與 GT 的 IOU 值大於等於 0.3 就標記為 TP;若一個 GT 有多個預測邊框,則認為 IOU 最大且大於等於 0.3 的預測框標記為 TP,其他的標記為 FP,即一個 GT 只能有一個預測框標記為 TP),這里的 0.3 是隨機取的一個值。
image
因為此時的到的只是一組固定P、R,不能繪制P-R 曲線,以此我們引入累加的概念。根據置信度從大到小排序所有的預測框,然后就可以計算 Precision 和 Recall 的值,見下表。
image

  • 每一行的Precision = ACCTP/(ACCTP+ACCFP):比如標號為10的Precision=3/(7+3)=0.3
  • 每一行的Recall = ACCTP/(GT):比如標號為10的Recall=3/15=0.2
    以此類推,按Confidences算出所有預測框的Precision和Recall
    然后就可以繪制出 P-R 曲線
    image
    得到 P-R 曲線就可以計算 AP(P-R 曲線下的面積),要計算 P-R 下方的面積,有兩種方法:
    在VOC2010以前,只需要選取當Recall >= 0, 0.1, 0.2, ..., 1共11個點時的Precision最大值,然后AP就是這11個Precision的平均值,取 11 個點 [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1] 的插值所得
    image
    當Recall=0.2時,>=0.2的Precision最大值為0.4,故為0.4,>0.5以后Recall都為0
    這時我們得到一個類別的AP結果:
    image
    在VOC2010及以后,需要針對每一個不同的Recall值(包括0和1),選取其大於等於這些Recall值時的Precision最大值,如下圖所示:
    image
    然后計算PR曲線下面積作為AP值:
    image
    image
    計算mAP就是將所有類別的相加再除以類別個數。

3.NMS(非極大值抑制)

非極大值抑制(Non-Maximum Suppression,NMS),顧名思義就是抑制不是極大值的元素。我們在檢測一個真實框時,可能出現很多備選測試框,這時我們選擇某一指標最大的窗口,並且抑制那些分數低的窗口。
在目標檢測中,NMS的目的就是要去除冗余的檢測框,保留最好的一個,如下圖所示:
image
NMS的原理是對於預測框的列表B及其對應的置信度S,選擇具有最大score的檢測框M,將其從B集合中移除並加入到最終的檢測結果D中.通常將B中剩余檢測框中與M的IoU大於閾值Nt的框從B中移除.重復這個過程,直到B為空。
使用流程如下圖所示:

  • 首先是檢測出一系列的檢測框
  • 將檢測框按照類別進行分類
  • 對同一類別的檢測框應用NMS獲取最終的檢測結果

通過一個例子看些NMS的使用方法,假設定位車輛,算法就找出了一系列的矩形框,我們需要判別哪些矩形框是沒用的,需要使用NMS的方法來實現。
image
假設現在檢測窗口有:A、B、C、D、E 5個候選框,接下來進行迭代計算:

  • 第一輪:因為B是得分最高的,與B的IoU>0.5刪除。A,CDE中現在與B計算IoU,DE結果>0.5,剔除DE,B作為一個預測結果,有個檢測框留下B,放入集合
  • 第二輪:A的得分最高,與A計算IoU,C的結果>0.5,剔除C,A作為一個結果

最終結果為在這個5個中檢測出了兩個目標為A和B。
代碼實現如下:

def nms(boxes,score,threshold):
	if len(boxes)==0:
		return [],[]
	# 類型轉換
	boxes = np.array(boxes)
	score = np.array(score)
	# 獲取坐標
	x1 = boxes[:,0]
	y1 = boxes[:,1]
	x2 = boxes[:,2]
	y2 = boxes[:,3]
	# 計算面積
	areas = (x2-x1)*(y2-y1)

	picked_boxed = []
	picked_score = []

	#按score排序,從小到大,返回索引值
	order = np.argsort(score)
	while order.size>0:
		# 獲取score最大值的索引
		index = order[-1]
		picked_boxed.append(boxes[index]) 
		picked_score.append(score[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]])
		inter_area = np.maximum(0.0,x22-x11)*np.maximum(0.0,y22-y11)
		keep_boxes = np.where(iou<threshold)
		order = order[keep_boxes]
	return picked_boxed,picked_score

假設有檢測結果如下:

bounding = [(187, 82, 337, 317), (150, 67, 305, 282), (246, 121, 368, 304)]
confidence_score = [0.9, 0.65, 0.8]
threshold = 0.3
picked_boxes, picked_score = nms(bounding, confidence_score, threshold)
print('閾值threshold為:', threshold)
print('NMS后得到的bbox是:', picked_boxes)
print('NMS后得到的bbox的confidences是:', picked_score)

返回結果:
閾值threshold為: 0.3
NMS后得到的bbox是: [array([187, 82, 337, 317])]
NMS后得到的bbox的confidences是: [0.9]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM