Ultralytics YOLO27: Trag dich in die Warteliste ein.
Get Started
LektionAnfänger

Hochwertige, repräsentative Daten sammeln

Sammle Bilder unter realen Einsatzbedingungen, halte Aufnahmemetadaten in jedem Dateinamen fest, verfolge die Abdeckung anhand der Spezifikation und wähle Videobilder aus, ohne den Datensatz aufzublähen.

Die meisten Probleme mit Datensätzen entstehen beim Sammeln. Ein Team nimmt eine Woche lang saubere Beispiele mit einer Kamera auf, die Validierung sieht hervorragend aus, und am zweiten Standort versagt das Modell. Die Datensammlung setzt die Obergrenze: Weder Labelqualität noch Augmentierung oder Hyperparameter können dem Modell eine Szene beibringen, die im Datensatz nie vorkam.

Lernergebnis

Erstelle einen Datensatz, dessen Dateinamen Kamera, Tag und Einzelbild enthalten, ermittle seine Abdeckung im Verhältnis zu den Kontingenten deiner Spezifikation und wähle aus Videos unterschiedliche Einzelbilder aus.

Schnellkurs
Wenn du dich bereits auskennst, findest du hier die Kurzfassung.
  1. Nimm Bilder mit den Produktionskameras auf, auf denen das Modell später laufen soll.

  2. Benenne jede Datei als camera_day_frame, damit sich die Dateien in späteren Schritten gruppieren und prüfen lassen.

  3. Zähle Bilder pro Kamera, Tag und Szenario anhand der Spezifikation und sammle gezielt Material für die Lücken.

  4. Wähle Videobilder so aus, dass nur Einzelbilder erhalten bleiben, bei denen sich die Szene verändert hat.

  5. Verwende öffentliche, inszenierte oder synthetische Bilder nur, um klar benannte Lücken zu schließen.

Praxisnah

Variabilität schlägt Umfang#

Vergleiche zwei Datensätze für denselben Einsatz:

DatensatzValidierungsergebnisIm Produktivbetrieb
10.000 nahezu identische Einzelbilder, eine Kamera, nur zur MittagszeitHoch: Validierungsbilder ähneln den TrainingsbildernDie Leistung sinkt bei einer anderen Kamera und in der Abenddämmerung
1.500 Einzelbilder, verteilt auf 12 Szenarien der SpezifikationWeniger beeindruckendFunktioniert zuverlässig, weil der Produktivbetrieb den Daten ähnelt

Der Validierungswert des ersten Datensatzes ist nur deshalb hoch, weil die Validierung die einzige darin abgedeckte Bedingung misst. Im Produktivbetrieb ist ein Modell nur so gut wie das am schlechtesten abgedeckte Szenario, dem es begegnet. Optimiere die Datensammlung zuerst auf die Abdeckung der Spezifikation und erst danach auf den Umfang.

Quellen in der richtigen Reihenfolge auswählen#

Der Großteil des Datensatzes sollte aus der realen Produktionsumgebung stammen. Der Leitfaden zur Datensammlung und Annotation beschreibt jede Quelle ausführlicher:

QuelleWann sie hilfreich istWann sie nachteilig ist
Produktionskameras, liveAm ähnlichsten zum späteren EinsatzLangsam; möglicherweise sind Datenvereinbarungen erforderlich
Produktionskameras, archiviertSchnell große VariabilitätÄlteres Filmmaterial entspricht möglicherweise nicht mehr der aktuellen Einrichtung
Öffentliche Datensätze (COCO, Open Images, VOC)Aufbau einer Grundlage für gängige KlassenDomänenverschiebung gegenüber deinen Szenen
Inszenierte AufnahmenBestimmte Sonderfälle gezielt aufnehmenZu sauber; man verlässt sich leicht zu sehr darauf
Synthetische oder generierte BilderSeltene Gefahren und Fehler, auf die du nicht warten kannstDas Modell kann den Stil des Generators lernen
Web ScrapingKostengünstige VielfaltUneinheitliche Qualität und Lizenzrisiken

Verwende inszenierte, öffentliche und synthetische Bilder, um bestimmte, klar benannte Lücken in der Spezifikation zu schließen, und verfolge ihren Anteil am Datensatz, damit du messen kannst, ob sie helfen. Auf der Ultralytics Platform fügt Ähnliche Bilder generieren einem Datensatz generierte Varianten eines vorhandenen Bildes hinzu, unbeschriftet und bereit zur Annotation.

Metadaten im Dateinamen festhalten#

Jedes Bild benötigt mindestens eine Kamera-ID, den Aufnahmetag und eine Einzelbild- oder Clipnummer. Ohne diese Angaben kannst du später nicht nach Gruppen aufteilen, eine Regression bis zu ihrer Quelle zurückverfolgen oder mehr Material für ein unterrepräsentiertes Szenario sammeln. Der dauerhafteste Speicherort dafür ist der Dateiname: cam2_2026-05-01_000124.jpg bleibt bei jedem Tool, Export und Upload erhalten. Die Datensatzsuche der Ultralytics Platform findet Dateinamen und benutzerdefinierte Metadaten, sodass diese Schlüssel auch nach dem Upload durchsuchbar bleiben.

Dieses Skript erstellt den Übungsdatensatz, der im restlichen Kurs verwendet wird. Es kopiert die beschrifteten Bilder aus COCO128 und benennt sie so um, als hätten vier Kameras sie über vier Tage aufgenommen, wobei cam1 überrepräsentiert ist, wie es bei einer praktischen Kamera oft der Fall ist:

import shutil
from pathlib import Path

from ultralytics.data.utils import check_det_dataset, img2label_paths

data = check_det_dataset("coco128.yaml")  # 128 COCO images stand in for your camera captures
out = Path("datasets/practice")
(out / "images").mkdir(parents=True, exist_ok=True)
(out / "labels").mkdir(parents=True, exist_ok=True)

for i, image in enumerate(sorted(Path(data["train"]).glob("*.jpg"))):
    camera = ("cam1", "cam1", "cam2", "cam3", "cam4")[i % 5]  # cam1 over-collected, like a real site
    name = f"{camera}_2026-05-0{i // 32 + 1}_{i:06d}"  # camera, capture day, frame number
    shutil.copy(image, out / "images" / f"{name}.jpg")
    label = Path(img2label_paths([str(image)])[0])
    if label.exists():
        shutil.copy(label, out / "labels" / f"{name}.txt")

print(len(list((out / "images").glob("*.jpg"))), "images written to", out)
128 images written to datasets/practice

Dialogfeld „Neuer Datensatz“ der Ultralytics Platform: Ziehe Bilder, Videos oder Datensätze im Format YOLO, COCO oder NDJSON hinein und lege anschließend Datensatzname, URL, Beschreibung, Aufgabentyp, Lizenz, Gesichtsunschärfe und Sichtbarkeit fest

Beim Upload auf die Ultralytics Platform bleiben diese Dateinamen erhalten. Im Upload-Dialog kannst du auch Videos und vollständige Datensätze hochladen; zu den Einstellungen gehört außerdem das Unkenntlichmachen von Gesichtern zum Schutz der Privatsphäre.

Abdeckung anhand der Spezifikation verfolgen#

Mit Metadaten in den Dateinamen lässt sich die Abdeckung einfach zählen. Lege die Kontingente anhand deiner Spezifikation fest und lass dir vom Skript sagen, was als Nächstes gesammelt werden soll:

from collections import Counter
from pathlib import Path

QUOTA = {"cam1": 30, "cam2": 30, "cam3": 30, "cam4": 30}  # images per camera, from your spec

images = sorted(Path("datasets/practice/images").glob("*.jpg"))
cameras = Counter(p.stem.split("_")[0] for p in images)
days = Counter(p.stem.split("_")[1] for p in images)

for camera, quota in QUOTA.items():
    gap = quota - cameras[camera]
    print(f"{camera}: {cameras[camera]:3d} / {quota}  {'ok' if gap <= 0 else f'collect {gap} more'}")
print("days:", dict(sorted(days.items())))
cam1:  52 / 30  ok
cam2:  26 / 30  collect 4 more
cam3:  25 / 30  collect 5 more
cam4:  25 / 30  collect 5 more
days: {'2026-05-01': 32, '2026-05-02': 32, '2026-05-03': 32, '2026-05-04': 32}

Die Entscheidungsregel: Sammle nicht weiter aus Quellen, deren Kontingent erreicht ist, und richte den Aufwand auf die Lücken. Hier enthält cam1 bereits 40 % der Bilder. Eine weitere Woche mit diesem Filmmaterial würde zwar den Umfang vergrößern, aber keine neue Abdeckung schaffen.

Videobilder auswählen, ohne den Datensatz aufzublähen#

Video ist die günstigste Quelle und lässt sich am leichtesten falsch einsetzen. Bei 30 Bildern pro Sekunde liefert eine Minute 1.800 nahezu identische Einzelbilder, und denselben Moment zweimal zu beschriften kostet Geld und verzerrt die Kennzahlen. Behalte ein Einzelbild nur dann, wenn sich die Szene seit dem letzten behaltenen Einzelbild verändert hat:

from pathlib import Path

import cv2

from ultralytics.utils.downloads import safe_download

video = "solutions_ci_demo.mp4"  # a short public demo clip; swap in your own footage
safe_download(f"https://github.com/ultralytics/assets/releases/download/v0.0.0/{video}")
Path("frames").mkdir(exist_ok=True)

cap = cv2.VideoCapture(video)
fps = cap.get(cv2.CAP_PROP_FPS)
read = kept = 0
last = None
while True:
    ok, frame = cap.read()
    if not ok:
        break
    thumb = cv2.cvtColor(cv2.resize(frame, (64, 64)), cv2.COLOR_BGR2GRAY).astype(float)
    if last is None or abs(thumb - last).mean() > 10:  # keep a frame only when the scene has changed
        cv2.imwrite(f"frames/clip01_{read:06d}.jpg", frame)  # the clip ID stays in the filename
        kept, last = kept + 1, thumb
    read += 1

print(f"{read} frames at {fps:.0f} FPS -> {kept} kept")
62 frames at 30 FPS -> 6 kept

Der zwei Sekunden lange Clip enthält 62 Einzelbilder, aber nur 6 visuell unterschiedliche Momente. Das Skript vergleicht kleine Graustufenminiaturen und ist deshalb auch bei stundenlangem Filmmaterial schnell. Erhöhe den Schwellenwert von 10, um bei statischen Kameras weniger Einzelbilder zu behalten; senke ihn für Szenen mit schnellen Bewegungen. Verteile das Kontingent außerdem auf mehrere Clips: 20 Einzelbilder aus jedem von 50 Clips sind besser als 1.000 Einzelbilder aus einem einzigen Clip.

Bilder aus einem Clip sind eine Stichprobe, nicht viele

Zwei Bilder im Abstand von einer Sekunde haben dieselbe Beleuchtung, denselben Hintergrund und meist dieselben Objekte. Wenn sie sowohl im Trainings- als auch im Validierungssatz landen, wird das Modell in der Validierung anhand von Bildern bewertet, die es praktisch schon gesehen hat. Nimm die Clip-ID in jeden Dateinamen auf, damit Datensatz korrekt aufteilen alle Bilder eines Clips zusammenhält.

Fallstricke bei der Datenerhebung vermeiden#

FallstrickSymptomLösung
Datenerhebung innerhalb einer WocheHoher mAP auf den Validierungsdaten, aber Fehler in anderen Jahreszeiten oder bei SchichtwechselnVerteile die Aufnahmen auf mehrere Wochen oder Monate
Nur eine KameraFunktioniert mit der zweiten Kamera nichtNimm Bilder mit allen Kameratypen auf, die du einsetzt
Nur inszenierte DatenFunktioniert bei realem Durcheinander nichtHalte inszenierte Bilder in der Minderheit und erfasse ihren Anteil
Doppelte FramesAufgeblähte Kennzahlen und unnötiger BeschriftungsaufwandStichproben nach Szenenwechseln; die Ultralytics Platform überspringt beim Hochladen außerdem exakte Kopien
Nur eine Bedienperson oder SchichtUngeplante Erscheinungsbilder und unausgewogene KlassenverteilungZiehe Stichproben über verschiedene Schichten, Standorte und Personen hinweg
Seltene Fälle fehlenDie wichtigsten Sicherheitsvorfälle werden übersehenGezielte Aufnahmen, Inszenierung oder Ergänzung mit synthetischen Daten

Verzerrungen sind ein Problem der Datenerhebung, kein Modellierungsproblem: Kein Hyperparameter kann eine Gruppe berücksichtigen, die in den Daten nie enthalten war. Der Leitfaden zur Datenerhebung nennt vier Ansatzpunkte: vielfältige Quellen, ausgewogene Repräsentation, regelmäßige erneute Prüfungen der Abdeckung und Maßnahmen zur Abhilfe, etwa Überstichproben für unterrepräsentierte Gruppen.

Wenn Bilder Gesichter, Nummernschilder oder andere personenbezogene Daten enthalten, brauchst du vor Beginn der Datenerhebung eine Einwilligung und eine Aufbewahrungsrichtlinie. Der Glossareintrag zu Datenschutz ist ein guter Ausgangspunkt; Datenschutz, Regionen und Compliance behandelt, wie du Daten mit dataRegion in der richtigen Rechtsordnung hältst.

Ausprobieren

Führe make_practice_set.py aus, bearbeite dann die Kontingente in coverage.py, damit sie deiner eigenen Spezifikation entsprechen (oder behalte die Übungskontingente bei), und führe das Skript aus. Benenne für dein echtes Projekt 50 aktuelle Bilder nach dem Muster camera_day_frame um und ermittle damit dieselbe Abdeckung. Ergebnis: ein Abdeckungsbericht und ein Erhebungsplan, der jede Quelle aufführt, deren Kontingent überschritten ist, sowie jede Lücke und deren Umfang.

Abgeschlossen, wenn
Du hast die Lektion abgeschlossen, wenn alle folgenden Punkte zutreffen.
  • Jeder Bilddateiname enthält eine Kamera (oder Quelle), einen Aufnahmetag und eine Frame- oder Clipnummer.

  • Ein Abdeckungsbericht vergleicht die Bildanzahl je Kamera, Tag oder Szenario mit den Kontingenten der Spezifikation.

  • Videos werden anhand von Szenenwechseln abgetastet, und die behaltenen Frames behalten ihre Clip-ID.

Lösung anzeigen

Für den Übungsdatensatz ergibt der Abdeckungsbericht einen konkreten Plan:

QuelleAnzahl / KontingentMaßnahme
cam152 / 30Beende die Datenerhebung; auf diese Quelle entfallen bereits 40 % aller Bilder
cam226 / 30Erfasse 4 weitere
cam325 / 30Erfasse 5 weitere
cam425 / 30Erfasse 5 weitere

Jede Kamera deckt alle vier Tage ab, daher beziehen sich die Lücken auf die Kameras, nicht auf die Tage. Verteile die 14 neuen Bilder auf mindestens zwei neue Tage, damit sie eine neue Bedingung abdecken und nicht noch mehr vom selben Nachmittag zeigen. Kann eine Kamera ihre Lücke nicht schließen (etwa weil sie ausschließlich Nachtaufnahmen liefert), ergänze die Spezifikation um eine Zeile für die fehlende Bedingung und halte fest, ob inszenierte oder generierte Bilder die Lücke füllen, damit sich die Auswirkungen später messen lassen.

Wie es weitergeht

Nachdem du die Bilder aufgenommen hast, zeigt dir die nächste Lektion, wie du sie gleich beim ersten Mal einheitlich beschriftest.