使用 Ultralytics YOLO 进行多目标追踪

YOLO multi-object tracking with trajectory paths

视频分析领域中的目标追踪是一项关键任务,它不仅能识别帧内目标的位置和类别,还能在视频处理过程中为每个检测到的目标保持唯一的 ID。其应用范围广泛——从监控和安全到实时体育分析,不一而足。

为什么要选择 Ultralytics YOLO 进行目标追踪?

Ultralytics 追踪器的输出与标准的 object detection 一致,但增加了目标 ID 的额外价值。这使得在视频流中追踪目标并进行后续分析变得十分简单。以下是你应考虑将 Ultralytics YOLO 用于目标追踪需求的理由:

  • 高效: 实时处理视频流,且不会影响 accuracy
  • 灵活: 支持多种追踪算法和配置。
  • 易用: 简单的 Python API 和 CLI 选项,可实现快速集成与部署。
  • 可定制: 可轻松与自定义训练的 YOLO 模型配合使用,从而集成到特定领域的应用中。


Watch: How to Run Multi-Object Tracking with Ultralytics YOLO26 | BoT-SORT & ByteTrack | VisionAI 🚀

实际应用

交通运输零售水产养殖
车辆追踪人员追踪鱼类追踪
车辆追踪人员追踪鱼类追踪

功能概览

Ultralytics YOLO 扩展了其目标检测功能,提供强大且多样的目标追踪能力:

  • 实时追踪: 在高帧率视频中实现无缝目标追踪。
  • 支持多种追踪器: 从多种成熟的追踪算法中进行选择。
  • 可定制的追踪器配置: 通过调整各种参数,根据具体要求调整追踪算法。

可用追踪器

Ultralytics YOLO 支持以下追踪算法。你可以通过传递相关的 YAML 配置文件(如 tracker=tracker_type.yaml)来启用它们:

  • BoT-SORT - 使用 botsort.yaml 启用此追踪器。
  • ByteTrack - 使用 bytetrack.yaml 启用此追踪器。

默认追踪器是 BoT-SORT。

追踪

要在视频流上运行追踪器,请使用经过训练的 Detect、Segment 或 Pose 模型,例如 YOLO26n、YOLO26n-seg 或 YOLO26n-pose。你可以在本地或通过 Ultralytics Platform 在云端 GPU 上训练自定义模型。

示例
from ultralytics import YOLO

# Load an official or custom model
model = YOLO("yolo26n.pt")  # Load an official Detect model
model = YOLO("yolo26n-seg.pt")  # Load an official Segment model
model = YOLO("yolo26n-pose.pt")  # Load an official Pose model
model = YOLO("path/to/best.pt")  # Load a custom-trained model

# Perform tracking with the model
results = model.track("https://youtu.be/LNwODJXcvt4", show=True)  # Tracking with default tracker
results = model.track("https://youtu.be/LNwODJXcvt4", show=True, tracker="bytetrack.yaml")  # with ByteTrack

如上面的用法所示,追踪功能适用于在视频或流媒体源上运行的所有 Detect、Segment 和 Pose 模型。

配置

追踪参数

追踪配置与 Predict 模式共享一些属性,例如 confioushow。有关进一步的配置,请参阅 Predict 模型页面。

示例
from ultralytics import YOLO

# Configure the tracking parameters and run the tracker
model = YOLO("yolo26n.pt")
results = model.track(source="https://youtu.be/LNwODJXcvt4", conf=0.1, iou=0.7, show=True)

追踪器选择

Ultralytics also allows you to use a modified tracker configuration file. To do this, simply make a copy of a tracker config file (for example, custom_tracker.yaml) from ultralytics/cfg/trackers and modify any configurations (except the tracker_type) as per your needs.

示例
from ultralytics import YOLO

# Load the model and run the tracker with a custom configuration file
model = YOLO("yolo26n.pt")
results = model.track(source="https://youtu.be/LNwODJXcvt4", tracker="custom_tracker.yaml")

有关每个参数的详细描述,请参阅 Tracker Arguments 部分。

追踪器参数

通过编辑针对每种追踪算法的 YAML 配置文件,可以对某些追踪行为进行微调。这些文件定义了诸如阈值、缓冲区和匹配逻辑等参数:

下表提供了每个参数的描述:

追踪器阈值信息

如果检测的置信度分数低于 track_high_thresh,追踪器将不会更新该目标,导致没有活跃的轨迹。

参数有效值或范围描述
tracker_typebotsort, bytetrack指定追踪器类型。选项为 botsortbytetrack
track_high_thresh0.0-1.0用于追踪期间第一次关联的阈值。影响将检测结果与现有轨迹匹配的置信度。
track_low_thresh0.0-1.0用于追踪期间第二次关联的阈值。当第一次关联失败时使用,条件更为宽松。
new_track_thresh0.0-1.0如果检测结果未与任何现有轨迹匹配,则用于初始化新轨迹的阈值。控制何时认为出现了新目标。
track_buffer>=0用于指示丢失的轨迹在被移除前应保留的帧数。值越大,对遮挡的容忍度越高。
match_thresh0.0-1.0轨迹匹配阈值。值越高,匹配越宽松。
fuse_scoreTrue, False决定是否在匹配前将置信度分数与 IoU 距离融合。有助于在关联时平衡空间和置信度信息。
gmc_methodorb, sift, ecc, sparseOptFlow, None用于全局运动补偿的方法。有助于抵消相机移动以提高追踪效果。
proximity_thresh0.0-1.0与 ReID(重新识别)有效匹配所需的最小 IoU。在利用外观特征之前确保空间上的接近度。
appearance_thresh0.0-1.0ReID 所需的最小外观相似度。设定两个检测结果必须在视觉上有多相似才能被链接。
with_reidTrue, False指示是否使用 ReID。启用基于外观的匹配,以便在遮挡情况下实现更好的追踪。仅由 BoTSORT 支持。
modelauto, yolo26[nsmlx]-cls.pt指定要使用的模型。默认为 auto,如果检测器是 YOLO,则使用原生功能,否则使用 yolo26n-cls.pt

启用重新识别 (ReID)

By default, ReID is turned off to minimize performance overhead. Enabling it is simple—just set with_reid: True in the tracker configuration. You can also customize the model used for ReID, allowing you to trade off accuracy and speed depending on your use case:

  • 原生功能 (model: auto):这利用来自 YOLO 检测器的直接特征进行 ReID,开销最小。当你需要一定程度的 ReID 且不想显著影响性能时,这是理想选择。如果检测器不支持原生功能,它会自动回退到使用 yolo26n-cls.pt
  • YOLO 分类模型:你可以显式设置一个分类模型(例如 yolo26n-cls.pt)用于 ReID 特征提取。这提供了更具辨别力的嵌入,但由于额外的推理步骤,会引入额外的延迟。

为了获得更好的性能,特别是在使用单独的分类模型进行 ReID 时,你可以将其导出到更快的后端,例如 TensorRT:

将 ReID 模型导出到 TensorRT
from torch import nn

from ultralytics import YOLO

# Load the classification model
model = YOLO("yolo26n-cls.pt")

# Add average pooling layer
head = model.model.model[-1]
pool = nn.Sequential(nn.AdaptiveAvgPool2d((1, 1)), nn.Flatten(start_dim=1))
pool.f, pool.i = head.f, head.i
model.model.model[-1] = pool

# Export to TensorRT
model.export(format="engine", half=True, dynamic=True, batch=32)

导出后,你可以在追踪器配置中指向 TensorRT 模型路径,它将在追踪过程中被用于 ReID。

Python 示例



Watch: How to Build Interactive Object Tracking with Ultralytics YOLO | Click to Crop & Display ⚡

持久化轨迹循环

这是一个使用 OpenCV (cv2) 和 YOLO26 在视频帧上运行目标追踪的 Python 脚本。此脚本假设必要的包(opencv-pythonultralytics)已安装。persist=True 参数告诉追踪器当前图像或帧是序列中的下一帧,并期望在当前图像中出现前一图像的轨迹。

带追踪的流式 for 循环
import cv2

from ultralytics import YOLO

# Load the YOLO26 model
model = YOLO("yolo26n.pt")

# Open the video file
video_path = "path/to/video.mp4"
cap = cv2.VideoCapture(video_path)

# Loop through the video frames
while cap.isOpened():
    # Read a frame from the video
    success, frame = cap.read()

    if success:
        # Run YOLO26 tracking on the frame, persisting tracks between frames
        results = model.track(frame, persist=True)

        # Visualize the results on the frame
        annotated_frame = results[0].plot()

        # Display the annotated frame
        cv2.imshow("YOLO26 Tracking", annotated_frame)

        # Break the loop if 'q' is pressed
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break
    else:
        # Break the loop if the end of the video is reached
        break

# Release the video capture object and close the display window
cap.release()
cv2.destroyAllWindows()

请注意从 model(frame)model.track(frame) 的变化,这启用了目标追踪而不是简单的检测。这个修改后的脚本将在视频的每一帧上运行追踪器,可视化结果,并将它们显示在窗口中。按下 'q' 键可以退出循环。

绘制轨迹随时间的变化

可视化连续帧上的目标轨迹可以提供有关视频中检测到的目标运动模式和行为的宝贵见解。使用 Ultralytics YOLO26,绘制这些轨迹是一个无缝且高效的过程。

在以下示例中,我们演示了如何利用 YOLO26 的追踪能力来绘制检测到的目标在多个视频帧中的运动轨迹。此脚本涉及打开视频文件,逐帧读取它,并利用 YOLO 模型来识别和追踪各种目标。通过保留检测到的边界框的中心点并将它们连接起来,我们可以绘制出代表被追踪目标所遵循路径的线条。

在多个视频帧上绘制轨迹
from collections import defaultdict

import cv2
import numpy as np

from ultralytics import YOLO

# Load the YOLO26 model
model = YOLO("yolo26n.pt")

# Open the video file
video_path = "path/to/video.mp4"
cap = cv2.VideoCapture(video_path)

# Store the track history
track_history = defaultdict(lambda: [])

# Loop through the video frames
while cap.isOpened():
    # Read a frame from the video
    success, frame = cap.read()

    if success:
        # Run YOLO26 tracking on the frame, persisting tracks between frames
        result = model.track(frame, persist=True)[0]

        # Get the boxes and track IDs
        if result.boxes and result.boxes.is_track:
            boxes = result.boxes.xywh.cpu()
            track_ids = result.boxes.id.int().cpu().tolist()

            # Visualize the result on the frame
            frame = result.plot()

            # Plot the tracks
            for box, track_id in zip(boxes, track_ids):
                x, y, w, h = box
                track = track_history[track_id]
                track.append((float(x), float(y)))  # x, y center point
                if len(track) > 30:  # retain 30 tracks for 30 frames
                    track.pop(0)

                # Draw the tracking lines
                points = np.hstack(track).astype(np.int32).reshape((-1, 1, 2))
                cv2.polylines(frame, [points], isClosed=False, color=(230, 230, 230), thickness=10)

        # Display the annotated frame
        cv2.imshow("YOLO26 Tracking", frame)

        # Break the loop if 'q' is pressed
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break
    else:
        # Break the loop if the end of the video is reached
        break

# Release the video capture object and close the display window
cap.release()
cv2.destroyAllWindows()

多线程追踪

多线程追踪提供了同时在多个视频流上运行目标追踪的能力。当处理多个视频输入(例如来自多个监控摄像头的输入)时,这特别有用,此时并发处理可以极大地提高效率和性能。

在提供的 Python 脚本中,我们利用 Python 的 threading 模块并发运行追踪器的多个实例。每个线程负责在一个视频文件上运行追踪器,所有线程在后台同时运行。

为了确保每个线程接收到正确的参数(视频文件、要使用的模型和文件索引),我们定义了一个函数 run_tracker_in_thread,该函数接受这些参数并包含主要的追踪循环。此函数逐帧读取视频、运行追踪器并显示结果。

在此示例中使用了两个不同的模型:yolo26n.ptyolo26n-seg.pt,每个模型分别在不同的视频文件中追踪目标。视频文件在 SOURCES 中指定。

The daemon=True parameter in threading.Thread means that these threads will be closed as soon as the main program finishes. We then start the threads with start() and use join() to make the main thread wait until both tracker threads have finished.

最后,在所有线程完成任务后,使用 cv2.destroyAllWindows() 关闭显示结果的窗口。

多线程追踪实现
import threading

import cv2

from ultralytics import YOLO

# Define model names and video sources
MODEL_NAMES = ["yolo26n.pt", "yolo26n-seg.pt"]
SOURCES = ["path/to/video.mp4", "0"]  # local video, 0 for webcam

def run_tracker_in_thread(model_name, filename):
    """Run YOLO tracker in its own thread for concurrent processing.

    Args:
        model_name (str): The YOLO26 model object.
        filename (str): The path to the video file or the identifier for the webcam/external camera source.
    """
    model = YOLO(model_name)
    results = model.track(filename, save=True, stream=True)
    for r in results:
        pass

# Create and start tracker threads using a for loop
tracker_threads = []
for video_file, model_name in zip(SOURCES, MODEL_NAMES):
    thread = threading.Thread(target=run_tracker_in_thread, args=(model_name, video_file), daemon=True)
    tracker_threads.append(thread)
    thread.start()

# Wait for all tracker threads to finish
for thread in tracker_threads:
    thread.join()

# Clean up and close windows
cv2.destroyAllWindows()

通过创建更多的线程并应用相同的方法,此示例可以轻松扩展以处理更多的视频文件和模型。

贡献新的追踪器

你精通多目标跟踪,并且已经使用 Ultralytics YOLO 成功实现或适配过跟踪算法吗?我们诚邀你为 ultralytics/cfg/trackers 中的 Trackers 部分做出贡献!你的实际应用和解决方案对于正在进行跟踪任务的用户来说将非常有价值。

通过为此部分做出贡献,你可以帮助扩展 Ultralytics YOLO 框架内可用的跟踪解决方案范围,为社区增加一层额外的功能和实用性。

若要开始你的贡献,请参阅我们的 Contributing Guide,获取提交 Pull Request (PR) 的详细说明 🛠️。我们非常期待看到你带来的成果!

让我们携手提升 Ultralytics YOLO 生态系统的跟踪能力 🙏!

常见问题 (FAQ)

什么是多目标跟踪,Ultralytics YOLO 如何支持它?

视频分析中的多目标跟踪既涉及识别对象,也涉及在视频帧中为每个检测到的对象保持唯一 ID。Ultralytics YOLO 通过提供实时跟踪以及对象 ID 来支持这一点,从而促进了安防监控和体育分析等任务。该系统使用 BoT-SORTByteTrack 等跟踪器,可以通过 YAML 文件进行配置。

如何为 Ultralytics YOLO 配置自定义跟踪器?

You can configure a custom tracker by copying an existing tracker configuration file (e.g., custom_tracker.yaml) from the Ultralytics tracker configuration directory and modifying parameters as needed, except for the tracker_type. Use this file in your tracking model like so:

示例
from ultralytics import YOLO

model = YOLO("yolo26n.pt")
results = model.track(source="https://youtu.be/LNwODJXcvt4", tracker="custom_tracker.yaml")

如何同时在多个视频流上运行对象跟踪?

要在多个视频流上同时运行对象跟踪,你可以使用 Python 的 threading 模块。每个线程将处理一个单独的视频流。以下是如何设置此操作的示例:

多线程追踪
import threading

import cv2

from ultralytics import YOLO

# Define model names and video sources
MODEL_NAMES = ["yolo26n.pt", "yolo26n-seg.pt"]
SOURCES = ["path/to/video.mp4", "0"]  # local video, 0 for webcam

def run_tracker_in_thread(model_name, filename):
    """Run YOLO tracker in its own thread for concurrent processing.

    Args:
        model_name (str): The YOLO26 model object.
        filename (str): The path to the video file or the identifier for the webcam/external camera source.
    """
    model = YOLO(model_name)
    results = model.track(filename, save=True, stream=True)
    for r in results:
        pass

# Create and start tracker threads using a for loop
tracker_threads = []
for video_file, model_name in zip(SOURCES, MODEL_NAMES):
    thread = threading.Thread(target=run_tracker_in_thread, args=(model_name, video_file), daemon=True)
    tracker_threads.append(thread)
    thread.start()

# Wait for all tracker threads to finish
for thread in tracker_threads:
    thread.join()

# Clean up and close windows
cv2.destroyAllWindows()

Ultralytics YOLO 多目标跟踪有哪些实际应用?

Ultralytics YOLO 的多目标跟踪有许多应用,包括:

  • 交通: 用于交通管理和 自动驾驶 的车辆跟踪。
  • 零售: 用于店内分析和安防的人员跟踪。
  • 水产养殖: 用于监测水生环境的鱼类跟踪。
  • 体育分析: 用于性能分析的运动员和设备跟踪。
  • 安全系统: 监测可疑活动 并创建 安全警报

这些应用受益于 Ultralytics YOLO 以卓越的精度实时处理高帧率视频的能力。

如何使用 Ultralytics YOLO 可视化多视频帧上的对象轨迹?

要可视化多视频帧上的对象轨迹,你可以使用 YOLO 模型的跟踪功能结合 OpenCV 来绘制检测到的对象的路径。以下是一个演示此操作的示例脚本:

在多个视频帧上绘制轨迹
from collections import defaultdict

import cv2
import numpy as np

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
video_path = "path/to/video.mp4"
cap = cv2.VideoCapture(video_path)
track_history = defaultdict(lambda: [])

while cap.isOpened():
    success, frame = cap.read()
    if success:
        results = model.track(frame, persist=True)
        boxes = results[0].boxes.xywh.cpu()
        track_ids = results[0].boxes.id.int().cpu().tolist()
        annotated_frame = results[0].plot()
        for box, track_id in zip(boxes, track_ids):
            x, y, w, h = box
            track = track_history[track_id]
            track.append((float(x), float(y)))
            if len(track) > 30:
                track.pop(0)
            points = np.hstack(track).astype(np.int32).reshape((-1, 1, 2))
            cv2.polylines(annotated_frame, [points], isClosed=False, color=(230, 230, 230), thickness=10)
        cv2.imshow("YOLO26 Tracking", annotated_frame)
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break
    else:
        break
cap.release()
cv2.destroyAllWindows()

此脚本将绘制显示跟踪对象随时间变化的移动路径的跟踪线,从而为对象行为和模式提供有价值的见解。

评论