一、引言
在目標檢測任務中,邊界框(Bounding Box)的坐標表示與轉換是核心基礎操作。本文將演示如何:
-
實現邊界框的兩種表示形式(角點坐標 vs 中心坐標)之間的轉換
-
使用Matplotlib在圖像上可視化邊界框
-
驗證坐標轉換的正確性
二、環境準備
import torch
from d2l import torch as d2l
-
PyTorch 1.12+
-
d2l 0.17.0+
-
Matplotlib 3.5+
三、代碼實現與解析
1. 圖像加載與顯示
d2l.set_figsize() # 設置畫布大小
img = d2l.plt.imread('./data/catdog.jpg') # 讀取圖像
d2l.plt.imshow(img) # 顯示圖像
2. 坐標轉換函數
角點坐標 → 中心坐標
def box_corner_to_center(boxes):x1, y1, x2, y2 = boxes[:,0], boxes[:,1], boxes[:,2], boxes[:,3]cx = (x1 + x2) / 2 # 中心x坐標cy = (y1 + y2) / 2 # 中心y坐標w = x2 - x1 # 寬度h = y2 - y1 # 高度return torch.stack((cx, cy, w, h), axis=-1)
中心坐標 → 角點坐標
def box_center_to_corner(boxes):cx, cy, w, h = boxes[:,0], boxes[:,1], boxes[:,2], boxes[:,3]x1 = cx - w/2 # 左上角xy1 = cy - h/2 # 左上角yx2 = cx + w/2 # 右下角xy2 = cy + h/2 # 右下角yreturn torch.stack((x1, y1, x2, y2), axis=-1)
3. 轉換驗證
dog_bbox = [10.0, 50.0, 80.0, 110.0] # 狗的邊界框(左上x,左上y,右下x,右下y)
cat_bbox = [90.0, 40.0, 160.0, 110.0] # 貓的邊界框
boxes = torch.tensor([dog_bbox, cat_bbox])# 驗證轉換的正確性
print(box_center_to_corner(box_corner_to_center(boxes)) == boxes)
輸出結果:
tensor([[True, True, True, True],[True, True, True, True]])
4. 邊界框可視化
def bbox_to_rect(bbox, color):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')) # 添加紅色貓框
可視化效果:
-
X軸范圍:0-150
-
Y軸范圍:0-125
-
藍色矩形框標注狗的位置
-
紅色矩形框標注貓的位置
四、完整代碼
import torch
from d2l import torch as d2l# 設置畫布并加載圖像
d2l.set_figsize()
img = d2l.plt.imread('./data/catdog.jpg')
d2l.plt.imshow(img)# 坐標轉換函數
def box_corner_to_center(boxes):x1, y1, x2, y2 = boxes[:,0], boxes[:,1], boxes[:,2], boxes[:,3]cx, cy = (x1+x2)/2, (y1+y2)/2w, h = x2-x1, y2-y1return torch.stack((cx, cy, w, h), axis=-1)def box_center_to_corner(boxes):cx, cy, w, h = boxes[:,0], boxes[:,1], boxes[:,2], boxes[:,3]x1, y1 = cx-w/2, cy-h/2x2, y2 = cx+w/2, cy+h/2return torch.stack((x1, y1, x2, y2), axis=-1)# 定義邊界框并驗證轉換
dog_bbox, cat_bbox = [10.0,50.0,80.0,110.0], [90.0,40.0,160.0,110.0]
boxes = torch.tensor([dog_bbox, cat_bbox])
print(box_center_to_corner(box_corner_to_center(boxes)) == boxes)# 可視化邊界框
def bbox_to_rect(bbox, color):return d2l.plt.Rectangle((bbox[0], bbox[1]), bbox[2]-bbox[0], 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'))
五、關鍵點解析
-
坐標表示形式:
-
角點表示:(左上x, 左上y, 右下x, 右下y)
-
中心表示:(中心x, 中心y, 寬度, 高度)
-
-
轉換驗證:
-
通過兩次轉換后與原值對比,全True結果證明轉換正確性
-
-
可視化技巧:
-
使用Matplotlib的Rectangle對象創建邊界框
-
通過add_patch方法將圖形元素添加到坐標軸
-
六、總結
本文實現了目標檢測中邊界框的坐標轉換與可視化,驗證了:
-
兩種坐標表示形式的等價性
-
邊界框在圖像上的準確定位
-
轉換函數的正確性
該技術可應用于目標檢測數據預處理、結果可視化等場景。讀者可以嘗試修改邊界框坐標,觀察不同位置的可視化效果。
實際運行效果示意圖:
(注:需自行準備包含貓狗的圖像,保存為./data/catdog.jpg
)