Ultralytics YOLO27: Trag dich in die Warteliste ein.
Get Started
Trainiere dein erstes YOLO-Modell·Bereitstellen·Lektion 9/10
LektionAnfänger

Inferenz auf Videos ausführen

Führe YOLO26 auf Videodateien und Live-Kameras mit begrenztem Speicherverbrauch aus, verfolge Objekte, um jedes nur einmal zu zählen, und prüfe, ob das Modell mit der Bildrate Schritt hält.

Die meisten eingesetzten Bildverarbeitungssysteme überwachen Videos: Kameras an Förderbändern, Türen und Straßen. Videos bringen zwei Probleme mit sich, die es bei Einzelbildern nicht gibt. Speicher: Eine lange Aufzeichnung lässt sich nicht vollständig im RAM halten. Identität: Ein Detektor erkennt dieselbe Person in 60 Bildern und meldet 60 Personen.

In dieser Lektion verarbeitest du Videos Bild für Bild im Predict-Modus, ergänzt Objektverfolgung, um jede Person nur einmal zu zählen, schreibst eine eigene Kameraschleife und misst, ob dein Modell mithalten kann.

Lernergebnis

Du kannst Videos oder Kameras mit begrenztem Speicherverbrauch durch YOLO26 streamen, eindeutige Objekte mithilfe der Verfolgung zählen und anhand der gemessenen Millisekunden pro Bild feststellen, ob das Modell mit der Quelle Schritt hält.

Schnellkurs
Wenn du dich bereits auskennst, findest du hier die Kurzfassung.
  1. model(video, stream=True) liefert für jedes Bild ein Results bei begrenztem Speicherverbrauch.

  2. model.track(video, stream=True, persist=True, tracker='bytetrack.yaml') ergänzt boxes.id.

  3. Zähle eindeutige Objekte anhand einer Menge von IDs, niemals anhand der höchsten ID.

  4. Zeitbudget = 1000 ÷ Quell-FPS; vergleiche es mit result.speed['inference'].

Praxisnah

Beispiel: Vorhersagen auf einer Videodatei#

Videos werden wie Bilder im selben Predict-Modus verarbeitet. Dieser Clip mit 62 Bildern zeigt Menschen, die ein Atrium durchqueren:

yolo predict model=yolo26n.pt source=https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4
video 1/1 (frame 1/62) solutions_ci_demo.mp4: 384x640 22 persons, 27.3ms
...
video 1/1 (frame 62/62) solutions_ci_demo.mp4: 384x640 22 persons, 54.8ms
Results saved to runs/detect/predict
  • frame 1/62: Ultralytics dekodiert das Video und verarbeitet jedes Bild wie ein Einzelbild.
  • 22 persons: Erkennungen in diesem Bild. Dieselben Passanten werden in jedem Bild erneut gezählt.
  • 27.3ms ... 54.8ms: Die Zeit pro Bild variiert je nachdem, womit der Rechner sonst beschäftigt ist.

Das annotierte Video ist runs/detect/predict/solutions_ci_demo.mp4. Dein eigenes Modell funktioniert genauso: Ersetze yolo26n.pt durch runs/detect/pills_v1/weights/best.pt.

Lange und Live-Quellen streamen#

Wenn dein Code mit Erkennungen arbeitet, durchlaufe einen Stream. Bei jeder Iteration wird das Results eines Bildes geliefert und anschließend verworfen:

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
source = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"

frames, people = 0, 0
for result in model(source, stream=True, classes=[0], verbose=False):  # one Results object per frame
    frames += 1
    people += len(result.boxes)
print(f"{frames} frames, {people / frames:.1f} people per frame")
62 frames, 22.2 people per frame

Dieselbe Schleife akzeptiert einen Webcam-Index (source=0) oder eine Kamera-URL wie rtsp://camera.local/stream und läuft, bis der Stream endet oder du ihn stoppst. Füge vid_stride=2 hinzu, um nur jedes zweite Bild zu verarbeiten. Der Leitfaden zur Live-Inferenz mit Streamlit verpackt diese Schleife in eine App für eine Browseroberfläche.

Beispiel: Jede Person nur einmal zählen#

„22 Personen pro Bild“ ist nicht die Zahl, die jemand wissen möchte; gefragt ist: „Wie viele Personen sind hindurchgegangen?“ Multi-Objekt-Verfolgung verknüpft Boxen über mehrere Bilder hinweg, und der Track-Modus weist jedem Objekt in boxes.id eine ID zu:

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
source = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"

seen = set()
for result in model.track(source, stream=True, persist=True, classes=[0], tracker="bytetrack.yaml", verbose=False):
    if result.boxes.is_track:
        seen.update(result.boxes.id.int().tolist())
print(f"{len(seen)} unique people tracked")
32 unique people tracked

is_track ist False für Bilder, bevor ein Track bestätigt wurde, wenn boxes.id None ist. Verwende die IDs zum Zählen, für Trajektorien oder für Logik wie „Dieses Objekt ist seit 3 Sekunden hier“.

Ultralytics YOLO verfolgt den Verkehr auf einer Autobahn: Jedes Auto, jeder Bus und jeder Lkw ist mit einer dauerhaften ID und einer Bewegungsspur versehen

TrackerGeschwindigkeitRobustheit
bytetrack.yamlSchneller, einfacherVerliert IDs häufiger, wenn Objekte kurzzeitig verschwinden
botsort.yamlLangsamerBehält IDs bei Kamerabewegungen besser bei (Bewegungskompensation; ReID anhand des Erscheinungsbilds ist über with_reid optional)

Wenn du tracker weglässt, verwendet Ultralytics tracktrack.yaml, die aktuelle Standardeinstellung; im Track-Modus sind außerdem ocsort.yaml, deepocsort.yaml und fasttrack.yaml enthalten. Die Auswahl und Feinabstimmung von Trackern sowie die darauf aufbauende Objektzählung, Heatmaps und Geschwindigkeitsschätzung werden in Objekte mit ByteTrack, BoT-SORT und TrackTrack verfolgen behandelt.

Beispiel: Deine eigene Kameraschleife#

Reale Anwendungen lesen Bilder oft selbst ein – etwa um sie zu skalieren, zuzuschneiden, mit Zeitstempeln zu versehen oder eine Kamera mit anderem Code gemeinsam zu nutzen – und übergeben sie dann einzeln an das Modell. persist=True hält den Tracker zwischen den Aufrufen am Leben:

import cv2

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
cap = cv2.VideoCapture("solutions_ci_demo.mp4")  # saved locally by the commands above; or 0, or an rtsp:// URL

seen = set()
while cap.isOpened():
    ok, frame = cap.read()
    if not ok:
        break
    result = model.track(frame, persist=True, classes=[0], tracker="bytetrack.yaml", verbose=False)[0]
    if result.boxes.is_track:
        seen.update(result.boxes.id.int().tolist())
cap.release()
print(f"{len(seen)} unique people, highest ID {max(seen)}")
32 unique people, highest ID 67

Dieselben 32 Personen wie bei track.py. Beachte, dass die höchste ID 67 und nicht 32 ist: Der Tracker vergibt auch IDs für vorläufige Tracks, die nie bestätigt werden, sodass Lücken entstehen.

Mit der Quelle Schritt halten#

Eine 30-FPS-Kamera liefert alle 33 ms ein Bild, und deine effektive Rate entspricht der langsamsten Phase: Dekodierung, Inferenz oder Schreiben. Auf unserem Laptop mit CPU dauerte yolo26n je nach sonstiger Auslastung des Rechners bei verschiedenen Durchläufen 26 bis 46 ms pro Bild mit einer Auflösung von 384×640: Das liegt am oder über dem Zeitbudget, ohne Spielraum. Wenn dein System nicht mithalten kann, probiere diese Stellschrauben der Reihe nach aus:

StellschraubeAuswirkung
Kleineres Modell (n statt s)Oft 2–3× schneller
Niedrigeres imgsz (480 statt 640)Weniger Pixel, weniger Rechenaufwand; kleine Objekte leiden zuerst
vid_stride=2Halbiert den Aufwand; geeignet für Szenen mit langsamen Bewegungen
Eine GPU oder ein optimierter ExportDie größten Leistungssteigerungen — eine TensorRT-Engine auf NVIDIA oder INT8; mehr dazu in der nächsten Lektion

Mehrere Kameras gleichzeitig und die dafür nötige Thread-Verarbeitung werden in Multi-Stream-Inferenz behandelt.

Diese Fehler vermeiden#

stream=True vergessen

Symptom: Bei einer langen Aufnahme steigt der Speicherverbrauch, bis der Prozess abstürzt, oder ein Aufruf mit einer Live-Kamera kehrt nie zurück. Ursache: Ohne diese Option sammelt der Python-Aufruf vor der Rückgabe für jedes Bild ein Results-Objekt. Lösung: Übergebe stream=True und durchlaufe den Generator – er tut nichts, bis du ihn durchläufst.

persist=True in der eigenen Schleife vergessen

Symptom: In cv2_loop.py ohne persist=True sank die Anzahl auf 27 und die höchste ID war ebenfalls 27: Die IDs wurden bei jedem Bild neu gestartet, sodass die „eindeutige“ Anzahl nur dem Bild mit den meisten Objekten entsprach. Lösung: Übergebe persist=True, wenn du track einmal pro Bild aufrufst.

Anhand der höchsten ID zählen

Symptom: 67 gezählte Personen bei tatsächlich 32 Personen. Ursache: Nicht bestätigte Tracks verursachen Lücken in den IDs. Lösung: Zähle die Anzahl eindeutiger IDs in einer Menge, wie in track.py.

Tracker ausdrücklich angeben

Der Standard-Tracker kann sich zwischen Versionen ändern. Übergib tracker="bytetrack.yaml" (oder den Tracker deiner Wahl), damit die Anzahlen über verschiedene Versionen hinweg vergleichbar bleiben.

Ausprobieren

Führe track_any.py (in der Lösung) auf dem Demo-Clip und anschließend auf einem kurzen eigenen Video aus. Gib einen dreizeiligen Bericht ab: die Anzahl eindeutiger Objekte, die durchschnittliche Inferenzzeit in ms pro Bild und ob das zur Bilddauer deiner Quelle passt; nenne außerdem die erste Stellschraube, an der du drehen würdest, wenn es nicht passt. Speichere eine annotierte Ausgabe mit yolo track ... save=True und vermerke, ob die IDs bei Verdeckungen stabil bleiben; flackern sie, probiere tracker=botsort.yaml aus.

Abgeschlossen, wenn
Du hast die Lektion abgeschlossen, wenn alle folgenden Punkte zutreffen.
  • Du hast ein annotiertes Video mit yolo predict oder yolo track gespeichert.

  • Dein Streaming-Skript gibt die Anzahl eindeutiger Objekte anhand einer Menge von boxes.id-Werten aus.

  • Du hast die gemessenen Millisekunden pro Bild mit der Bilddauer der Quelle verglichen und deine erste Stellschraube zur Beschleunigung benannt.

Lösung anzeigen
import sys

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
seen, times = set(), []
for result in model.track(sys.argv[1], stream=True, persist=True, tracker="bytetrack.yaml", verbose=False):
    times.append(result.speed["inference"])
    if result.boxes.is_track:
        seen.update(result.boxes.id.int().tolist())
print(f"{len(seen)} unique objects, {sum(times) / len(times):.1f} ms inference per frame")

Führe es mit python track_any.py your_video.mp4 aus.

32 unique objects, 30.5 ms inference per frame (26-46 ms across runs on a laptop CPU)
Source is 30 FPS -> 33 ms budget: fits only on a quiet machine, with no headroom
First lever: export to OpenVINO or ONNX for this CPU, then vid_stride=2 if still short
Wie es weitergeht

Dein Modell funktioniert in Python auf Bildern und Videos. Der letzte Schritt: Exportiere es in ein Format, das eine Laufzeitumgebung für den Produktiveinsatz laden kann.