计算机视觉——基于YOLOv8 BotSort 与 ByteTrack实现目标追踪的对比

概述

计算机视觉领域正在迅速发展,不仅影响现实世界中的挑战,还推动了人工智能其他领域(如自然语言处理)的进步。随着计算机视觉中不断涌现的新概念,当解决现实问题时,持续的目标跟踪几乎变得至关重要。


Ultralytics YOLOv8 目标跟踪器(BotSort 与 ByteTrack)对比

目标跟踪是计算机视觉的一个基本方面,涉及在视频序列中持续识别和监控目标。它确保即使在外观和条件发生变化的情况下,也能持续跟踪目标的轨迹。各种算法,包括卡尔曼滤波器和深度学习方法,都被用于提高准确性。

一. ByteTrack 和 BotSort 与 Ultralytics YOLOv8 的使用

流行的目标跟踪算法包括 ByteTrack 和 BotSort,而 DeepSORT 在各种场景中表现出色。Ultralytics YOLOv8 提供了全面的目标跟踪功能,包括目标检测、目标分割和姿态估计等任务,所有这些都可以通过几行代码实现。

注意:请使用以下命令安装 Ultralytics 包。

pip install ultralytics

1.1 BotSort

你可以使用以下代码将 BotSort 与 YOLOv8 结合使用。通过命令行界面中的单行命令,可以轻松执行带有 BotSort 的目标跟踪。

yolo track model="path/to/best.pt" source="path/to/video.mp4"

为了绘制每个目标的跟踪线,可以使用以下代码。

import cv2
import numpy as np
from pathlib import Path
from ultralytics import YOLO
from collections import defaultdict
from ultralytics.utils.plotting import Annotator

track_history = defaultdict(lambda: [])

model = YOLO("yolov8n.pt")
names = model.model.names
video_path = "path/to/video.mp4"
if not Path(video_path).exists():
    raise FileNotFoundError(f"Source path "                            
                            f"'{video_path}' "                            
                            f"does not exist.")

cap = cv2.VideoCapture(video_path)
while cap.isOpened():
    success, frame = cap.read()
    if success:
        results = model.track(frame, persist=True)

        boxes = results[0].boxes.xywh.cpu()
        clss = results[0].boxes.cls.cpu().tolist()
        track_ids = results[0].boxes.id.int().cpu().tolist()

        annotator = Annotator(frame, line_width=2,
                              example=str(names))
        for box, track_id, cls in zip(boxes, track_ids, clss):
            x, y, w, h = box
            x1, y1, x2, y2 = (x - w / 2, y - h / 2,
                              x + w / 2, y + h / 2)
            label = str(names[cls]) + " : " + str(track_id)
            annotator.box_label([x1, y1, x2, y2],
                                label, (218, 100, 255))
            # 绘制跟踪线
            track = track_history[track_id]
            track.append((float(box[0]), float(box[1])))
            if len(track) > 30:
                track.pop(0)

            points = np.hstack(track).astype(np.int32).reshape((-1, 1, 2))
            cv2.polylines(frame, [points], isClosed=False,
                          color=(37, 255, 225), thickness=2)
            # 绘制中心圆
            cv2.circle(frame,
                       (int(track[-1][0]), int(track[-1][1])),
                       5, (235, 219, 11), -1)

        cv2.imshow("YOLOv8 Detection", frame)
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break    
    else:
        break
cap.release()
cv2.destroyAllWindows()

结果如下所示:


使用 Ultralytics YOLOv8 的 BotSort 进行目标跟踪

1.2 ByteTrack

你可以使用以下代码将 ByteTrack 与 YOLOv8 结合使用。

yolo track model=path/to/best.pt tracker="bytetrack.yaml" source=0

为了绘制每个目标的跟踪线,可以使用以下代码。

import cv2
import numpy as np
from pathlib import Path
from ultralytics import YOLO
from collections import defaultdict
from ultralytics.utils.plotting import Annotator

track_history = defaultdict(lambda: [])

model = YOLO("yolov8n.pt")
model.to("cpu")
names = model.model.names
video_path = "G:vidpose.mp4"
if not Path(video_path).exists():
    raise FileNotFoundError(f"Source path "                            
                            f"'{video_path}' "                            
                            f"does not exist.")

cap = cv2.VideoCapture(video_path)
while cap.isOpened():
    success, frame = cap.read()
    if success:
        results = model.track(frame, persist=True,
                              tracker="bytetrack.yaml")

        boxes = results[0].boxes.xywh.cpu()
        clss = results[0].boxes.cls.cpu().tolist()
        track_ids = results[0].boxes.id.int().cpu().tolist()

        annotator = Annotator(frame, line_width=2,
                              example=str(names))
        for box, track_id, cls in zip(boxes, track_ids, clss):
            x, y, w, h = box
            x1, y1, x2, y2 = (x - w / 2, y - h / 2,
                              x + w / 2, y + h / 2)
            label = str(names[cls]) + " : " + str(track_id)
            annotator.box_label([x1, y1, x2, y2],
                                label, (218, 100, 255))
            # 绘制跟踪线
            track = track_history[track_id]
            track.append((float(box[0]), float(box[1])))
            if len(track) > 30:
                track.pop(0)

            points = np.hstack(track).astype(np.int32).reshape((-1, 1, 2))
            cv2.polylines(frame, [points], isClosed=False,
                          color=(37, 255, 225), thickness=2)
            # 绘制中心圆
            cv2.circle(frame,
                       (int(track[-1][0]), int(track[-1][1])),
                       5, (235, 219, 11), -1)

        cv2.imshow("YOLOv8 Detection", frame)
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break    
    else:
        break
cap.release()
cv2.destroyAllWindows()

结果如下所示:


使用 Ultralytics YOLOv8 的 ByteTrack 进行目标跟踪

二. BotSort 与 ByteTrack 的对比

BotSort 和 ByteTrack 都是强大的目标跟踪算法,它们各自独特的特点使它们脱颖而出。在我们的全面对比中,我们将深入探讨两个关键指标,即速度(以每秒帧数或 FPS 衡量)和准确性,揭示它们各自的长处和性能特点。此分析旨在提供对每个算法在实时跟踪关键方面表现出色的深入理解。

2.1 速度(FPS)

在速度方面,ByteTrack 优于 BotSort。这使得 ByteTrack 能够近乎实时地运行推理。这一特性对于需要快速且响应迅速的目标跟踪的应用场景至关重要。

图 1.4:Ultralytics YOLOv8 的 BotSort 与 ByteTrack 速度(FPS)对比

2.2 准确性

尽管在各种场景中表现出色,但与 ByteTrack 相比,BotSort 在涉及 REID(再识别)和新跟踪器关联的场景中表现出更高的有效性。

在提供的图像中,突出显示的区域清晰地展示了 BotSort 与 ByteTrack 相比实现的更强关联。


Ultralytics YOLOv8 的 BotSort 与 ByteTrack 准确性对比**

三.结论

ByteTrack 和 BotSort 都是有效的目标跟踪算法。在决定采用之前,建议针对特定用例测试每种算法。

  • 如果你优先考虑速度且对准确性的影响最小,则可以选择 ByteTrack。
  • 如果你优先考虑准确性且对速度略有折衷,则可以选择 BotSort。
  • 对于再识别目的,BotSort 优于 ByteTrack。
### Bytetrack 实现方法 Bytetrack 是一种高效且易于实现的目标跟踪算法,特别适合资源受限的嵌入式设备。该算法主要依赖于目标的运动信息和外观特征来进行轨迹匹配,在复杂场景下表现出良好的鲁棒性和适应性[^2]。 #### 1. 运动预测更新 为了提高追踪效果,Bytetrack 使用卡尔曼滤波器来估计目标的位置变化趋势。当检测到新物体时,会初始化一个新的轨迹;对于已有的轨迹,则根据前一帧的状态预测当前帧中的位置,并用实际观测数据对其进行修正。 ```cpp // 初始化Kalman Filter参数设置 cv::KalmanFilter KF(4, 2, 0); KF.transitionMatrix = (Mat_<float>(4, 4) << 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1); setIdentity(KF.measurementMatrix); setIdentity(KF.processNoiseCov, Scalar::all(.01)); setIdentity(KF.measurementNoiseCov, Scalar::all(1e-1)); setIdentity(KF.errorCovPost, Scalar::all(.1)); // 预测下一时刻状态 Point predict_pt; Mat prediction = KF.predict(); predict_pt.x =(prediction.at<float>(0)); predict_pt.y =(prediction.at<float>(1)); // 更新测量值并校正预测结果 Mat measurement(2, 1, CV_32F); measurement.setTo(cv::Scalar(new_x, new_y)); KF.correct(measurement); ``` #### 2. 外观相似度计算 除了考虑空间距离外,还引入了表观特征作为辅助判断依据之一。通常采用深度学习框架预训练好的卷积神经网络提取图像块特征向量,再通过余弦距离或其他方式衡量不同实例间的差异程度。 ```python import torch.nn.functional as F from torchvision import models def compute_similarity(feat_a, feat_b): """Compute cosine similarity between two feature vectors.""" cos_sim = F.cosine_similarity(feat_a.unsqueeze(0), feat_b.unsqueeze(0)) return float(cos_sim) # Load pre-trained model and extract features from ROI regions. model = models.resnet50(pretrained=True).eval() transform = transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), ]) with torch.no_grad(): img_tensor = transform(image_crop).unsqueeze_(0) feats = model(img_tensor) ``` #### 3. 轨迹关联策略 针对多目标情况下的身份混淆问题,设计了一套有效的解决机制——匈牙利算法用于求解最优分配方案,使得总成本最小化的同时尽可能多地完成配对操作。 ```python from scipy.optimize import linear_sum_assignment cost_matrix = np.zeros((num_tracks, num_detections)) for i in range(num_tracks): for j in range(num_detections): cost_matrix[i][j] = -compute_similarity(track_features[i], detection_features[j]) \ + spatial_distance(tracks[i].position(), detections[j].bbox_center()) row_ind, col_ind = linear_sum_assignment(cost_matrix) assignments = list(zip(row_ind.tolist(), col_ind.tolist())) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知来者逆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值