计算机视觉:目标检测的发展历程与基础概念
計算機視覺:目標檢測的發展歷程與基礎概念
- 目標檢測發展歷程
- 目標檢測基礎概念
- 邊界框(bounding box)
- 錨框(Anchor box)
- 交并比
對計算機而言,能夠“看到”的是圖像被編碼之后的數字,但它很難理解高層語義概念,比如圖像或者視頻幀中出現的目標是人還是物體,更無法定位目標出現在圖像中哪個區域。目標檢測的主要目的是讓計算機可以自動識別圖片或者視頻幀中所有目標的類別,并在該目標周圍繪制邊界框,標示出每個目標的位置,如 圖1 所示。
圖1:圖像分類和目標檢測示意圖
- 圖1(a)是圖像分類任務,只需識別出這是一張斑馬的圖片。
- 圖1(b)是目標檢測任務,不僅要識別出這是一張斑馬的圖片,還要標出圖中斑馬的位置。
目標檢測發展歷程
在上一節中學習了圖像分類處理基本流程,先使用卷積神經網絡提取圖像特征,然后再用這些特征預測分類概率,根據訓練樣本標簽建立起分類損失函數,開啟端到端的訓練,如 圖2 所示。
圖2:圖像分類流程示意圖
但對于目標檢測問題,按照 圖2 的流程則行不通。因為在圖像分類任務中,對整張圖提取特征的過程中沒能體現出不同目標之間的區別,最終也就沒法分別標示出每個物體所在的位置。
為了解決這個問題,結合圖片分類任務取得的成功經驗,我們可以將目標檢測任務進行拆分。假設我們現在有某種方式可以在輸入圖片上生成一系列可能包含物體的區域,這些區域稱為候選區域,在一張圖上可以生成很多個候選區域。然后對每個候選區域,可以把它單獨當成一幅圖像來看待,使用圖像分類模型對它進行分類,看它屬于哪個類別或者背景(即不包含任何物體的類別)。
上一節學過如何解決圖像分類任務,使用卷積神經網絡對一幅圖像進行分類不再是一件困難的事情。那么,現在問題的關鍵就是如何產生候選區域?比如我們可以使用窮舉法來產生候選區域,如圖3所示。
圖3:候選區域
A為圖像上的某個像素點,B為A右下方另外一個像素點,A、B兩點可以確定一個矩形框,記作AB。
- 如圖3(a)所示:A在圖片左上角位置,B遍歷除A之外的所有位置,生成矩形框A1B1, …, A1Bn, …
- 如圖3(b)所示:A在圖片中間某個位置,B遍歷A右下方所有位置,生成矩形框AkB1, …, AkBn, …
當A遍歷圖像上所有像素點,B則遍歷它右下方所有的像素點,最終生成的矩形框集合{AiBj}將會包含圖像上所有可以選擇的區域。
只要我們對每個候選區域的分類足夠的準確,則一定能找到跟實際物體足夠接近的區域來。窮舉法也許能得到正確的預測結果,但其計算量也是非常巨大的,其所生成的總候選區域數目約為W2H24\frac{W^2 H^2}{4}4W2H2?,假設H=W=100H=W=100H=W=100,總數將會達到2.5×1072.5 \times 10^{7}2.5×107個,如此多的候選區域使得這種方法幾乎沒有什么實用性。但是通過這種方式,我們可以看出,假設分類任務完成的足夠完美,從理論上來講檢測任務也是可以解決的,亟待解決的問題是如何設計出合適的方法來產生候選區域。
科學家們開始思考,是否可以應用傳統圖像算法先產生候選區域,然后再用卷積神經網絡對這些區域進行分類?
- 2013年,Ross Girshick 等人于首次將CNN的方法應用在目標檢測任務上,他們使用傳統圖像算法Selective Search產生候選區域,取得了極大的成功,這就是對目標檢測領域影響深遠的區域卷積神經網絡(R-CNN)模型。
- 2015年,Ross Girshick 對此方法進行了改進,提出了Fast R-CNN模型。通過將不同區域的物體共用卷積層的計算,大大縮減了計算量,提高了處理速度,而且還引入了調整目標物體位置的回歸方法,進一步提高了位置預測的準確性。
- 2015年,Shaoqing Ren 等人提出了Faster R-CNN模型,提出了RPN的方法來產生物體的候選區域,這一方法不再需要使用傳統的圖像處理算法來產生候選區域,進一步提升了處理速度。
- 2017年,Kaiming He 等人提出了Mask R-CNN模型,只需要在Faster R-CNN模型上添加比較少的計算量,就可以同時實現目標檢測和物體實例分割兩個任務。
以上都是基于R-CNN系列的著名模型,對目標檢測方向的發展有著較大的影響力。此外,還有一些其他模型,比如SSD、YOLO(1, 2, 3)、R-FCN等也都是目標檢測領域流行的模型結構。
R-CNN的系列算法分成兩個階段,先在圖像上產生候選區域,再對候選區域進行分類并預測目標物體位置,它們通常被叫做兩階段檢測算法。SSD和YOLO算法則只使用一個網絡同時產生候選區域并預測出物體的類別和位置,所以它們通常被叫做單階段檢測算法。由于篇幅所限,本章將重點介紹YOLO-V3算法,并用其完成林業病蟲害檢測任務,主要涵蓋如下內容:
- 圖像檢測基礎概念:介紹與目標檢測相關的基本概念,包括邊界框、錨框和交并比等。
- 林業病蟲害數據集:介紹數據集結構及數據預處理方法。
- YOLO-V3目標檢測模型:介紹算法原理,及如何應用林業病蟲害數據集進行模型訓練和測試。
目標檢測基礎概念
在介紹目標檢測算法之前,先介紹一些跟檢測相關的基本概念,包括邊界框、錨框和交并比等。
邊界框(bounding box)
檢測任務需要同時預測物體的類別和位置,因此需要引入一些跟位置相關的概念。通常使用邊界框(bounding box,bbox)來表示物體的位置,邊界框是正好能包含物體的矩形框,如 圖4 所示,圖中3個人分別對應3個邊界框。
圖4:邊界框
通常有兩種格式來表示邊界框的位置:
- 左:(40.93,141.1,226.99,515.73)(40.93, 141.1, 226.99, 515.73)(40.93,141.1,226.99,515.73)。
- 中:(214.29,325.03,399.82,631.37)(214.29, 325.03, 399.82, 631.37)(214.29,325.03,399.82,631.37)。
- 右:(247.2,131.62,480.0,639.32)(247.2, 131.62, 480.0, 639.32)(247.2,131.62,480.0,639.32)。
在檢測任務中,訓練數據集的標簽里會給出目標物體真實邊界框所對應的(x1,y1,x2,y2)(x_1, y_1, x_2, y_2)(x1?,y1?,x2?,y2?),這樣的邊界框也被稱為真實框(ground truth box),如 圖4 所示,圖中畫出了3個人像所對應的真實框。模型會對目標物體可能出現的位置進行預測,由模型預測出的邊界框則稱為預測框(prediction box)。
注意:
要完成一項檢測任務,我們通常希望模型能夠根據輸入的圖片,輸出一些預測的邊界框,以及邊界框中所包含的物體的類別或者說屬于某個類別的概率,例如這種格式: [L,P,x1,y1,x2,y2][L, P, x_1, y_1, x_2, y_2][L,P,x1?,y1?,x2?,y2?],其中LLL是類別標簽,PPP是物體屬于該類別的概率。一張輸入圖片可能會產生多個預測框,接下來讓我們一起學習如何完成這項任務。
錨框(Anchor box)
錨框與物體邊界框不同,是由人們假想出來的一種框。先設定好錨框的大小和形狀,再以圖像上某一個點為中心畫出矩形框。在下圖中,以像素點[300, 500]為中心可以使用下面的程序生成3個框,如圖中藍色框所示,其中錨框A1跟人像區域非常接近。
# 畫圖展示如何繪制邊界框和錨框 import numpy as np import matplotlib.pyplot as plt import matplotlib.patches as patches from matplotlib.image import imread import math# 定義畫矩形框的程序 def draw_rectangle(currentAxis, bbox, edgecolor = 'k', facecolor = 'y', fill=False, linestyle='-'):# currentAxis,坐標軸,通過plt.gca()獲取# bbox,邊界框,包含四個數值的list, [x1, y1, x2, y2]# edgecolor,邊框線條顏色# facecolor,填充顏色# fill, 是否填充# linestype,邊框線型# patches.Rectangle需要傳入左上角坐標、矩形區域的寬度、高度等參數rect=patches.Rectangle((bbox[0], bbox[1]), bbox[2]-bbox[0]+1, bbox[3]-bbox[1]+1, linewidth=1,edgecolor=edgecolor,facecolor=facecolor,fill=fill, linestyle=linestyle)currentAxis.add_patch(rect)plt.figure(figsize=(10, 10))filename = '/home/aistudio/work/images/section3/000000086956.jpg' im = imread(filename) plt.imshow(im)# 使用xyxy格式表示物體真實框 bbox1 = [214.29, 325.03, 399.82, 631.37] bbox2 = [40.93, 141.1, 226.99, 515.73] bbox3 = [247.2, 131.62, 480.0, 639.32]currentAxis=plt.gca()draw_rectangle(currentAxis, bbox1, edgecolor='r') draw_rectangle(currentAxis, bbox2, edgecolor='r') draw_rectangle(currentAxis, bbox3,edgecolor='r')# 繪制錨框 def draw_anchor_box(center, length, scales, ratios, img_height, img_width):"""以center為中心,產生一系列錨框其中length指定了一個基準的長度scales是包含多種尺寸比例的listratios是包含多種長寬比的listimg_height和img_width是圖片的尺寸,生成的錨框范圍不能超出圖片尺寸之外"""bboxes = []for scale in scales:for ratio in ratios:h = length*scale*math.sqrt(ratio)w = length*scale/math.sqrt(ratio) x1 = max(center[0] - w/2., 0.)y1 = max(center[1] - h/2., 0.)x2 = min(center[0] + w/2. - 1.0, img_width - 1.0)y2 = min(center[1] + h/2. - 1.0, img_height - 1.0)print(center[0], center[1], w, h)bboxes.append([x1, y1, x2, y2])for bbox in bboxes:draw_rectangle(currentAxis, bbox, edgecolor = 'b')img_height = im.shape[0] img_width = im.shape[1] draw_anchor_box([300., 500.], 100., [2.0], [0.5, 1.0, 2.0], img_height, img_width)################# 以下為添加文字說明和箭頭###############################plt.text(285, 285, 'G1', color='red', fontsize=20) plt.arrow(300, 288, 30, 40, color='red', width=0.001, length_includes_head=True, \head_width=5, head_length=10, shape='full')plt.text(190, 320, 'A1', color='blue', fontsize=20) plt.arrow(200, 320, 30, 40, color='blue', width=0.001, length_includes_head=True, \head_width=5, head_length=10, shape='full')plt.text(160, 370, 'A2', color='blue', fontsize=20) plt.arrow(170, 370, 30, 40, color='blue', width=0.001, length_includes_head=True, \head_width=5, head_length=10, shape='full')plt.text(115, 420, 'A3', color='blue', fontsize=20) plt.arrow(127, 420, 30, 40, color='blue', width=0.001, length_includes_head=True, \head_width=5, head_length=10, shape='full')#draw_anchor_box([200., 200.], 100., [2.0], [0.5, 1.0, 2.0]) plt.show() 300.0 500.0 282.84271247461896 141.4213562373095 300.0 500.0 200.0 200.0 300.0 500.0 141.42135623730948 282.842712474619在目標檢測任務中,通常會以某種規則在圖片上生成一系列錨框,將這些錨框當成可能的候選區域。模型對這些候選區域是否包含物體進行預測,如果包含目標物體,則還需要進一步預測出物體所屬的類別。還有更為重要的一點是,由于錨框位置是固定的,它不大可能剛好跟物體邊界框重合,所以需要在錨框的基礎上進行微調以形成能準確描述物體位置的預測框,模型需要預測出微調的幅度。在訓練過程中,模型通過學習不斷的調整參數,最終能學會如何判別出錨框所代表的候選區域是否包含物體,如果包含物體的話,物體屬于哪個類別,以及物體邊界框相對于錨框位置需要調整的幅度。
不同的模型往往有著不同的生成錨框的方式,在后面的內容中,會詳細介紹YOLO-V3算法里面產生錨框的規則,理解了它的設計方案,也很容易類推到其它模型上。
交并比
上面我們畫出了以點(300,500)(300, 500)(300,500)為中心,生成的三個錨框,我們可以看到錨框A1 與真實框 G1的重合度比較好。那么如何衡量這三個錨框跟真實框之間的關系呢?在檢測任務中,使用交并比(Intersection of Union,IoU)作為衡量指標。這一概念來源于數學中的集合,用來描述兩個集合AAA和BBB之間的關系,它等于兩個集合的交集里面所包含的元素個數,除以它們的并集里面所包含的元素個數,具體計算公式如下:
IoU=A∩BA∪BIoU = \frac{A\cap B}{A \cup B}IoU=A∪BA∩B?
我們將用這個概念來描述兩個框之間的重合度。兩個框可以看成是兩個像素的集合,它們的交并比等于兩個框重合部分的面積除以它們合并起來的面積。下圖“交集”中青色區域是兩個框的重合面積,圖“并集”中藍色區域是兩個框的相并面積。用這兩個面積相除即可得到它們之間的交并比,如 圖5 所示。
圖5:交并比
假設兩個矩形框A和B的位置分別為:
A:[xa1,ya1,xa2,ya2]A: [x_{a1}, y_{a1}, x_{a2}, y_{a2}]A:[xa1?,ya1?,xa2?,ya2?]
B:[xb1,yb1,xb2,yb2]B: [x_{b1}, y_{b1}, x_{b2}, y_{b2}]B:[xb1?,yb1?,xb2?,yb2?]
假如位置關系如 圖6 所示:
圖6:計算交并比
如果二者有相交部分,則相交部分左上角坐標為:
x1=max(xa1,xb1),y1=max(ya1,yb1)x_1 = max(x_{a1}, x_{b1}), \ \ \ \ \ y_1 = max(y_{a1}, y_{b1})x1?=max(xa1?,xb1?),?????y1?=max(ya1?,yb1?)
相交部分右下角坐標為:
x2=min(xa2,xb2),y2=min(ya2,yb2)x_2 = min(x_{a2}, x_{b2}), \ \ \ \ \ y_2 = min(y_{a2}, y_{b2})x2?=min(xa2?,xb2?),?????y2?=min(ya2?,yb2?)
計算先交部分面積:
intersection=max(x2?x1+1.0,0)?max(y2?y1+1.0,0)intersection = max(x_2 - x_1 + 1.0, 0) \cdot max(y_2 - y_1 + 1.0, 0)intersection=max(x2??x1?+1.0,0)?max(y2??y1?+1.0,0)
矩形框A和B的面積分別是:
SA=(xa2?xa1+1.0)?(ya2?ya1+1.0)S_A = (x_{a2} - x_{a1} + 1.0) \cdot (y_{a2} - y_{a1} + 1.0)SA?=(xa2??xa1?+1.0)?(ya2??ya1?+1.0)
SB=(xb2?xb1+1.0)?(yb2?yb1+1.0)S_B = (x_{b2} - x_{b1} + 1.0) \cdot (y_{b2} - y_{b1} + 1.0)SB?=(xb2??xb1?+1.0)?(yb2??yb1?+1.0)
計算相并部分面積:
union=SA+SB?intersectionunion = S_A + S_B - intersectionunion=SA?+SB??intersection
計算交并比:
IoU=intersectionunionIoU = \frac{intersection}{union}IoU=unionintersection?
思考:
兩個矩形框之間的相對位置關系,除了上面的示意圖之外,還有哪些可能,上面的公式能否覆蓋所有的情形?
交并比計算程序如下:
# 計算IoU,矩形框的坐標形式為xyxy,這個函數會被保存在box_utils.py文件中 def box_iou_xyxy(box1, box2):# 獲取box1左上角和右下角的坐標x1min, y1min, x1max, y1max = box1[0], box1[1], box1[2], box1[3]# 計算box1的面積s1 = (y1max - y1min + 1.) * (x1max - x1min + 1.)# 獲取box2左上角和右下角的坐標x2min, y2min, x2max, y2max = box2[0], box2[1], box2[2], box2[3]# 計算box2的面積s2 = (y2max - y2min + 1.) * (x2max - x2min + 1.)# 計算相交矩形框的坐標xmin = np.maximum(x1min, x2min)ymin = np.maximum(y1min, y2min)xmax = np.minimum(x1max, x2max)ymax = np.minimum(y1max, y2max)# 計算相交矩形行的高度、寬度、面積inter_h = np.maximum(ymax - ymin + 1., 0.)inter_w = np.maximum(xmax - xmin + 1., 0.)intersection = inter_h * inter_w# 計算相并面積union = s1 + s2 - intersection# 計算交并比iou = intersection / unionreturn ioubbox1 = [100., 100., 200., 200.] bbox2 = [120., 120., 220., 220.] iou = box_iou_xyxy(bbox1, bbox2) print('IoU is {}'.format(iou)) IoU is 0.47402644317607107 # 計算IoU,矩形框的坐標形式為xywh def box_iou_xywh(box1, box2):x1min, y1min = box1[0] - box1[2]/2.0, box1[1] - box1[3]/2.0x1max, y1max = box1[0] + box1[2]/2.0, box1[1] + box1[3]/2.0s1 = box1[2] * box1[3]x2min, y2min = box2[0] - box2[2]/2.0, box2[1] - box2[3]/2.0x2max, y2max = box2[0] + box2[2]/2.0, box2[1] + box2[3]/2.0s2 = box2[2] * box2[3]xmin = np.maximum(x1min, x2min)ymin = np.maximum(y1min, y2min)xmax = np.minimum(x1max, x2max)ymax = np.minimum(y1max, y2max)inter_h = np.maximum(ymax - ymin, 0.)inter_w = np.maximum(xmax - xmin, 0.)intersection = inter_h * inter_wunion = s1 + s2 - intersectioniou = intersection / unionreturn iou為了直觀的展示交并比的大小跟重合程度之間的關系,圖7 示意了不同交并比下兩個框之間的相對位置關系,從 IoU = 0.95 到 IoU = 0.
圖7:不同交并比下兩個框之間相對位置示意圖
問題:
總結
以上是生活随笔為你收集整理的计算机视觉:目标检测的发展历程与基础概念的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机视觉:基于眼疾分类数据集iChal
- 下一篇: AI识虫:林业病虫害数据集和数据预处理方