日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

利用OpenCV進行對象跟蹤的示例代碼_python

作者:AI浩 ? 更新時間: 2022-04-12 編程語言

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

欄目分類
最近更新