iT邦幫忙

2026 iThome 鐵人賽

DAY 7
0
自我挑戰組

盯!視覺追蹤機器人 | ROS2打造追蹤機器人系列 第 7 篇

Day 7|目標到底在哪邊?從 Bounding Box 找出目標中心

  • 分享至 

  • xImage
  •  

我透過 HSV 顏色篩選,從相機畫面中挑出紅色區域,再透過遮罩(Mask)尋找輪廓。現在程式已經可以找到紅色候選區域了,下一步就是把這個區域的位置算出來。

如果之後想讓 TurtleBot3 自動追蹤目標,只有知道「畫面裡有紅色」還不夠。今天先不急著讓機器人移動,而是先回答一個問題:

目標現在是在畫面的左邊、右邊,還是中央?

從輪廓取得 Bounding Box

今天先不急著讓機器人移動,而是從昨天找到的紅色區域繼續往下,取得目標的位置,並算出目標和畫面中心之間的水平偏差。

昨天透過 Mask 找出紅色區域後,可以使用 findContours() 找到畫面中的輪廓,再利用 Bounding Box 取得候選目標的位置與大小。

如果畫面中有多個紅色區域,目前先簡單選擇面積最大的輪廓作為追蹤目標:

if contours:
    largest = max(contours, key=cv2.contourArea)
    x, y, w, h = cv2.boundingRect(largest)

這裡的 if contours: 是先確認有沒有找到輪廓。有找到,才接著挑出面積最大的那一個,並使用 cv2.boundingRect() 取得包住它的矩形外框,也就是 Bounding Box。接下來的目標中心與誤差,也都只在找到輪廓時才計算。

這四個數值分別代表:

數值 意義
x 外框左上角的 X 座標
y 外框左上角的 Y 座標
w 外框寬度
h 外框高度

也就是先用一個矩形,把找到的紅色區域框起來。這裡取得的是外框的位置與大小,如果想在畫面上看到框線,還需要另外把它畫出來。

不過,選擇最大輪廓只是目前練習場景中的簡化方式。如果畫面中出現更大的紅色物體,程式也可能選到它。之後還需要搭配面積門檻或其他條件,判斷哪一個區域才是要追蹤的目標。

找出目標中心

有了 x、y、w、h,就可以從外框左上角的位置,分別加上一半的寬度和高度,算出外框的中心:

target_x = x + w // 2
target_y = y + h // 2

這裡的 // 是整數除法,方便把結果表示成整數像素座標。目前先用 Bounding Box 的中心,代表目標在畫面中的位置。

我的追蹤目前先處理左右方向,所以會先關注 target_x。它代表目標中心在影像 X 軸上的位置。影像座標通常以左上角為起點,X 值越大,位置就越靠右;Y 值越大,位置就越靠下。例如影像寬度是 640 像素,而 target_x = 500,就表示目標中心比較靠近畫面的右側。不過,要知道它到底偏了多少,還需要先找到畫面中心,作為比較的基準。

畫面的中心在哪?

在 Day 5 中,我已經把 ROS 2 的影像訊息轉成 OpenCV 可以處理的畫面。這裡以 image 代表轉換後的影像,可以透過 shape 取得它的高度和寬度,再計算水平方向的中心:

height, width = image.shape[:2]
center_x = width // 2

這裡要注意,image.shape[:2] 取得的順序是高度、寬度,所以計算左右方向的中心時,要使用 width。

例如影像寬度是 640 像素,程式使用的畫面中心就是 center_x = 320。如果目標的 target_x 也是 320,就表示目標中心剛好對準這個位置;小於 320 時在左側,大於 320 時則在右側。640 只是這裡方便說明的示例寬度。實際計算時,我會直接使用影像的 width,這樣即使相機解析度改變,也不用手動修改畫面中心的數值。

算出目標和中心的誤差

知道目標中心與畫面中心之後,就可以把兩者相減,算出水平方向的誤差:

error_x = target_x - center_x

這裡的 error_x,代表目標中心相對於畫面中心,向左或向右偏了多少像素。它的正負號可以用來判斷方向,數值的絕對值則表示偏離的程度。

以 center_x = 320 為例:

目標中心 target_x 計算方式 誤差 error_x 代表的位置
150 150 − 320 -170 在畫面中心左側,偏了 170 像素
320 320 − 320 0 對準程式設定的畫面中心
500 500 − 320 180 在畫面中心右側,偏了 180 像素

負數在左邊,正數在右邊,接近 0 就表示接近中央。這個方向判斷和減法順序有關,目前使用的是「目標中心減掉畫面中心」,如果順序反過來,正負號的意義也會跟著改變。這裡計算的是影像上的左右偏移,單位是像素,還不是目標與機器人之間的實際距離。

為什麼要算 error_x?

因為之後要讓 TurtleBot3 對準目標,就需要把畫面中的位置,轉成可以用來控制機器人的資訊。目標在左側時,機器人需要往左轉;在右側時,就需要往右轉,讓目標逐漸回到畫面中央。除了方向,偏離的程度也很重要。如果目標只偏了一點點,和目標已經跑到畫面邊緣,機器人需要的轉向速度應該不太一樣。error_x 就能提供這個判斷依據,讓後續的控制程式決定要往哪裡轉,以及要轉多快。

今天先做到位置計算。實際如何把誤差轉成旋轉速度,以及多接近中央時可以停止轉向,會在接下來的控制部分繼續處理。

今天的流程

  1. 取得相機影像,並轉成 OpenCV 可以處理的格式。
  2. 轉換成 HSV,篩選紅色範圍並產生遮罩。
  3. 尋找輪廓,選出候選目標並取得 Bounding Box。
  4. 計算目標中心 target_x 與畫面中心 center_x。
  5. 算出 error_x,判斷目標在左側、右側,或接近中央。

這一步完成後,程式拿到的就不只是畫面中有沒有紅色,還能進一步知道目標偏離畫面中心多少。接下來,才有辦法把這個數值用在 TurtleBot3 的轉向控制上。

NEXT

下一篇會接著把 error_x 用來控制 TurtleBot3:目標在左邊就往左轉,在右邊就往右轉。如果目標偏得越多,是不是也應該轉得越快?


上一篇
Day 6|尋找紅色方塊:用 HSV 找到第一個目標
下一篇
Day 8|看你往哪跑!用 P 控制讓 TurtleBot3 對準目標
系列文
盯!視覺追蹤機器人 | ROS2打造追蹤機器人 共 12 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言