網站首頁 編程語言 正文
OpenCV 對象跟蹤
這篇文章使用 OpenCV 中內置的八種不同的對象跟蹤算法,實現對物體的跟蹤。
首先,介紹一下8種跟蹤算法。
然后,演示如何使用OpenCV實現這些跟蹤算法。
最后,對本文做總結。
OpenCV 對象跟蹤器
OpenCV 八種對象跟蹤器:
BOOSTING Tracker:基于用于驅動 Haar 級聯 (AdaBoost) 背后的機器學習的相同算法,但與 Haar 級聯一樣,已有十多年的歷史。這個跟蹤器很慢,而且效果不太好。僅出于遺留原因和比較其他算法而感興趣。 (最低 OpenCV 3.0.0)
MIL Tracker:比 BOOSTING 跟蹤器更準確,但在報告失敗方面做得很差。 (最低 OpenCV 3.0.0)
KCF 跟蹤器:內核化相關過濾器。比 BOOSTING 和 MIL 更快。與 MIL 和 KCF 類似,不能很好地處理完全遮擋。 (最低 OpenCV 3.1.0)
CSRT Tracker:判別相關濾波器(具有通道和空間可靠性)。往往比 KCF 更準確,但速度稍慢。 (最低 OpenCV 3.4.2)
MedianFlow Tracker:很好地報告失敗;但是,如果運動中的跳躍太大,例如快速移動的物體,或者外觀快速變化的物體,模型就會失敗。 (最低 OpenCV 3.0.0)
TLD 跟蹤器:我不確定 TLD 跟蹤器的 OpenCV 實現或實際算法本身是否存在問題,但 TLD 跟蹤器極易出現誤報。我不推薦使用這個 OpenCV 對象跟蹤器。 (最低 OpenCV 3.0.0)
MOSSE Tracker:非常非常快。不如 CSRT 或 KCF 準確,但如果您需要純粹的速度,這是一個不錯的選擇。 (最低 OpenCV 3.4.1)
GOTURN Tracker:OpenCV 中唯一基于深度學習的目標檢測器。它需要額外的模型文件才能運行(本文不會涉及)。我最初的實驗表明,盡管據說它可以很好地處理查看變化,但使用起來還是有點痛苦(盡管我最初的實驗并沒有證實這一點)。我將嘗試在以后的帖子中介紹它,但與此同時,請看一下 Satya 的文章。 (最低 OpenCV 3.2.0)
個人建議:
- 當需要更高的對象跟蹤精度并且可以容忍較慢的 FPS 吞吐量時,請使用 CSRT
- 當需要更快的 FPS 吞吐量但可以處理稍低的對象跟蹤精度時使用 KCF
- 當需要純粹的速度時使用 MOSSE
物體跟蹤
在開始算法之前,先寫輔助方法和類。
fps類:
import datetime class FPS: ?? ?def __init__(self): ?? ??? ?# 定義開始時間、結束時間和總幀數 ?? ??? ?self._start = None ?? ??? ?self._end = None ?? ??? ?self._numFrames = 0 ?? ?def start(self): ?? ??? ?# 開始計時 ?? ??? ?self._start = datetime.datetime.now() ?? ??? ?return self ?? ?def stop(self): ?? ??? ?# 停止計時 ?? ??? ?self._end = datetime.datetime.now() ?? ?def update(self): ?? ??? ?# 增加在開始和結束間隔期間檢查的總幀數 ?? ??? ?self._numFrames += 1 ?? ?def elapsed(self): ?? ??? ?# 返回開始和結束間隔之間的總秒數 ?? ??? ?return (self._end - self._start).total_seconds() ?? ?def fps(self): ?? ??? ?# 計算每秒幀數 ?? ??? ?return self._numFrames / self.elapsed()
請打開一個新文件,將其命名為 object_tracker.py ,定義resize方法,等比例縮放圖片。
import cv2 from fps import FPS def resize(image, width=None, height=None, inter=cv2.INTER_AREA): # 初始化要調整大小的圖像的尺寸并抓取圖像大小 dim = None (h, w) = image.shape[:2] # 如果寬高都為None,則返回原圖 if width is None and height is None: return image # 檢查寬度是否為None if width is None: # 計算高度的比例并構造尺寸 r = height / float(h) dim = (int(w * r), height) # 否則,高度為 None else: # 計算寬度的比例并構造尺寸 r = width / float(w) dim = (width, int(h * r)) resized = cv2.resize(image, dim, interpolation=inter) return resized
定義全局變量:
videos = 0 tracker_type = 'kcf'
我們的命令行參數包括:
videos:輸入視頻文件或者攝像頭的ID。
tracker_type:跟蹤器的類型,接下來的代碼定義了跟蹤器列表。
接下來定義不同類型的跟蹤器:
# 提取 OpenCV 版本信息 (major, minor) = cv2.__version__.split(".")[:2] # 如果我們使用 OpenCV 3.2 或之前版本,我們可以使用特殊的工廠函數來創建我們的對象跟蹤器 if int(major) == 3 and int(minor) < 3: tracker = cv2.Tracker_create(tracker_type) # 否則,對于 OpenCV 3.3 或更新版本,我們需要顯式調用對應的對象跟蹤器構造函數: else: # 初始化一個字典,將字符串映射到其對應的 OpenCV 對象跟蹤器實現 OPENCV_OBJECT_TRACKERS = { "csrt": cv2.TrackerCSRT_create, "kcf": cv2.TrackerKCF_create, "boosting": cv2.legacy.TrackerBoosting_create, "mil": cv2.TrackerMIL_create, "tld": cv2.legacy.TrackerTLD_create, "medianflow": cv2.legacy.TrackerMedianFlow_create, "mosse": cv2.legacy.TrackerMOSSE_create } # 使用我們的 OpenCV 對象跟蹤器對象字典獲取適當的對象跟蹤器 tracker = OPENCV_OBJECT_TRACKERS[tracker_type]()
在OpenCV 3.3之前,必須使用cv2.Tracker_create創建跟蹤器對象,并傳遞跟蹤器名稱的大寫字符串。
對于OpenCV 3.3+,可以使用各自的函數調用創建每個跟蹤器,例如cv2.TrackerCSRT_create。字典OPENCV_OBJECT_TRACKERS包含8個內置OpenCV對象跟蹤器中的七個。它將對象跟蹤器命令行參數字符串(鍵)與實際的OpenCV對象跟蹤器函數(值)進行映射。
# 初始化我們要追蹤的物體的邊界框坐標 initBB = None vs = cv2.VideoCapture(videos) fps = None
initBB初始化為None,此變量將保存我們使用鼠標選擇的對象的邊界框坐標。
接下來,初始化VideoCapture對象和FPS計數器。
讓我們開始循環來自視頻流的幀:
# 循環播放視頻流中的幀 while True: # 抓取當前幀。 (grabbed, frame) = vs.read() if not grabbed: break # 調整框架大小并獲取框架尺寸。 frame = resize(frame, width=500) (H, W) = frame.shape[:2] # 檢查是否正在跟蹤一個對象 if initBB is not None: # 抓取物體的新邊界框坐標 (success, box) = tracker.update(frame) # 檢查跟蹤是否成功 if success: (x, y, w, h) = [int(v) for v in box] cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) # 更新 FPS 計數器 fps.update() fps.stop() # 初始化在框架上顯示的信息集 info = [ ("Tracker", tracker_type), ("Success", "Yes" if success else "No"), ("FPS", "{:.2f}".format(fps.fps())), ] # 遍歷信息元組并將它們繪制在框架上 for (i, (k, v)) in enumerate(info): text = "{}: {}".format(k, v) cv2.putText(frame, text, (10, H - ((i * 20) + 20)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) # 顯示輸出幀 cv2.imshow("Frame", frame) key = cv2.waitKey(1) & 0xFF
抓住一個幀,如果獲取不到幀,則退出。
為了使對象跟蹤算法能夠更快地處理幀,我們將輸入幀的大小調整為500像素。
然后輸出框架的高和寬。
如果已選擇對象,則需要更新對象的位置。 update方法將定位對象的新位置并返回成功布爾值和對象的邊界框。
如果成功,我們在框架上繪制新的,更新的邊界框位置。
更新FPS。
初始化顯示的文本信息列表。隨后,繪制到frame上。
顯示輸出幀。
# 使用's'鍵選擇一個邊界框來跟蹤 if key == ord("s"): # 選擇跟蹤的對象的邊界框(選擇 ROI 后按 ENTER 或 SPACE) initBB = cv2.selectROI("Frame", frame, fromCenter=False, showCrosshair=True) # 使用提供的邊界框坐標啟動 OpenCV 對象跟蹤器,然后也啟動 FPS 吞吐量估計器 tracker.init(frame, initBB) fps = FPS().start() # 如果 `q` 鍵被按下,則退出循環 elif key == ord("q"): break vs.release() cv2.destroyAllWindows()
按下“s”鍵時,使用cv2.selectROI“選擇”對象ROI。此時,視頻幀凍結,用鼠標繪制跟蹤對象的邊界框。
繪制完邊界框,然后按“ENTER”或“SPACE”確認選擇。如果需要重新選擇區域,只需按“ESCAPE”即可。
然后,啟動OpenCV 對象跟蹤器,再啟動 FPS 吞吐量估計器。
最后一個段代碼只是處理我們已經脫離循環的情況。釋放所有指針并關閉窗口。
總結
在今天的博客文章中,您學習了如何利用OpenCV進行對象跟蹤。具體來說,我們回顧了OpenCV庫中包含的8個對象跟蹤算法(從OpenCV 3.4開始):
CSRT、KCF、Boosting、MIL、TLD、MedianFlow、MOSSE、GOTURN。
建議對大多數對象跟蹤應用程序使用CSRT,KCF或MOSSE:
當需要更高的對象跟蹤精度并且可以容忍更慢的FPS吞吐量時,請使用CSRT
當需要更快的FPS吞吐量時使用KCF,但可以處理稍低的對象跟蹤精度
當需要純粹的速度時使用MOSSE
原文鏈接:https://blog.csdn.net/hhhhhhhhhhwwwwwwwwww/article/details/122815739
相關推薦
- 2022-04-23 R語言繪制line?plot線圖示例詳解_R語言
- 2022-03-20 Android實現桌面快捷方式實例代碼_Android
- 2022-05-25 如何把自己寫的jar包打進本地maven倉庫呢(也是springboot項目怎么打成SDK)
- 2022-09-20 Python中類的mro與繼承關系詳解_python
- 2022-03-28 python?Pandas中數據的合并與分組聚合_python
- 2022-09-21 python?paramiko連接ssh實現命令_python
- 2021-11-06 C/C++?Qt?StringListModel?字符串列表映射組件詳解_C 語言
- 2022-10-20 Swift繼承Inheritance淺析介紹_Swift
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支