OpenCV 单对象追踪
这篇教学会介绍如何使用 OpenCV 里的单对象追踪功能 ( tracker ),并搭配 cv2.selectROI 选取需要追踪的物体,就能即时进行该对象的追踪。
快速导览:
因为程序中的 OpenCV 会需要使用镜头或 GPU,所以请使用本机环境 ( 参考:使用 Python 虚拟环境 ) 或使用 Anaconda Jupyter 进行实作 ( 参考:使用 Anaconda ) ,并安装 OpenCV 函数库 ( 参考:OpenCV 函数库 )。
对象追踪的八种算法
OpenCV 提供了八种对象追踪的算法,算法的速度和精准度如下表所示:
| 算法 | 速度 | 精准度 | 说明 |
|---|---|---|---|
| BOOSTING | 慢 | 差 | 元老级追踪器,速度较慢,并且不是很准确。 |
| MIL | 慢 | 差 | 比 BOOSTING 更精确,但仍然不是很准确。 |
| GOTURN | 中 | 中 | 需要搭配深度运算模型才能运作的追踪器。 |
| TLD | 中 | 中 | 速度普通,精准度普通的追踪器。 |
| MEDIANFLOW | 中 | 中 | 对于会跳动或快速移动的对象,判断不是很准确。 |
| KCF | 快 | 高 | 不错的追踪器,但在对象被遮蔽的状态下不是很准确。 |
| MOSSE | 最快 | 高 | 速度最快,但精准度比 KCF 和 CSRT 稍差。 |
| CSRT | 快 | 最高 | 精准度比 KCF 好,但速度比 KCF 慢。 |
使用 Python 时创建追踪器的语法如下:
| 算法 | 创建语法 |
|---|---|
| BOOSTING | cv2.TrackerBoosting_create() |
| MIL | cv2.TrackerMIL_create() |
| GOTURN | cv2.TrackerGOTURN_create() |
| TLD | cv2.TrackerTLD_create() |
| MEDIANFLOW | cv2.TrackerMedianFlow_create() |
| KCF | cv2.TrackerKCF_create() |
| MOSSE | cv2.TrackerMOSSE_create() |
| CSRT | cv2.TrackerCSRT_create() |
cv2.selectROI 选取特定区域
要进行对象追踪,必须先选取特定区域,OpenCV 内建 cv2.selectROI 方法可以进行选取的功能,使用方法如下:
area = cv2.selectROI('視窗名稱', frame, showCrosshair=False, fromCenter=False)
# area:(x, y, width, height)
# frame:要選取的影像
# showCrosshair:選取框中間是否要有十字線,預設 True
# fromCenter:True 中心點選取,False 右上角選取
下方的程序码执行后,按下键盘按键 a 就会进入选取模式,此时摄影机画面会暂停,使用鼠标拖拉选取后,按下 enter 键,就会回传 xy 座标以及长宽尺寸。
import cv2
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
ret, frame = cap.read()
if not ret:
print("Cannot receive frame")
break
keyName = cv2.waitKey(1)
# 按下 q 結束
if keyName == ord('q'):
break
# 按下 a 開始選取
if keyName == ord('a'):
# 選取區域
area = cv2.selectROI('oxxostudio', frame, showCrosshair=False, fromCenter=False)
print(area)
cv2.imshow('oxxostudio', frame)
cap.release()
cv2.destroyAllWindows()
即时追踪画面中的特定物体
透过 cv2.selectROI 方法取得区域位置和尺寸后,将位置和尺寸提交给透过 cv2.TrackerCSRT_create() 所创建的追踪器,搭配 tracker.init 追踪器初始化以及 tracker.update 追踪器更新的方法,就能即时追踪画面中的特定物体。
下方的程序码执行后,视窗中会看见摄影机的即时图像,按下键盘的 a 后图像会暂停,进入截取模式,透过鼠标拖曳出要追踪的对象区域,按下 Enter 后就会出现红色追踪外框,开始追踪特定的对象。
import cv2
tracker = cv2.TrackerCSRT_create() # 創建追蹤器
tracking = False # 設定 False 表示尚未開始追蹤
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
ret, frame = cap.read()
if not ret:
print("Cannot receive frame")
break
frame = cv2.resize(frame,(540,300)) # 縮小尺寸,加快速度
keyName = cv2.waitKey(1)
if keyName == ord('q'):
break
if keyName == ord('a'):
area = cv2.selectROI('oxxostudio', frame, showCrosshair=False, fromCenter=False)
tracker.init(frame, area) # 初始化追蹤器
tracking = True # 設定可以開始追蹤
if tracking:
success, point = tracker.update(frame) # 追蹤成功後,不斷回傳左上和右下的座標
if success:
p1 = [int(point[0]), int(point[1])]
p2 = [int(point[0] + point[2]), int(point[1] + point[3])]
cv2.rectangle(frame, p1, p2, (0,0,255), 3) # 根據座標,繪製四邊形,框住要追蹤的物件
cv2.imshow('oxxostudio', frame)
cap.release()
cv2.destroyAllWindows()
微信扫码关注
抖音扫码关注