目標檢測和邊界框
前面的章節(例如 sec_alexnet
— sec_googlenet
)介紹了各種圖像分類模型。
在圖像分類任務中,我們假設圖像中只有一個主要物體對象,我們只關注如何識別其類別。
然而,很多時候圖像里有多個我們感興趣的目標,我們不僅想知道它們的類別,還想得到它們在圖像中的具體位置。
在計算機視覺里,我們將這類任務稱為目標檢測(object detection)或目標識別(object recognition)。
目標檢測在多個領域中被廣泛使用。
例如,在無人駕駛里,我們需要通過識別拍攝到的視頻圖像里的車輛、行人、道路和障礙物的位置來規劃行進線路。
機器人也常通過該任務來檢測感興趣的目標。安防領域則需要檢測異常目標,如歹徒或者炸彈。
接下來的幾節將介紹幾種用于目標檢測的深度學習方法。
我們將首先介紹目標的位置。
%matplotlib inline
import torch
from d2l import torch as d2l
下面加載本節將使用的示例圖像。可以看到圖像左邊是一只狗,右邊是一只貓。
它們是這張圖像里的兩個主要目標。
d2l.set_figsize()
img = d2l.plt.imread('../img/catdog.jpg')
d2l.plt.imshow(img);
?
?
邊界框
在目標檢測中,我們通常使用邊界框(bounding box)來描述對象的空間位置。
邊界框是矩形的,由矩形左上角的以及右下角的 x x x和 y y y坐標決定。
另一種常用的邊界框表示方法是邊界框中心的 ( x , y ) (x, y) (x,y)軸坐標以及框的寬度和高度。
在這里,我們[定義在這兩種表示法之間進行轉換的函數]:box_corner_to_center
從兩角表示法轉換為中心寬度表示法,而box_center_to_corner
反之亦然。
輸入參數boxes
可以是長度為4的張量,也可以是形狀為( n n n,4)的二維張量,其中 n n n是邊界框的數量。
#@save
def box_corner_to_center(boxes):"""從(左上,右下)轉換到(中間,寬度,高度)"""x1, y1, x2, y2 = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3]cx = (x1 + x2) / 2cy = (y1 + y2) / 2w = x2 - x1h = y2 - y1boxes = torch.stack((cx, cy, w, h), axis=-1)return boxes#@save
def box_center_to_corner(boxes):"""從(中間,寬度,高度)轉換到(左上,右下)"""cx, cy, w, h = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3]x1 = cx - 0.5 * wy1 = cy - 0.5 * hx2 = cx + 0.5 * wy2 = cy + 0.5 * hboxes = torch.stack((x1, y1, x2, y2), axis=-1)return boxes
我們將根據坐標信息[定義圖像中狗和貓的邊界框]。
圖像中坐標的原點是圖像的左上角,向右的方向為 x x x軸的正方向,向下的方向為 y y y軸的正方向。
# bbox是邊界框的英文縮寫
dog_bbox, cat_bbox = [60.0, 45.0, 378.0, 516.0], [400.0, 112.0, 655.0, 493.0]
我們可以通過轉換兩次來驗證邊界框轉換函數的正確性。
boxes = torch.tensor((dog_bbox, cat_bbox))
box_center_to_corner(box_corner_to_center(boxes)) == boxes
tensor([[True, True, True, True],[True, True, True, True]])
我們可以[將邊界框在圖中畫出],以檢查其是否準確。
畫之前,我們定義一個輔助函數bbox_to_rect
。
它將邊界框表示成matplotlib
的邊界框格式。
#@save
def bbox_to_rect(bbox, color):# 將邊界框(左上x,左上y,右下x,右下y)格式轉換成matplotlib格式:# ((左上x,左上y),寬,高)return d2l.plt.Rectangle(xy=(bbox[0], bbox[1]), width=bbox[2]-bbox[0], height=bbox[3]-bbox[1],fill=False, edgecolor=color, linewidth=2)
在圖像上添加邊界框之后,我們可以看到兩個物體的主要輪廓基本上在兩個框內。
fig = d2l.plt.imshow(img)
fig.axes.add_patch(bbox_to_rect(dog_bbox, 'blue'))
fig.axes.add_patch(bbox_to_rect(cat_bbox, 'red'));
?
?
小結
- 目標檢測不僅可以識別圖像中所有感興趣的物體,還能識別它們的位置,該位置通常由矩形邊界框表示。
- 我們可以在兩種常用的邊界框表示(中間,寬度,高度)和(左上,右下)坐標之間進行轉換。