YOLO Vision 2026:

Theo dõi đa đối tượng với Ultralytics YOLO#

YOLO multi-object tracking with trajectory paths

Theo dõi đối tượng trong lĩnh vực phân tích video là một nhiệm vụ quan trọng, không chỉ xác định vị trí và lớp của đối tượng trong khung hình mà còn duy trì một ID duy nhất cho mỗi đối tượng được phát hiện khi video tiếp diễn. Các ứng dụng của nó là vô hạn—từ giám sát và an ninh cho đến phân tích thể thao theo thời gian thực.

🚀 Các Tracker mới: OC-SORT, Deep OC-SORT, FastTracker, TrackTrack

Bắt đầu từ Ultralytics YOLO v8.4.63, các thuật toán tracking mới đã có sẵn: OC-SORT, Deep OC-SORT, FastTrackerTrackTrack. Các tracker này cải thiện hiệu suất tracking nhiều đối tượng và tính nhất quán của ID.

Tại sao nên chọn Ultralytics YOLO để theo dõi đối tượng?#

Kết quả đầu ra từ các tracker của Ultralytics nhất quán với object detection tiêu chuẩn nhưng có thêm giá trị là các ID đối tượng. Điều này giúp dễ dàng track đối tượng trong các luồng video và thực hiện phân tích tiếp theo. Dưới đây là lý do bạn nên cân nhắc sử dụng Ultralytics YOLO cho các nhu cầu tracking đối tượng của mình:

  • Hiệu suất: Xử lý các luồng video theo thời gian thực mà không làm giảm độ chính xác.
  • Tính linh hoạt: Hỗ trợ nhiều thuật toán và cấu hình theo dõi.
  • Dễ sử dụng: Cung cấp API Python và các tùy chọn CLI đơn giản để tích hợp và triển khai nhanh chóng.
  • Khả năng tùy biến: Dễ dàng sử dụng với các mô hình YOLO được huấn luyện tùy chỉnh, cho phép tích hợp vào các ứng dụng chuyên biệt theo miền.


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

Các ứng dụng thực tế#

Giao thôngBán lẻNuôi trồng thủy sản
Vehicle TrackingPeople TrackingFish Tracking
Theo dõi phương tiệnTheo dõi ngườiTheo dõi cá

Bắt đầu nhanh#

Chạy tracking trên video bằng tracker BoT-SORT mặc định. Chuyển sang tracker khác bằng cách thay đổi đối số tracker.

Ví dụ
from ultralytics import YOLO

model = YOLO("yolo26n.pt")

# Default tracker (BoT-SORT)
results = model.track(source="https://youtu.be/LNwODJXcvt4", show=True)

# Switch to ByteTrack
results = model.track(source="https://youtu.be/LNwODJXcvt4", show=True, tracker="bytetrack.yaml")

Để chạy tracker trên các luồng video, hãy sử dụng model Detect, Segment, Pose hoặc OBB đã được huấn luyện như YOLO26n, YOLO26n-seg, YOLO26n-pose hoặc YOLO26n-obb. Bạn có thể huấn luyện các model tùy chỉnh cục bộ hoặc thông qua hướng dẫn huấn luyện trên đám mây của Ultralytics Platform.

Ví dụ
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

Các bộ theo dõi được hỗ trợ#

Ultralytics YOLO đi kèm với sáu tracker tích hợp sẵn. Kích hoạt một tracker bằng cách truyền tệp cấu hình YAML của nó vào đối số tracker.

Bộ theo dõiTệp cấu hìnhMô hình chuyển độngDiện mạo / ReIDBù chuyển động cameraXử lý che khuất
BoT-SORTbotsort.yamlLinear KalmanTùy chọn (with_reid)Có (sparseOptFlow / ECC)Track buffer + ReID rebinding
ByteTrackbytetrack.yamlLinear KalmanKhôngKhôngTwo-stage low-conf rescue
OC-SORTocsort.yamlObservation-centric KalmanKhôngKhôngORU, OCM, OCR re-update from last observation
Deep OC-SORTdeepocsort.yamlObservation-centric KalmanTùy chọn (with_reid)Tùy chọn (gmc_method)OC-SORT + adaptive appearance EMA
FastTrackerfasttrack.yamlLinear Kalman + rollbackKhôngKhôngKalman rollback + bbox enlargement on occlusion
TrackTracktracktrack.yamlLinear Kalman (NSA)Tùy chọn (HMIoU fallback)Có (sparseOptFlow / ECC)Iterative multi-cue association + TAI

Tôi nên sử dụng bộ theo dõi nào?#

Sử dụng quy trình này để chọn điểm bắt đầu:

  1. Cần baseline nhanh nhất, đơn giản nhất?ByteTrack (không ReID, không bù chuyển động camera, overhead tối thiểu).
  2. Cảnh quay cầm tay, drone, hoặc camera di động?BoT-SORT (mặc định; thêm bù chuyển động camera và ReID tùy chọn).
  3. Chuyển động phi tuyến tính (thể thao, khiêu vũ, rẽ đột ngột) và không cần ReID?OC-SORT (hiệu chỉnh theo quan sát mà không mất chi phí về diện mạo).
  4. Các cảnh quay camera di động đông đúc nơi hoán đổi ID là vấn đề chính?Deep OC-SORT hoặc TrackTrack (cả hai đều thêm hợp nhất diện mạo thích ứng; TrackTrack cũng thêm liên kết đa tín hiệu và triệt tiêu trùng lặp ID).
  5. Thường xuyên chồng lấp một phần trong thời gian thực, không có ngân sách cho ReID?FastTracker (biến thể ByteTrack nhận biết che khuất với Kalman rollback).

Chuyển đổi bộ theo dõi#

Truyền tên tệp cấu hình tracker vào tracker=. Tất cả các mã nguồn khác giữ nguyên.

Ví dụ
from ultralytics import YOLO

model = YOLO("yolo26n.pt")

results = model.track(source="path/to/video.mp4", tracker="bytetrack.yaml")
results = model.track(source="path/to/video.mp4", tracker="ocsort.yaml")
results = model.track(source="path/to/video.mp4", tracker="tracktrack.yaml")

Cấu hình#

Các đối số theo dõi#

Cấu hình tracking chia sẻ các thuộc tính với chế độ Predict, chẳng hạn như conf, ioushow. Để biết thêm cấu hình, hãy tham khảo trang model Predict.

Ví dụ
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)

Cấu hình bộ theo dõi tùy chỉnh#

Ultralytics cũng cho phép bạn sử dụng tệp cấu hình tracker đã sửa đổi. Để làm điều này, chỉ cần tạo một bản sao của tệp cấu hình tracker (ví dụ: custom_tracker.yaml) từ thư mục ultralytics/cfg/trackers và chỉnh sửa bất kỳ cấu hình nào (ngoại trừ tracker_type) theo nhu cầu của bạn.

Ví dụ
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")

Các đối số bộ theo dõi được chia sẻ#

Các tham số sau đây là chung cho hầu hết các tệp YAML của bộ theo dõi; không phải mọi tham số đều xuất hiện trong mọi cấu hình:

Thông tin ngưỡng bộ theo dõi

Nếu điểm độ tin cậy của một phát hiện rơi xuống dưới track_high_thresh, tracker sẽ không cập nhật đối tượng đó, dẫn đến không có track nào hoạt động.

Tham sốCác giá trị hoặc phạm vi hợp lệMô tả
tracker_typebotsort, bytetrack, ocsort, deepocsort, fasttrack, tracktrackChỉ định loại bộ theo dõi.
track_high_thresh0.0-1.0Ngưỡng cho liên kết đầu tiên. Ảnh hưởng đến độ tin cậy khi một phát hiện được khớp với một track hiện có.
track_low_thresh0.0-1.0Ngưỡng cho lần kết hợp thứ hai qua các phát hiện có độ tin cậy thấp. Đối với OC-SORT và Deep OC-SORT, điều này chỉ áp dụng khi use_byte: True.
new_track_thresh0.0-1.0Ngưỡng để khởi tạo một track mới nếu phát hiện không khớp với bất kỳ track nào hiện có.
track_buffer>=0Số khung hình mà các track bị mất vẫn được giữ lại trước khi xóa. Giá trị cao hơn nghĩa là khả năng chịu đựng che khuất tốt hơn.
match_thresh0.0-1.0Ngưỡng khớp track. Giá trị cao hơn làm cho việc khớp trở nên dễ dàng hơn.
fuse_scoreTrue, FalseCó nên kết hợp các điểm tin cậy với khoảng cách IoU trước khi khớp hay không.
gmc_methodsparseOptFlow, orb, sift, ecc, nonePhương pháp bù chuyển động toàn cục. Giúp tính đến chuyển động của camera.
proximity_thresh0.0-1.0IoU tối thiểu cần thiết cho một khớp ReID hợp lệ. Đảm bảo sự gần gũi về không gian trước khi sử dụng các tín hiệu diện mạo.
appearance_thresh0.0-1.0Độ tương đồng diện mạo tối thiểu cần thiết cho ReID.
with_reidTrue, FalseKích hoạt khớp dựa trên diện mạo để theo dõi tốt hơn khi bị che khuất. Được hỗ trợ bởi BoT-SORT, Deep OC-SORT, và TrackTrack.
modelauto hoặc đường dẫn đến một tệp đã xuấtModel ReID. auto sử dụng các đặc trưng backbone YOLO nguyên bản khi có sẵn; nếu không sẽ quay lại sử dụng yolo26n-cls.pt. Truyền một tệp .torchscript, .onnx, .engine, .openvino, … cho bộ mã hóa tùy chỉnh.

Các tham số dành riêng cho trình theo dõi (tracker)#

Mỗi thuật toán cung cấp thêm các tùy chọn bổ sung ngoài các tham số dùng chung. Xem các phần dành riêng cho từng trình theo dõi bên dưới để biết mô tả và lời khuyên tinh chỉnh, hoặc tham khảo trực tiếp các tệp cấu hình:

Bật tính năng Tái nhận dạng (ReID)#

ReID được tắt theo mặc định để giảm thiểu chi phí phát sinh. Bật tính năng này bằng cách đặt with_reid: True trong tệp cấu hình tracker.

Các tùy chọn mô hình ReID:

  • model: auto — Sử dụng các đặc trưng bộ phát hiện YOLO nguyên bản, thêm chi phí phát sinh tối thiểu. Lý tưởng khi bạn cần một số ReID mà không bị sụt giảm hiệu suất lớn. Quay lại sử dụng yolo26n-cls.pt nếu bộ phát hiện không cung cấp các đặc trưng tương thích.
  • Model ReID đã xuất — Trỏ model: đến một tệp đã xuất (.torchscript, .onnx, .engine, .openvino, v.v.) để có các embedding phân biệt tốt hơn với cái giá là một lần forward pass bổ sung cho mỗi ô cắt (crop). Bộ mã hóa được tải qua AutoBackend, do đó mọi định dạng xuất mà Ultralytics hỗ trợ đều hoạt động mà không cần thay đổi mã nguồn.

Các bộ mã hóa ONNX sẵn sàng sử dụng được phát hành cho mọi kích thước model. Đặt model: thành một trong những tên này và tệp sẽ được tải xuống tự động lần đầu tiên tracker chạy (giống như cách tải trọng số YOLO) — không cần bước xuất hoặc tải xuống thủ công nào:

# In your tracker config (e.g. tracktrack.yaml)
with_reid: True
model: yolo26n-reid.onnx # downloaded on first use; swap n→s/m/l/x for a larger encoder
Mô hìnhkích thước
(pixels)
tham số
(M)
FLOPs
(B)
YOLO26n-reid.onnx4482.82.0
YOLO26s-reid.onnx4487.56.6
YOLO26m-reid.onnx44812.420.1
YOLO26l-reid.onnx44815.325.2
YOLO26x-reid.onnx44832.755.9
ReID chỉ dành cho việc theo dõi

Hiện chỉ có sẵn các bộ mã hóa ReID ONNX cho nhánh ngoại hình của tracker. Các chế độ ReID train, valpredict, cũng như các công thức xuất ReID chuyên dụng, vẫn đang được phát triển.

Để có hiệu suất tốt hơn với một mô hình phân loại riêng biệt, hãy xuất nó sang một backend nhanh hơn như TensorRT:

Xuất mô hình ReID sang 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", quantize=16, dynamic=True, batch=32)

Sau khi xuất xong, hãy trỏ đến đường dẫn mô hình TensorRT trong cấu hình trình theo dõi của bạn.

Chi tiết về trình theo dõi#

Mở rộng các phần bên dưới để xem thiết kế, các tham số cụ thể và mẹo tinh chỉnh cho từng trình theo dõi.

BoT-SORT#

BoT-SORT (Aharon et al., 2022) là tracker mặc định. Nó mở rộng ByteTrack bằng tính năng bù chuyển động của camera và ReID tùy chọn:

  • Bù trừ chuyển động camera (CMC): một phép biến đổi affine được ước tính cho mỗi khung hình (mặc định là luồng quang học thưa; ORB / ECC cũng khả dụng) được áp dụng cho các trạng thái Kalman trước khi khớp IoU.
  • ReID tùy chọn: các embedding ngoại hình có thể được kết hợp vào ma trận chi phí. Mặc định là tắt; bật bằng with_reid: True.

Tốt nhất cho: theo dõi đa mục đích, đặc biệt là với camera di động. Chỉ thêm ReID khi các nhóm đối tượng trông giống nhau gây ra tình trạng hoán đổi ID.

Các tham số dành riêng cho BoT-SORT:

Tham sốCác giá trị hoặc phạm vi hợp lệMô tả
gmc_methodsparseOptFlow, orb, sift, ecc, noneBackend bù chuyển động của camera (CMC). sparseOptFlow là mặc định. none tắt CMC.
with_reidTrue, FalseBật khớp dựa trên ngoại hình. Mặc định bị tắt.
modelauto hoặc đường dẫn đến model ReIDModel ReID. auto sử dụng các đặc trưng YOLO nguyên bản khi có sẵn; nếu không, hãy truyền đường dẫn .torchscript / .onnx / .engine.
proximity_thresh0.0-1.0IoU tối thiểu trước khi các tính năng ngoại hình được xem xét.
appearance_thresh0.0-1.0Độ tương đồng cosine tối thiểu cần thiết cho một khớp ReID. Tăng giá trị này để giảm tình trạng hoán đổi định danh.

Mẹo tinh chỉnh:

  • Camera tĩnh: đặt gmc_method: none để tiết kiệm một vài ms/khung hình.
  • Chuyển động camera mạnh: giữ nguyên sparseOptFlow; ecc chính xác hơn nhưng chậm hơn.
  • Đám đông trông giống nhau: bật with_reid: True và tăng appearance_thresh (ví dụ: 0.85+).

ByteTrack#

ByteTrack (Zhang et al., ECCV 2022) là cơ sở tối ưu trọng lượng nhẹ. Nó sử dụng Kalman tuyến tính + IoU với sự kết hợp hai giai đoạn:

  • Giai đoạn 1: khớp các phát hiện có điểm tin cậy cao với các dấu vết (track) đang hoạt động.
  • Giai đoạn 2: thử lại các dấu vết chưa khớp với các phát hiện có điểm tin cậy thấp để phục hồi thông qua việc bị che khuất một phần trong thời gian ngắn.

Không có mô hình ngoại hình và không có bù trừ chuyển động camera.

Tốt nhất cho: camera tĩnh hoặc gần như tĩnh, nơi chi phí của bộ dò là chủ đạo và bạn muốn chi phí xử lý của trình theo dõi ở mức tối thiểu.

Các đối số dành riêng cho ByteTrack: Không có ngoài các đối số tracker chung.

Mẹo tinh chỉnh:

  • Bộ phát hiện nhiều nhiễu: giảm track_low_thresh để giai đoạn thứ hai có nhiều ứng cử viên hơn.
  • Bộ phát hiện thu hồi cao: tăng track_high_thresh để giảm ID bị phân mảnh.
  • ID nhấp nháy thường xuyên: tăng track_buffer để các track bị bỏ lỡ trong thời gian ngắn vẫn có thể tồn tại.

OC-SORT#

OC-SORT (Cao et al., CVPR 2023) là một phần mở rộng tập trung vào quan sát của SORT. Nó giữ lại thiết kế nhẹ của SORT (không có đặc trưng ngoại hình) và thêm ba bản sửa lỗi:

  • Cập nhật lại dựa trên quan sát (ORU): phát lại một quỹ đạo ảo giữa quan sát cuối cùng và phát hiện hiện tại, chạy lại cập nhật Kalman để sửa lỗi vận tốc bị trôi.
  • Động lượng dựa trên quan sát (OCM): phạt các phát hiện di chuyển sai hướng thông qua một thành phần nhất quán vận tốc.
  • Phục hồi dựa trên quan sát (OCR): kiểm tra lại các phát hiện chưa khớp so với các dấu vết bị mất gần đây bằng cách sử dụng quan sát cuối cùng thay vì trạng thái dự đoán.

Tốt nhất cho: chuyển động phi tuyến tính mà không cần chi phí của mô hình ReID.

Các tham số dành riêng cho OC-SORT:

Tham sốCác giá trị hoặc phạm vi hợp lệMô tả
delta_t>=1Cửa sổ thời gian (khung hình) để tính toán hướng vận tốc trong OCM. Các giá trị lớn hơn sẽ làm mượt hơn.
inertia0.0-1.0Trọng số của chi phí nhất quán vận tốc. Các giá trị cao hơn sẽ phạt các thay đổi hướng đột ngột.
use_byteTrue, FalseBật lượt liên kết thứ hai theo kiểu ByteTrack đối với các phát hiện có độ tin cậy thấp.

Mẹo tinh chỉnh:

  • Chuyển động phi tuyến tính: tăng inertia (ví dụ: 0.3-0.4).
  • Phát hiện thưa thớt: bật use_byte: True.
  • Bị che khuất lâu: tăng track_buffer để OCR có nhiều track bị mất hơn để liên kết lại.

Deep OC-SORT#

Deep OC-SORT bổ sung cho OC-SORT thông tin ngoại hình và tính năng bù chuyển động camera:

  • Hợp nhất ngoại hình thích ứng: các embedding phát hiện được hợp nhất vào ma trận chi phí với trọng số được điều chỉnh theo độ tin cậy của phát hiện và sự chồng lấp.
  • EMA ngoại hình động: các embedding của dấu vết cập nhật với một EMA có hệ số làm mượt thích ứng với độ tin cậy của phát hiện.
  • Bù trừ chuyển động camera: các trạng thái Kalman được biến đổi giữa các khung hình thông qua luồng quang học thưa, ORB hoặc ECC.

Tốt nhất cho: các cảnh đông đúc hoặc cảnh quay bằng camera di chuyển, nơi việc hoán đổi ID giữa các đối tượng khác biệt về mặt thị giác nhưng gần nhau về không gian là phổ biến.

Các tham số dành riêng cho Deep OC-SORT:

Tham sốCác giá trị hoặc phạm vi hợp lệMô tả
with_reidTrue, FalseBật khớp dựa trên ngoại hình. Mặc định bị tắt.
modelauto, tệp model ReID đã xuấtModel ReID. auto tái sử dụng các đặc trưng YOLO nguyên bản; nếu không, hãy truyền một tệp đã xuất (.torchscript, .onnx, .engine, …).
proximity_thresh0.0-1.0IoU tối thiểu trước khi các tính năng ngoại hình được xem xét.
appearance_thresh0.0-1.0Độ tương đồng cosine tối thiểu cần thiết cho một khớp ReID.
alpha_fixed_emb0.0-1.0Hệ số EMA cơ sở cho cập nhật embedding của dấu vết. Các giá trị cao hơn giữ lại embedding cũ lâu hơn.
gmc_methodsparseOptFlow, orb, sift, ecc, nonePhương pháp bù trừ chuyển động toàn cục.
delta_t>=1Cửa sổ thời gian (khung hình) để tính toán hướng vận tốc trong OCM (được kế thừa từ OC-SORT).
inertia0.0-1.0Trọng số của chi phí nhất quán vận tốc (được kế thừa từ OC-SORT).
use_byteTrue, FalseBật lượt liên kết thứ hai theo kiểu ByteTrack đối với các phát hiện có độ tin cậy thấp (được kế thừa từ OC-SORT).

Mẹo tinh chỉnh:

  • Đổi ID trong đám đông: tăng appearance_thresh (ví dụ: 0.92-0.95) và giảm alpha_fixed_emb để các embedding thích ứng chậm hơn.
  • Camera di chuyển: đặt gmc_method: sparseOptFlow (Deep OC-SORT mặc định là none).
  • Độ trễ thấp hơn: giữ nguyên with_reid: False (mặc định) chỉ dành cho chuyển động + CMC; chỉ bật ReID khi việc đổi ID chiếm ưu thế trong các lỗi.

FastTracker#

FastTracker là một biến thể ByteTrack nhận thức sự che khuất không có model ngoại hình:

  • Phát hiện che khuất: đánh dấu các track bị che khuất khi mức độ che phủ bởi các track hoạt động khác vượt quá occ_cover_thresh.
  • Cuộn ngược Kalman khi bị che khuất: cuộn trạng thái Kalman ngược lại về khung hình trước khi bị che khuất bằng cách sử dụng lịch sử vùng đệm vòng.
  • Giảm chuyển động và mở rộng tìm kiếm: vận tốc bị giảm và bbox dự đoán được mở rộng trong khi bị che khuất.
  • Triệt tiêu Init-IoU: ngăn chặn các dấu vết mới sinh ra trên đầu các dấu vết đang hoạt động.

Tốt nhất cho: các pipeline chỉ phát hiện thời gian thực với sự chồng lấp mục tiêu thường xuyên (đám đông, hàng đợi, thể thao).

Các tham số dành riêng cho FastTracker:

Tham sốCác giá trị hoặc phạm vi hợp lệMô tả
reset_velocity_offset_occ>=0Các khung hình lịch sử quay lại để khôi phục vận tốc Kalman khi bắt đầu bị che khuất.
reset_pos_offset_occ>=0Các khung hình lịch sử quay lại để khôi phục vị trí Kalman khi bắt đầu bị che khuất.
enlarge_bbox_occ>=1.0Tỷ lệ chiều cao áp dụng cho bbox dự đoán trong khi bị che khuất (chiều rộng tỷ lệ theo tỷ lệ khung hình XYAH).
dampen_motion_occ0.0-1.0Hệ số nhân vận tốc trong khi bị che khuất. Các giá trị thấp hơn làm cho dấu vết "chậm lại" khi xuyên qua vùng che khuất.
active_occ_to_lost_thresh>=1Số khung hình bị che khuất liên tiếp tối đa trước khi một dấu vết đang hoạt động được chuyển sang trạng thái mất.
occ_cover_thresh0.0-1.0Tỷ lệ diện tích của một track bị che khuất bởi một track đang hoạt động khác để xác định trạng thái bị che khuất.
occ_reappear_window>=0Số khung hình mà một track bị mất do che khuất gần đây sẽ được ưu tiên giữ lại để tìm kiếm lại.
init_iou_suppress0.0-1.0Ngăn chặn khởi tạo track mới nếu IoU của nó với bất kỳ track hoạt động nào vượt quá mức này. Đặt thành 1.0 để tắt.

Mẹo tinh chỉnh:

  • Che khuất một phần thường xuyên: giảm occ_cover_thresh (ví dụ: 0.5-0.6).
  • ID trùng lặp xung quanh vùng chồng chéo: giảm init_iou_suppress (ví dụ: 0.5).
  • Bị che khuất lâu: tăng đồng thời occ_reappear_windowtrack_buffer.
  • Mục tiêu di chuyển nhanh: tăng dampen_motion_occ (gần với 1.0) và giảm enlarge_bbox_occ.

TrackTrack#

TrackTrack (Shim et al., CVPR 2025) suy luận từ góc độ của từng track với sự kết hợp lặp đi lặp lại đa dấu hiệu:

  • Association dựa trên góc nhìn Track (TPA): kết hợp HMIoU, khoảng cách ReID cosine, khoảng cách dự báo độ tin cậy và khoảng cách góc góc khung hình. Việc gán được giải quyết lặp lại với ngưỡng nới lỏng.
  • Khởi tạo nhận thức Track (TAI): ngăn chặn việc sinh ra track trùng lặp trước khi một ID mới được tạo.

Tốt nhất cho: các cảnh đông đúc có sự che khuất thường xuyên, nơi ID trùng lặp là một vấn đề.

Các tham số cụ thể của TrackTrack:

Tham sốCác giá trị hoặc phạm vi hợp lệMô tả
iou_weight0.0-1.0Trọng số của khoảng cách HMIoU trong ma trận chi phí đa tín hiệu.
reid_weight0.0-1.0Trọng số của khoảng cách ReID cosine. Chuyển sang HMIoU nếu ReID bị vô hiệu hóa.
conf_weight0.0-1.0Trọng số của khoảng cách dự báo độ tin cậy.
angle_weight0.0-1.0Trọng số của khoảng cách góc góc khung hình.
penalty_p0.0-1.0Phạt chi phí cho các phát hiện có độ tin cậy thấp.
penalty_q0.0-1.0Phạt chi phí cho các phát hiện được khôi phục bởi NMS thứ cấp.
reduce_step0.0-1.0Độ nới lỏng ngưỡng khớp trên mỗi lần lặp.
tai_thr0.0-1.0Ngưỡng IoU cho NMS Khởi tạo Nhận thức Track (TAI).
min_track_len>=0Số lần cập nhật thành công tối thiểu trước khi một track mới được xác nhận.
lost_match_thr0.0-1.0Cổng chi phí lỏng lẻo hơn cho lượt liên kết lại track bị mất nới lỏng; 0 vô hiệu hóa tính năng này.
with_reidTrue, FalseKích hoạt khớp đặc điểm ngoại hình cosine-ReID (sử dụng các tính năng gốc của YOLO). Mặc định là Tắt.
modelauto, tệp ReIDModel ReID; auto sử dụng các đặc trưng YOLO nguyên bản, nếu không sẽ dùng tệp ReID đã xuất.
gmc_methodsparseOptFlow, orb, sift, ecc, nonePhương pháp bù trừ chuyển động toàn cục.

Mẹo tinh chỉnh:

  • Người đi bộ đông đúc: giảm tai_thr (ví dụ: 0.45) để loại bỏ bớt các bản sao được tạo ra; tăng track_buffer cho các trường hợp bị che khuất lâu hơn.
  • Camera chuyển động nhanh: giữ gmc_method: sparseOptFlow được bật.
  • Đối tượng nhỏ/nhanh: tăng nhẹ angle_weight và giảm min_track_len.
  • Chỉ kích hoạt ReID khi cần: nó làm tăng chi phí inference; đối với các trường hợp che khuất ngắn, chi phí đa tín hiệu mặc định thường là đủ.

Ví dụ với Python#



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

Vòng lặp duy trì các Track#

Dưới đây là một tập lệnh Python sử dụng OpenCV (cv2) và YOLO26 để chạy tracking đối tượng trên các khung hình video. Tập lệnh này giả định rằng các gói cần thiết (opencv-pythonultralytics) đã được cài đặt sẵn. Đối số persist=True thông báo cho tracker rằng hình ảnh hoặc khung hình hiện tại là hình ảnh tiếp theo trong một chuỗi và dự kiến sẽ có các track từ hình ảnh trước đó trong hình ảnh hiện tại.

Duy trì các track và lựa chọn tracker

Chỉ sử dụng persist=True khi truyền các khung hình liên tiếp từ cùng một luồng video tới model.track(). Điều này cho phép tracker tái sử dụng trạng thái từ các khung hình trước đó và duy trì ID track nhất quán theo thời gian. Không sử dụng persist=True trên các hình ảnh không liên quan hoặc một luồng khác, vì trạng thái track trước đó có thể bị mang theo.

Bạn cũng có thể chọn một backend tracker bằng cách truyền tệp cấu hình tracker, chẳng hạn như tracker="botsort.yaml", tracker="bytetrack.yaml" hoặc tracker="tracktrack.yaml".

Vòng lặp for stream với tính năng theo dõi
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
        # and using the BoT-SORT tracker backend
        results = model.track(frame, persist=True, tracker="botsort.yaml")

        # 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()

Xin lưu ý sự thay đổi từ model(frame) thành model.track(frame), giúp kích hoạt tracking đối tượng thay vì phát hiện đơn thuần. Tập lệnh đã chỉnh sửa này sẽ chạy tracker trên từng khung hình của video, trực quan hóa kết quả và hiển thị chúng trong một cửa sổ. Có thể thoát vòng lặp bằng cách nhấn phím 'q'.

Vẽ biểu đồ các Track theo thời gian#

Việc trực quan hóa các track đối tượng qua các khung hình liên tiếp có thể cung cấp thông tin chi tiết có giá trị về các mô hình di chuyển và hành vi của các đối tượng được phát hiện trong video. Với Ultralytics YOLO26, việc vẽ các track này là một quá trình liền mạch và hiệu quả.

Trong ví dụ sau, chúng tôi minh họa cách sử dụng khả năng theo dõi của YOLO26 để vẽ biểu đồ di chuyển của các đối tượng được phát hiện qua nhiều khung hình video. Tập lệnh này bao gồm việc mở một tệp video, đọc từng khung hình và sử dụng model YOLO để xác định và theo dõi các đối tượng khác nhau. Bằng cách giữ lại các điểm trung tâm của các hộp bao (bbox) được phát hiện và nối chúng lại, chúng ta có thể vẽ các đường đại diện cho các đường đi của các đối tượng được theo dõi.

Vẽ biểu đồ track trên nhiều khung hình video
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(list)

# 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()

Theo dõi đa luồng#

Theo dõi đa luồng cung cấp khả năng chạy theo dõi đối tượng trên nhiều luồng video cùng một lúc. Điều này đặc biệt hữu ích khi xử lý nhiều đầu vào video, chẳng hạn như từ nhiều camera giám sát, nơi việc xử lý đồng thời có thể tăng hiệu quả và hiệu suất đáng kể.

Trong tập lệnh Python được cung cấp, chúng ta sử dụng mô-đun threading của Python để chạy đồng thời nhiều phiên bản của tracker. Mỗi luồng chịu trách nhiệm chạy tracker trên một tệp video và tất cả các luồng chạy đồng thời ở chế độ nền.

Để đảm bảo rằng mỗi luồng nhận được các tham số chính xác (tệp video, model cần sử dụng và chỉ mục tệp), chúng ta định nghĩa một hàm run_tracker_in_thread chấp nhận các tham số này và chứa vòng lặp tracking chính. Hàm này đọc từng khung hình video, chạy tracker và hiển thị kết quả.

Hai model khác nhau được sử dụng trong ví dụ này: yolo26n.ptyolo26n-seg.pt, mỗi model track các đối tượng trong một tệp video khác nhau. Các tệp video được chỉ định trong SOURCES.

Tham số daemon=True trong threading.Thread có nghĩa là các luồng này sẽ được đóng ngay khi chương trình chính hoàn tất. Sau đó, chúng ta khởi động các luồng bằng start() và sử dụng join() để làm cho luồng chính chờ cho đến khi cả hai luồng tracker hoàn tất.

Cuối cùng, sau khi tất cả các luồng đã hoàn thành nhiệm vụ của mình, các cửa sổ hiển thị kết quả sẽ được đóng lại bằng cv2.destroyAllWindows().

Triển khai theo dõi đa luồng
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()

Ví dụ này có thể dễ dàng mở rộng để xử lý nhiều tệp video và model hơn bằng cách tạo thêm nhiều luồng và áp dụng cùng một phương pháp luận.

Đóng góp các Trình theo dõi mới#

Bạn có thành thạo về tracking nhiều đối tượng và đã triển khai hoặc điều chỉnh thành công một thuật toán tracking với Ultralytics YOLO không? Chúng tôi mời bạn đóng góp vào phần Trình theo dõi (Trackers) của chúng tôi tại ultralytics/cfg/trackers! Các ứng dụng và giải pháp thực tế của bạn có thể vô cùng có giá trị đối với người dùng đang làm việc với các tác vụ tracking.

Bằng cách đóng góp vào phần này, bạn giúp mở rộng phạm vi của các giải pháp theo dõi có sẵn trong hệ sinh thái Ultralytics YOLO, thêm một lớp chức năng và tiện ích mới cho cộng đồng.

Để bắt đầu đóng góp của bạn, vui lòng tham khảo Hướng dẫn Đóng góp của chúng tôi để biết hướng dẫn toàn diện về cách gửi Pull Request (PR) 🛠️. Chúng tôi rất hào hứng muốn xem những gì bạn đóng góp!

Cùng nhau, hãy nâng cao khả năng theo dõi của hệ sinh thái Ultralytics YOLO 🙏!

Câu hỏi thường gặp#

  • Tracking nhiều đối tượng trong phân tích video liên quan đến cả việc xác định đối tượng và duy trì một ID duy nhất cho mỗi đối tượng được phát hiện qua các khung hình video. Ultralytics YOLO hỗ trợ điều này bằng cách cung cấp tính năng tracking thời gian thực cùng với các ID đối tượng, hỗ trợ các tác vụ như giám sát an ninh và phân tích thể thao. Hệ thống sử dụng các tracker như BoT-SORT, ByteTrack, OC-SORT, Deep OC-SORT, FastTracker và TrackTrack, có thể được cấu hình thông qua các tệp YAML.

  • Không. Các tệp .pt chuẩn của Ultralytics lưu trữ các trọng số model YOLO, trong khi tracker được tạo tại thời điểm suy luận bằng model.track(). Các ID track phụ thuộc vào trạng thái tracker qua các khung hình liên tiếp, vì vậy một hình ảnh đơn lẻ độc lập có thể trả về các phát hiện như hộp, lớp và độ tin cậy, nhưng bản thân nó không thể tạo ra các ID tracking liên tục có ý nghĩa.

    Đối với việc triển khai, hãy đóng gói bộ phát hiện và tracker lại với nhau trong ứng dụng của bạn và gọi model.track() theo từng khung hình với persist=True khi các khung hình đến từ cùng một luồng video. Sử dụng các thể hiện model hoặc tracker riêng biệt cho các luồng không liên quan để trạng thái không bị mang theo giữa các video.

  • Bạn có thể cấu hình một tracker tùy chỉnh bằng cách sao chép một tệp cấu hình tracker hiện có (ví dụ: custom_tracker.yaml) từ thư mục cấu hình tracker của Ultralytics và chỉnh sửa các tham số theo ý muốn, ngoại trừ tracker_type. Sử dụng tệp này trong model tracking của bạn như sau:

    Ví dụ
    from ultralytics import YOLO
    
    model = YOLO("yolo26n.pt")
    results = model.track(source="https://youtu.be/LNwODJXcvt4", tracker="custom_tracker.yaml")
  • Để chạy tracking đối tượng trên nhiều luồng video cùng một lúc, bạn có thể sử dụng mô-đun threading của Python. Mỗi luồng sẽ xử lý một luồng video riêng biệt. Dưới đây là ví dụ về cách bạn có thể thiết lập điều này:

    Theo dõi đa luồng
    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()
  • Theo dõi đa đối tượng với Ultralytics YOLO có vô số ứng dụng, bao gồm:

    • Giao thông: Tracking phương tiện để quản lý giao thông và lái xe tự động.
    • Bán lẻ: Theo dõi người để phân tích trong cửa hàng và bảo mật.
    • Nuôi trồng thủy sản: Theo dõi cá để giám sát môi trường thủy sinh.
    • Phân tích thể thao: Theo dõi người chơi và thiết bị để phân tích hiệu suất.
    • Hệ thống An ninh: Giám sát các hoạt động đáng ngờ và tạo cảnh báo an ninh.

    Những ứng dụng này được hưởng lợi từ khả năng xử lý các video có tốc độ khung hình cao trong thời gian thực với độ chính xác vượt trội của Ultralytics YOLO.

  • Để trực quan hóa các track đối tượng qua nhiều khung hình video, bạn có thể sử dụng các tính năng theo dõi của model YOLO cùng với OpenCV để vẽ đường đi của các đối tượng được phát hiện. Đây là một tập lệnh ví dụ minh họa điều này:

    Vẽ biểu đồ track trên nhiều khung hình video
    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(list)
    
    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()

    Tập lệnh này sẽ vẽ các đường theo dõi cho thấy lộ trình di chuyển của các đối tượng được theo dõi theo thời gian, cung cấp thông tin chi tiết có giá trị về hành vi và mô hình của đối tượng.

Bình luận