ByteTrack, BoT-SORT ve TrackTrack ile Nesneleri Takip Et
Her nesneye kareler boyunca kararlı bir kimlik ver, bir takipçi seç ve eşiklerini algılayıcına göre ayarla.
Her sayım, bekleme süresi ve hız tahmini tek bir soruya bağlıdır: Bu karedeki 17 numaralı kimlik, önceki karedeki 17 numaralı kimlikle aynı nesne mi? Yaklaşık 30 yayanın bulunduğu aynı 62 karelik klipte ve aynı algılayıcıyla ByteTrack 32 kimlik, varsayılan TrackTrack ise 9 kimlik buldu. Takipçiyi seçmek ve ayarlamak modelin bir parçasıdır; yanlış seçim, sonraki tüm sayıları fark ettirmeden bozar.
Uygulamalı
Bir Takipçi Ne Katar?#

Bu karedeki etiketler ve izler, takipçinin ürettiği çıktılardır. Her kimlik bir izdir; gerçek bir nesneye ilişkin bir varsayımdır ve iz, o nesnenin yakın geçmişidir. Takipçi her karede bir Kalman filtresi kullanarak her izin nerede olması gerektiğini tahmin eder, ardından yeni algılamaları bu tahminlerle kutu örtüşmesine (ve isteğe bağlı olarak görünüme) göre eşleştirir:
track_buffer kare boyunca eşleşmeyen izler silinir. Mekanizmanın tamamı budur ve sonraki her şeyi eşik değerleri belirler.
Bir Takipçi Seç#
Takip modu altı takipçiyle birlikte gelir: BoT-SORT, ByteTrack, OC-SORT, Deep OC-SORT, FastTracker ve TrackTrack (tracker parametresini geçirmezsen varsayılan). Çoğu ihtiyacı üçü karşılar:
| Takip algoritması | Eşleştirme ölçütleri (varsayılan yapılandırma) | Şu durumlarda tercih et |
|---|---|---|
| ByteTrack | Hareket ve kutu örtüşmesine ek olarak, düşük güvenli kutuları kurtaran ikinci bir eşleştirme geçişi | Sabit kameralar, küçük veya kararsız algılayıcılar; işlem hacmi önemliyse |
| BoT-SORT | ByteTrack tarzı eşleştirme ve kamera hareketi telafisi (gmc_method: sparseOptFlow) | Hareketli veya sarsılan kameralar; kalabalıklar ve uzun süreli örtülmeler için with_reid: True değerini ayarla |
| TrackTrack | Çoklu ölçüt maliyeti (kutu şekli, güven, açı), iz farkındalıklı başlatma, kamera hareketi telafisi | Güçlü ve iyi eğitilmiş bir modelden gelen yüksek güvenli algılamalar |
BoT-SORT'un görünüm eşleştirmesi (yeniden kimlik belirleme) varsayılan olarak kapalıdır; model: auto ile açıldığında algılayıcının kendi özelliklerini yeniden kullanır, bu nedenle etkinleştirmek çok az ek yük getirir.
Tek Bir Klipte Takipçileri Karşılaştır#
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
video = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"
for tracker in ("bytetrack.yaml", "botsort.yaml", "tracktrack.yaml"):
ids, frames = set(), 0
for r in model.track(video, stream=True, tracker=tracker, classes=[0], verbose=False):
frames += 1
if r.boxes.is_track:
ids.update(r.boxes.id.int().tolist())
print(f"{tracker:16s} {frames} frames, {len(ids)} unique person IDs")bytetrack.yaml 62 frames, 32 unique person IDs
botsort.yaml 62 frames, 33 unique person IDs
tracktrack.yaml 62 frames, 9 unique person IDsKlipte yaklaşık 30 kişi, yukarıdan görülen bir meydanı geçiyor; bu nedenle ByteTrack ve BoT-SORT gerçek sayıya yakın sonuç veriyor. TrackTrack bozuk değil: yalnızca new_track_thresh: 0.7 üzerindeki izleri başlatıyor ve ilk eşleştirmeyi track_high_thresh: 0.6 üzerinde yapıyor; oysa YOLO26n'nin bu klipteki kişi güven değerlerinin medyanı 0,53 ve algılamaların yalnızca %17'si 0,7'ye ulaşıyor. Çoğu kişiye hiçbir zaman kimlik verilmiyor. Karar kuralı: herhangi bir sayıya güvenmeden önce takipçi eşiklerini algılayıcının güven dağılımıyla karşılaştır.
Bir İş Hattında Kimlikleri Kullan#
from collections import defaultdict
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
video = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"
counts = defaultdict(set)
for r in model.track(video, stream=True, tracker="bytetrack.yaml", verbose=False):
if not r.boxes.is_track: # no confirmed tracks in this frame yet
continue
for cls, tid in zip(r.boxes.cls.int().tolist(), r.boxes.id.int().tolist()):
counts[r.names[cls]].add(tid)
for cls, ids in counts.items():
print(f"{cls}: {len(ids)} unique objects")person: 32 unique objectsSınıf başına bir küme, her kimliği kaç karede görünürse görünsün yalnızca bir kez sayar; böylece sonuç algılama değil, nesne sayısı olur. stream=True, videonun tamamını bellekte tutmak yerine sonuçları her seferinde bir kare için üretir. Bölge sayımı, ısı haritaları ve mesafe hesaplama, bu döngünün üzerine eklenen ince katmanlardır.
Kendin Okuduğun Kareleri Takip Et#
Bir yol veya URL verdiğinde takipçi durumunu senin yerine yönetir. Kareler kendi kod çözücünden, web kamerandan ya da RTSP kamerandan geliyorsa her çağrının aynı diziyi sürdürmesi için persist=True parametresini geçir (Tahmin modu belgelerinde tüm kaynak türleri listelenir):
import cv2
from ultralytics import YOLO
from ultralytics.utils.downloads import safe_download
model = YOLO("yolo26n.pt")
video = safe_download("https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4")
cap = cv2.VideoCapture(str(video)) # or 0 for a webcam, or an rtsp:// URL
seen = set()
while True:
ok, frame = cap.read()
if not ok:
break
r = model.track(frame, persist=True, tracker="bytetrack.yaml", classes=[0], verbose=False)[0]
if r.boxes.is_track:
seen.update(r.boxes.id.int().tolist()) # your logic: dwell time, trajectories, alerts
cap.release()
print(f"{len(seen)} unique IDs")32 unique IDsYolu parametre olarak vermekle aynı sonucu alırsın; çünkü persist=True 62 çağrının tamamında tek bir takipçiyi çalışır durumda tuttu.
Takipçiyi Algılayıcına Göre Ayarla#
Paketle birlikte gelen bir yapılandırmayı kopyala, algılayıcına uymayan eşikleri düşür ve yeni dosyayı geçir:
from pathlib import Path
from ultralytics import YOLO
from ultralytics.utils import ROOT
cfg = (ROOT / "cfg/trackers/tracktrack.yaml").read_text() # packaged defaults
for old, new in (
("track_high_thresh: 0.6", "track_high_thresh: 0.3"),
("track_low_thresh: 0.25", "track_low_thresh: 0.1"),
("new_track_thresh: 0.7", "new_track_thresh: 0.35"),
):
cfg = cfg.replace(old, new)
Path("tracktrack_tuned.yaml").write_text(cfg)
model = YOLO("yolo26n.pt")
video = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"
for tracker in ("tracktrack.yaml", "tracktrack_tuned.yaml"):
ids = set()
for r in model.track(video, stream=True, tracker=tracker, classes=[0], verbose=False):
if r.boxes.is_track:
ids.update(r.boxes.id.int().tolist())
print(f"{tracker:22s} {len(ids)} unique person IDs")tracktrack.yaml 9 unique person IDs
tracktrack_tuned.yaml 27 unique person IDsEşikleri algılayıcının medyan güven değerinin hemen altına çekmek, TrackTrack'in kimlik sayısını 9'dan 27'ye çıkardı ve elle yapılan sayımın yakınına getirdi. Her takipçinin ortak ayarları:
| Ayar | ByteTrack varsayılanı | Şu durumlarda yükselt | Şu durumlarda düşür |
|---|---|---|---|
track_high_thresh | 0.25 | İlk eşleştirmede zayıf algılamaları yok say | Düşük güvenli algılayıcıyı takip et |
new_track_thresh | 0.25 | Kısa ömürlü hatalı izleri azalt | Belirsiz nesneler için iz başlat |
track_buffer | 30 kare | Daha uzun süreli örtülmelerde izleri koru | Kadrajdan çıkan nesnelerin kimliklerini daha erken boşa çıkar |
match_thresh | 0.8 | Daha esnek eşleştir (hızlı hareket, sıçrayan kutular) | Daha katı eşleştir (kalabalıklar) |
Yaygın Hatalar#
Belirti: Özellikle küçük bir modelle nesne sayısına kıyasla çok daha az ID var. Çözüm: Tespit güveninin medyanını yazdır (çözüme bak) ve new_track_thresh ile track_high_thresh değerlerini bu medyanın hemen altına ayarla.
Belirti: model.track(frame) işlevini kendin çağırdığında her karede ID'ler sıfırlanıyor veya iki kamera tek bir modele görüntü verdiğinde ID'ler nesneler arasında geçiş yapıyor. Çözüm: Tek bir akışın ardışık kareleri için persist=True değerini aktar ve her kameraya kendi model örneğini ver (veya her akış için bir izleyici tutan .streams kaynağını kullan).
Belirti: Park hâlindeki bir arabanın ID'si birkaç karede bir değişiyor. Çözüm: İzleyici, eski izlerle eşleştirmek yerine yeni izler başlatıyor. Önce dedektörün o nesne için güven değerini kontrol et, ardından match_thresh ve track_buffer değerlerini yükselt.
Çözümü göster
Önce algılayıcının güven değerlerini ölç, ardından eşikleri bu değerlerin hemen altına ayarla:
import torch
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
video = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"
conf = torch.cat([r.boxes.conf for r in model.predict(video, stream=True, classes=[0], verbose=False)])
print(f"median {conf.median():.2f}, share >= 0.7: {(conf >= 0.7).float().mean():.0%}")median 0.53, share >= 0.7: 17%Meydan klibinin tablosunda şu değerler yer alıyor: ByteTrack 32, BoT-SORT 33, TrackTrack 9, ayarlanmış TrackTrack 27, elle sayım yaklaşık 30. Algılamaların yalnızca %17'si TrackTrack'in new_track_thresh: 0.7 değerini aşıyor; bu nedenle değeri 0,35'e düşürmek (track_high_thresh: 0.3 ile) doğru çözüm. Bu sabit, tepeden bakan kamera için yalın ByteTrack daha basit bir tercih.