跳转至内容

使用 Ultralytics YOLO 进行多目标跟踪

多目标跟踪示例

视频分析领域中的目标跟踪是一项关键任务,它不仅能识别帧内目标的位置和类别,还能在视频播放过程中为每个检测到的目标维护一个唯一的 ID。其应用范围非常广泛,从监控和安全到实时体育分析,无所不及。

为什么选择 Ultralytics YOLO 进行对象跟踪?

Ultralytics 跟踪器的输出与标准目标检测一致,但增加了目标 ID 的价值。这使得在视频流中跟踪目标并执行后续分析变得容易。以下是您应考虑使用 Ultralytics YOLO 来满足您的目标跟踪需求的原因:

  • 效率: 实时处理视频流,且不影响准确性
  • 灵活性: 支持多种跟踪算法和配置。
  • 易用性: 简单的 python API 和 CLI 选项,可快速集成和部署。
  • 可定制性: 易于与自定义训练的 YOLO 模型一起使用,从而可以集成到特定领域的应用程序中。



观看: 使用 Ultralytics YOLO 进行目标检测和跟踪。

实际应用

运输 零售业 水产养殖
车辆追踪 行人追踪 鱼类追踪
车辆追踪 行人追踪 鱼类追踪

功能概览

Ultralytics YOLO 扩展了其目标检测功能,以提供强大而通用的目标跟踪:

  • 实时跟踪: 无缝跟踪高帧率视频中的目标。
  • 多跟踪器支持: 从各种已建立的跟踪算法中进行选择。
  • 可定制的跟踪器配置: 通过调整各种参数来定制跟踪算法,以满足特定要求。

可用跟踪器

Ultralytics YOLO 支持以下跟踪算法。可以通过传递相关的 YAML 配置文件(例如 tracker=tracker_type.yaml:

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

默认跟踪器是 BoT-SORT。

跟踪

要在视频流上运行跟踪器,请使用经过训练的检测、分割或姿势估计模型,例如YOLO11n、YOLO11n-seg 和 YOLO11n-pose。

示例

from ultralytics import YOLO

# Load an official or custom model
model = YOLO("yolo11n.pt")  # Load an official Detect model
model = YOLO("yolo11n-seg.pt")  # Load an official Segment model
model = YOLO("yolo11n-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
# Perform tracking with various models using the command line interface
yolo track model=yolo11n.pt source="https://youtu.be/LNwODJXcvt4"      # Official Detect model
yolo track model=yolo11n-seg.pt source="https://youtu.be/LNwODJXcvt4"  # Official Segment model
yolo track model=yolo11n-pose.pt source="https://youtu.be/LNwODJXcvt4" # Official Pose model
yolo track model=path/to/best.pt source="https://youtu.be/LNwODJXcvt4" # Custom trained model

# Track using ByteTrack tracker
yolo track model=path/to/best.pt tracker="bytetrack.yaml"

如以上用法所示,跟踪适用于在视频或流媒体源上运行的所有检测、分割和姿势估计模型。

配置

跟踪参数

跟踪配置与 Predict 模式共享属性,例如 conf, ioushow。有关更多配置,请参阅 预测 模型页面。

示例

from ultralytics import YOLO

# Configure the tracking parameters and run the tracker
model = YOLO("yolo11n.pt")
results = model.track(source="https://youtu.be/LNwODJXcvt4", conf=0.3, iou=0.5, show=True)
# Configure tracking parameters and run the tracker using the command line interface
yolo track model=yolo11n.pt source="https://youtu.be/LNwODJXcvt4" conf=0.3, iou=0.5 show

跟踪器选择

Ultralytics 还允许您使用修改后的跟踪器配置文件。为此,只需复制一个跟踪器配置文件(例如, custom_tracker.yaml),从 ultralytics/cfg/trackers 并根据您的需求修改任何配置(除了 tracker_type)。

示例

from ultralytics import YOLO

# Load the model and run the tracker with a custom configuration file
model = YOLO("yolo11n.pt")
results = model.track(source="https://youtu.be/LNwODJXcvt4", tracker="custom_tracker.yaml")
# Load the model and run the tracker with a custom configuration file using the command line interface
yolo track model=yolo11n.pt source="https://youtu.be/LNwODJXcvt4" tracker='custom_tracker.yaml'

有关每个参数的详细说明,请参阅追踪器参数部分。

跟踪器参数

可以通过编辑特定于每种跟踪算法的 YAML 配置文件来微调某些跟踪行为。这些文件定义了阈值、缓冲区和匹配逻辑等参数:

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

跟踪器阈值信息

如果目标置信度得分较低,即低于 track_high_thresh,则不会成功返回和更新任何轨迹。

参数 有效值或范围 描述
tracker_type botsort, bytetrack 指定跟踪器类型。选项包括 botsortbytetrack.
track_high_thresh 0.0-1.0 跟踪期间第一次关联使用的阈值。 影响检测与现有轨迹匹配的置信度。
track_low_thresh 0.0-1.0 跟踪期间第二次关联使用的阈值。 在第一次关联失败时使用,具有更宽松的标准。
new_track_thresh 0.0-1.0 如果检测结果与现有跟踪不匹配,则使用此阈值初始化新跟踪。用于控制何时认为新对象出现。
track_buffer >=0 用于指示在移除丢失的跟踪之前应保持活动状态的帧数的缓冲区。值越高,对遮挡的容忍度越高。
match_thresh 0.0-1.0 匹配轨迹的阈值。 值越高,匹配越宽松。
fuse_score True, False 确定在匹配之前是否将置信度分数与 IoU 距离融合。有助于在关联时平衡空间和置信度信息。
gmc_method orb, sift, ecc, sparseOptFlow, None 用于全局运动补偿的方法。有助于解决摄像机移动问题,从而改善跟踪效果。
proximity_thresh 0.0-1.0 与 ReID(重新识别)有效匹配所需的最小 IoU。确保空间上的接近性,然后再使用外观线索。
appearance_thresh 0.0-1.0 ReID 所需的最小外观相似度。设置两个检测结果在视觉上必须有多相似才能被链接。
with_reid True, False 指示是否使用 ReID。启用基于外观的匹配,以便在遮挡情况下更好地进行跟踪。仅 BoTSORT 支持。
model auto, yolo11[nsmlx]-cls.pt 指定要使用的模型。默认为 auto,如果检测器是 YOLO,则使用原生特征,否则使用 yolo11n-cls.pt.

启用 Re-Identification (ReID)

默认情况下,ReID 处于关闭状态,以最大限度地减少性能开销。 启用它很简单,只需设置 with_reid: True跟踪器配置。您还可以自定义 model 用于 ReID,允许您根据用例权衡准确性和速度:

  • 原生功能 (model: auto):这利用了 YOLO 检测器的直接特征来进行 ReID,增加的开销极少。当您需要某种程度的 ReID 但不会显著影响性能时,这是理想的选择。如果检测器不支持本机特征,它会自动退回使用“”。 yolo11n-cls.pt.
  • YOLO 分类模型:您可以明确设置分类模型(例如,“”)。 yolo11n-cls.pt)用于 ReID 特征提取。这提供了更具区分性的嵌入,但由于额外的推理步骤而引入了额外的延迟。

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

导出 ReID 模型到 TensorRT

from torch import nn

from ultralytics import YOLO

# Load the classification model
model = YOLO("yolo11n-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 示例

持久化跟踪循环

这是一个使用 python 脚本, OpenCV (cv2)和 YOLO11 在视频帧上运行对象跟踪。此脚本仍然假定您已经安装了必要的软件包(opencv-pythonultralytics)。 persist=True 参数告诉跟踪器,当前图像或帧是序列中的下一个,并期望当前图像中存在来自前一个图像的跟踪。

使用跟踪的流式 for 循环

import cv2

from ultralytics import YOLO

# Load the YOLO11 model
model = YOLO("yolo11n.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 YOLO11 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("YOLO11 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 YOLO11,绘制这些轨迹是一个无缝且高效的过程。

在下面的示例中,我们将演示如何利用 YOLO11 的跟踪功能来绘制检测到的对象在多个视频帧中的移动。此脚本涉及打开一个视频文件,逐帧读取它,并利用 YOLO 模型来识别和跟踪各种对象。通过保留检测到的边界框的中心点并将它们连接起来,我们可以绘制表示被跟踪对象所遵循的路径的线条。

在多个视频帧上绘制轨迹

from collections import defaultdict

import cv2
import numpy as np

from ultralytics import YOLO

# Load the YOLO11 model
model = YOLO("yolo11n.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 YOLO11 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("YOLO11 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 ,它接受这些参数并包含主跟踪循环。此函数逐帧读取视频,运行跟踪器,并显示结果。

本例中使用了两个不同的模型: yolo11n.ptyolo11n-seg.pt,每个模型跟踪不同视频文件中的对象。视频文件在 SOURCES.

字段 daemon=True 参数中指定。 threading.Thread 这意味着一旦主程序结束,这些线程将立即关闭。然后我们使用以下代码启动线程: start() 并使用 join() 来使主线程等待,直到两个跟踪器线程都完成。

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

多线程跟踪实现

import threading

import cv2

from ultralytics import YOLO

# Define model names and video sources
MODEL_NAMES = ["yolo11n.pt", "yolo11n-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 YOLO11 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 中的“跟踪器”部分投稿!您的实际应用和解决方案对于从事跟踪任务的用户来说可能非常宝贵。

通过向此部分投稿,您有助于扩展 Ultralytics YOLO 框架中可用的跟踪解决方案的范围,为社区增加另一层功能和实用性。

要开始投稿,请参阅我们的投稿指南,以获取有关提交 Pull Request (PR) 🛠️ 的全面说明。我们很高兴看到您能带来什么!

让我们一起增强 Ultralytics YOLO 生态系统的跟踪能力 🙏!

常见问题

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

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

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

您可以通过复制现有的跟踪器配置文件(例如, custom_tracker.yaml)来自 Ultralytics 跟踪器配置目录 并根据需要修改参数来配置自定义跟踪器,但 tracker_type除外。像这样在您的跟踪模型中使用此文件:

示例

from ultralytics import YOLO

model = YOLO("yolo11n.pt")
results = model.track(source="https://youtu.be/LNwODJXcvt4", tracker="custom_tracker.yaml")
yolo track model=yolo11n.pt 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 = ["yolo11n.pt", "yolo11n-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 YOLO11 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("yolo11n.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("YOLO11 Tracking", annotated_frame)
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break
    else:
        break
cap.release()
cv2.destroyAllWindows()

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



📅 创建于 1 年前 ✏️ 更新于 2 个月前

评论