跳至内容

多目标跟踪Ultralytics YOLO

多目标跟踪示例

视频分析领域中的物体跟踪是一项关键任务,它不仅要识别帧内物体的位置和类别,还要在视频播放过程中为每个检测到的物体保留一个唯一的 ID。从监控和安防到实时体育分析,其应用是无限的。

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

Ultralytics 追踪器的输出与标准物体检测一致,但具有物体 ID 的附加值。这样就能轻松跟踪视频流中的物体并进行后续分析。以下是您应考虑使用Ultralytics YOLO 满足对象跟踪需求的原因:

  • 效率:实时处理视频流,同时保证准确性。
  • 灵活性:支持多种跟踪算法和配置。
  • 易用性:简单的Python API 和CLI 选项可实现快速集成和部署。
  • 可定制性:易于使用定制的训练有素的YOLO 模型,可集成到特定领域的应用程序中。



观看: 利用Ultralytics YOLOv8 进行物体检测和跟踪 .

真实世界的应用

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

功能概览

Ultralytics YOLO 扩展了其物体检测功能,提供了强大的多功能物体跟踪功能:

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

可用跟踪器

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

  • BoT-SORT - 使用 botsort.yaml 以启用此跟踪器。
  • 字节跟踪 - 使用 bytetrack.yaml 以启用此跟踪器。

默认跟踪器是 BoT-SORT。

跟踪

跟踪器阈值信息

如果对象置信度得分较低,即低于 track_high_thresh则不会成功返回和更新轨道。

要在视频流中运行跟踪器,可使用训练有素的检测、分割或姿势模型,如YOLOv8n,YOLOv8n-seg 和YOLOv8n-pose。

示例

from ultralytics import YOLO

# Load an official or custom model
model = YOLO("yolov8n.pt")  # Load an official Detect model
model = YOLO("yolov8n-seg.pt")  # Load an official Segment model
model = YOLO("yolov8n-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=yolov8n.pt source="https://youtu.be/LNwODJXcvt4"  # Official Detect model
yolo track model=yolov8n-seg.pt source="https://youtu.be/LNwODJXcvt4"  # Official Segment model
yolo track model=yolov8n-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"

从上述用法中可以看出,在视频或流媒体源上运行的所有 Detect、Segment 和 Pose 模型都可以进行跟踪。

配置

跟踪器阈值信息

如果对象置信度得分较低,即低于 track_high_thresh则不会成功返回和更新轨道。

跟踪参数

跟踪配置与预测模式共享属性,例如 conf, ioushow.有关进一步配置,请参阅 预测 模型页。

示例

from ultralytics import YOLO

# Configure the tracking parameters and run the tracker
model = YOLO("yolov8n.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=yolov8n.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("yolov8n.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=yolov8n.pt source="https://youtu.be/LNwODJXcvt4" tracker='custom_tracker.yaml'

有关跟踪参数的完整列表,请参阅ultralytics/cfg/trackers页面。

Python 实例

持续轨迹循环

Python 以下是使用 OpenCV (cv2)和YOLOv8 在视频帧上运行对象跟踪。本脚本仍假设您已安装了必要的软件包 (opencv-pythonultralytics).("")。 persist=True 参数告诉跟踪器当前图像或帧是序列中的下一帧,并期望在当前图像中跟踪上一帧图像的轨迹。

带跟踪功能的流式 for 循环

import cv2

from ultralytics import YOLO

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

在下面的示例中,我们将演示如何利用YOLOv8 的跟踪功能绘制多个视频帧中检测到的物体的运动轨迹。该脚本包括打开一个视频文件,逐帧读取,并利用YOLO 模型来识别和跟踪各种物体。通过保留检测到的边界框的中心点并将它们连接起来,我们就可以绘制出代表被跟踪物体运动轨迹的线条。

在多个视频帧上绘制轨迹

from collections import defaultdict

import cv2
import numpy as np

from ultralytics import YOLO

# Load the YOLOv8 model
model = YOLO("yolov8n.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 YOLOv8 tracking on the frame, persisting tracks between frames
        results = model.track(frame, persist=True)

        # Get the boxes and track IDs
        boxes = results[0].boxes.xywh.cpu()
        track_ids = results[0].boxes.id.int().cpu().tolist()

        # Visualize the results on the frame
        annotated_frame = results[0].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 90 tracks for 90 frames
                track.pop(0)

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

        # Display the annotated frame
        cv2.imshow("YOLOv8 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()

多线程跟踪

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

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

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

本例中使用了两种不同的模型: yolov8n.ptyolov8n-seg.pt,每个跟踪器跟踪不同视频文件中的对象。视频文件在 video_file1video_file2.

"(《世界人权宣言》) daemon=True 中的参数 threading.Thread 意味着这些线程将在主程序结束后立即关闭。然后,我们用 start() 并使用 join() 使主线程等待两个跟踪线程都结束。

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

带跟踪功能的流式 for 循环

import threading

import cv2

from ultralytics import YOLO


def run_tracker_in_thread(filename, model, file_index):
    """
    Runs a video file or webcam stream concurrently with the YOLOv8 model using threading.

    This function captures video frames from a given file or camera source and utilizes the YOLOv8 model for object
    tracking. The function runs in its own thread for concurrent processing.

    Args:
        filename (str): The path to the video file or the identifier for the webcam/external camera source.
        model (obj): The YOLOv8 model object.
        file_index (int): An index to uniquely identify the file being processed, used for display purposes.

    Note:
        Press 'q' to quit the video display window.
    """
    video = cv2.VideoCapture(filename)  # Read the video file

    while True:
        ret, frame = video.read()  # Read the video frames

        # Exit the loop if no more frames in either video
        if not ret:
            break

        # Track objects in frames if available
        results = model.track(frame, persist=True)
        res_plotted = results[0].plot()
        cv2.imshow(f"Tracking_Stream_{file_index}", res_plotted)

        key = cv2.waitKey(1)
        if key == ord("q"):
            break

    # Release video sources
    video.release()


# Load the models
model1 = YOLO("yolov8n.pt")
model2 = YOLO("yolov8n-seg.pt")

# Define the video files for the trackers
video_file1 = "path/to/video1.mp4"  # Path to video file, 0 for webcam
video_file2 = 0  # Path to video file, 0 for webcam, 1 for external camera

# Create the tracker threads
tracker_thread1 = threading.Thread(target=run_tracker_in_thread, args=(video_file1, model1, 1), daemon=True)
tracker_thread2 = threading.Thread(target=run_tracker_in_thread, args=(video_file2, model2, 2), daemon=True)

# Start the tracker threads
tracker_thread1.start()
tracker_thread2.start()

# Wait for the tracker threads to finish
tracker_thread1.join()
tracker_thread2.join()

# Clean up and close windows
cv2.destroyAllWindows()

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

贡献新跟踪器

您是否精通多目标跟踪,并已成功实施或改编了使用Ultralytics YOLO 的跟踪算法?我们邀请您为ultralytics/cfg/trackers 中的 Trackers 版块投稿!您在现实世界中的应用和解决方案对于从事跟踪任务的用户来说可能是无价之宝。

通过对本部分的贡献,您可以帮助扩大Ultralytics YOLO 框架内可用跟踪解决方案的范围,为社区增加另一层功能和实用性。

要启动您的贡献,请参阅我们的贡献指南,了解有关提交拉动请求 (PR) 的全面说明 🛠️。我们非常期待看到您的贡献!

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



Created 2023-11-12, Updated 2024-06-10
Authors: glenn-jocher (15), IvorZhu331 (1), Burhan-Q (1)

评论