11 min Lesezeit

Erstelle ein Objekt-Erkennung-Datenset für Filmklappen

Als ich 2022 zum ersten Mal mit der Erstellung eigener Datasets für Paperdot herumexperimentiert habe, ging es noch um reine Klassifikation: Ein Modell sollte lernen, verschiedene Materialien zu unterscheiden. Richtig gute Tools, um den Labeling-Prozess zu beschleunigen, gab es damals kaum. Meistens hat man sich seine Scripts einfach selbst zusammengebaut. Vier Jahre später sieht das anders aus: Mittlerweile gibt es ein ganzes Ökosystem an Annotation-Tools genau für diesen Zweck (CVAT, Label Studio und Roboflow sind die, zu denen ich immer wieder zurückkomme).

In meinem aktuellen Forschungsprojekt ist die Sache nochmal einen Schritt weitergegangen - weg vom statischen Labeling, hin zu dynamischem Echtzeit-Tracking. Diesmal lautet das Ziel: Filmklappen tracken, also die Klappen, die den Anfang (oder das Ende) einer Einstellung markieren. Dieser Post dreht sich um den Teil, der eigentlich darüber entscheidet, ob der Rest des Projekts überhaupt funktioniert: die Erstellung des Datensets.


1. Die Grundüberlegung: Was tracken wir hier eigentlich?

Bevor wir auch nur ein einziges Bild annotieren, sollten wir klären, was man wirklich braucht - nicht, was sich bequem labeln lässt. Für die Erkennung von Filmklappen sahen die Anforderungen wie folgt aus:

  • Echtzeit-Geschwindigkeit - das Ganze muss live am Set laufen, nicht als Offline-Batch-Job.
  • Rotationsbewusstsein - Klappen werden nicht immer gerade gehalten. Fürs Kamerabild werden sie gekippt, und „End-Klappen" (auch „Tail Slates" genannt, gefilmt am Ende statt am Anfang einer Einstellung) werden oft um 180° gedreht in die Kamera gehalten.
  • Zustandserkennung - das System muss wissen, ob die Klappe offen oder geschlossen ist, denn genau dieser Moment markiert den eigentlichen Schnittpunkt.

Nur die ersten beiden Punkte sind wirklich Geometrie-Fragen. Der dritte ist ein Labeling-/Taxonomie-Problem, dazu komme ich im nächsten Abschnitt. Was die Geometrie angeht, gibt es drei gängige Wege, ein Object-Detection-Problem zu formulieren:

  • Standard Object Detection (BBox): Liefert ein achsenparalleles $x, y, w, h$-Rechteck. Da Klappen fast immer in einem Winkel gehalten werden, muss eine achsenparallele Box so groß werden, dass sie die gesamte gekippte Form umschließt - und besteht dadurch größtenteils aus ungenutzten Hintergrund. Schlimmer noch: Eine BBox kann Rotation grundsätzlich nicht abbilden, dafür gibt es schlicht kein Feld, sodass nachgelagerte Schritte wie das Geraderücken der Klappe für die Texterkennung (OCR) keinerlei Hilfe vom Detektor bekommen. Und End-Klappen lassen sich damit auch nicht zuverlässig erkennen.
  • Instance Segmentation: Liefert pixelgenaue Masken, was das Rotationsproblem technisch lösen würde - allerdings sind die Annotationskosten brutal (statt vier Ecken zu ziehen, muss man pro Frame ein Polygon nachzeichnen), und eine pixelgenaue Maske ist mathematisch gesehen völliger Overkill, wenn du eigentlich nur ein sauberes Rechteck zum Zuschneiden und Entzerren brauchst. Dazu kommt: Die Inferenz ist langsamer - ein echtes Problem, wenn der ganze Sinn der Übung Echtzeit-Tracking ist.
  • Oriented Bounding Boxes (OBB): der Gewinner. Ein gedrehtes Rechteck, meist gespeichert als vier explizite Eckpunkte (Ultralytics-Format: class x1 y1 x2 y2 x3 y3 x4 y4, normalisiert) statt als Mittelpunkt plus Rotationswinkel $\theta$.


2. Die eigene Regeln festlegen

Das ist der Schritt, den man am leichtesten überspringt - und der einen später am teuersten zu stehen kommt, weil er festlegt, was jede einzelne Annotation in deinem Dataset überhaupt bedeutet. „Klappe tracken" ist keine Kategorie. Du musst schriftlich festlegen, bevor du auch nur ein Label setzt:

  • Zwei vollwertige Klassen statt einer Klasse mit Attribut. Ich habe mich für slate_open und slate_closed als zwei komplett getrennte Labels entschieden, statt für eine einzelne slate-Klasse mit einem Offen/Geschlossen-Attribut nebenbei. Eine gemeinsame Klasse mit Attribut ist auf dem Papier die „sauberere" Modellierung - aber Attribute sind eine Funktion des jeweiligen Annotation-Tools und der Trainings-Pipeline, die du gerade benutzt. Sie überleben nicht zwangsläufig einen Wechsel des Exportformats oder eine andere Modellarchitektur. Zwei einfache Klassen sind dagegen der kleinste gemeinsame Nenner: Sie funktionieren später mit so gut wie jedem Setup, auf das du dein Dataset ansetzt - und wenn ein zukünftiges Modell sich nur für einen der beiden Zustände interessiert, kann es einfach nur auf dieser Klasse trainieren und die andere ignorieren.
  • Die Grenze ist einfacher zu ziehen, als es klingt - weil es sie im Grunde kaum gibt. In der Praxis ist eine Klappe ein Scharnier mit zwei Ruhepositionen und verhält sich damit wie ein binärer Schalter: Ist am Scharnier auch nur ein winziger Spalt sichtbar, ist die Klappe slate_open - Punkt, egal wie klein der Spalt ist. Du bewertest keine Öffnungsgrade, du prüfst nur, ob sie bündig zu ist oder nicht. Diese eine Regel löst so gut wie jedes Frame ohne Ermessensspielraum, inklusive der kurzen „gerade erst am Zuklappen"-Frames.
  • Lege auch für Verdeckungen und Teilsichtbarkeit eine explizite Regel fest. Eine Hand, die die Klappe hält, eine Klappe, die halb aus dem Bild ragt, eine Klappe, die sich im Hintergrund in einem Spiegel oder Monitor spiegelt - definiere eine Regel (z. B. annotieren bis zu einem bestimmten Mindest-Sichtbarkeitsanteil, sonst überspringen) und wende sie konsequent an, statt bei jedem Frame neu zu entscheiden.

Das Ganze muss kein offizielles Dokument sein - ein paar Stichpunkte neben deinem Annotation-Tool reichen völlig. Es geht nur darum, dass die Regel existiert und bei Frame 1 genauso gilt wie bei Frame 10.000.


3. Eine durchdachte Sampling-Strategie für Video-Clips

Filmklappen stehen entweder still oder bewegen sich in kurzen, vorhersehbaren Schüben. Wenn man rohes 25-fps-Videomaterial direkt in ein Annotation-Tool kippst, annotierst du am Ende tausende Frames, die optisch praktisch identisch mit ihren Nachbarn sind - und verbrennst damit Stunden an Labeling-Zeit für so gut wie keinen zusätzlichen Informationsgewinn.

  • Der Basis-Clip: In den meisten unserer letzten geshooteten Takes ist die Klappe rund 2 Sekunden im Bild (bei 25 fps also etwa 50 Rohframes).
  • Das Sampling-Intervall: Da wir nicht jedes Bild annotieren wollen und die Datenqualität davon abhängt, dass sich die Bilder tatsächlich unterscheiden, samplen wir jedes 2. Bild. Das ergibt rund 25 annotierte Frames pro Clip - genug, um den kompletten Ablauf abzudecken: offen, in Bewegung, der Moment des Zuschlagens, dann der stabile geschlossene Zustand, ohne Redundanz. Gehst du gröber vor (z. B. nur jedes 5. Frame), riskierst du, genau den kurzen „leicht geschlossen, noch in Bewegung"-Zustand zu überspringen - und das ist exakt der Übergang, von dem dein Modell die meisten Beispiele braucht.
  • Sample nicht blind durch statische Haltephasen. Das Intervall oben setzt Bewegung voraus. Wird die Klappe in einem Take für ein, zwei Sekunden völlig ruhig im Bild gehalten, bevor geklappt wird, erzeugt ein 2er-Sampling dort nur eine Serie von Fast-Duplikaten. Ein kurzer Blick hilft, visuell identische Serien auszudünnen - die investierten paar Minuten sind an anderer Stelle besser angelegt, etwa für ein anderes Lichtsetup oder einen weiteren Take.
  • Hintergrund- und Negativ-Frames: Trainiere einen Model nie ausschließlich mit positiven Beispielen (nur Bilder mit klappen), sonst fängt er an, überall Phantom-Klappen zu halluzinieren. Ziel sind 15-20 % deines Datasets als leere Frames - rund 4-6 pro Clip. Ganz ohne eine Box.
  • Lass deine Negativ-Beispiele als Hard Negatives zählen, nicht nur als leere Räume. Eine schlichte Aufnahme einer Wand bringt dem Modell fast nichts, was es nicht ohnehin schon weiß. Frames mit anderen rechteckigen, kontrastreichen Objekten - Klemmbretter, Laptops, Monitore, Whiteboards, Notizbücher - sind deutlich wertvollere Negativbeispiele, weil genau das die Dinge sind, die dein Modell später am ehesten mit einer Klappe verwechselt.
  • Diversität auf jeder Achse - nicht nur bei der Frame-Anzahl. Kameraabstand und -winkel, Lichtsetup (Tageslicht, Kunstlicht, Low-Light-Bedingungen am Set), das physische Design der Klappe (Kreide, Whiteboard, digitale/Smart Slate), Hände und Hautfarben der Personen, die die Klappe halten, sowie das Ausmaß an Motion-Blur beim Zuklappen wirken sich stärker auf die Generalisierung aus als die reine Bildanzahl. Zwanzig Takes über fünf verschiedene Lichtsetups schlagen hundert Takes aus demselben Raum - immer.


4. Splits erstellen, ohne in die Zukunft zu spicken

Das ist der Teil, den man bei videobasierten Daten wirklich leicht übersieht - und der Fehler zeigt sich nicht als offensichtlicher Bug, sondern als Validation Score, der fantastisch aussieht, während das Modell bei echtem, ungesehenem Material still und leise schlechter performt.

Die Falle: Wenn du 25 Frames aus einem Clip samplest und dann Frames zufällig auf Train/Val aufteilst, landet zum Beispiel Frame 14 im Training und Frame 15 - fast pixelidentisch - in der Validation. Deine Validation-Metrik misst dann, wie gut sich das Modell genau diesen einen Take gemerkt hat, nicht wie gut es generalisiert. Sieht fantastisch aus, sagt aber kaum etwas aus.

  • Splitte nach Take/Clip, nie nach Frame. Alle Frames eines Clips gehören komplett ins Training, komplett in die Validation oder komplett ins Test-Set - niemals aufgeteilt auf zwei davon.
  • Ein vernünftiges Startverhältnis ist 70/20/10 oder 80/10/10 auf Clip-Ebene, anpassbar, sobald du siehst, wie viele unterschiedliche Takes du tatsächlich hast.
  • Stratifiziere den Split über deine Diversitäts-Achsen, nicht nur zufällig nach Clip. Landen zufällig alle deine Low-Light-Takes oder Takes mit ungewöhnlichem Klappendesign im Training, sieht dein Validation Score besser aus als die Realität - und du merkst es erst beim Deployment.
  • Halte mindestens ein bis zwei Clips mit einem Klappendesign oder Setup zurück, das das Modell sonst nirgendwo zu sehen bekommt - exklusiv fürs Test-Set. Das ist dein eigentlicher Generalisierungs-Check, unabhängig von der Frage „hat es diese konkreten Takes gelernt", die Train/Val beantwortet.


5. Dataset-Größe und die Mehr-ist-besser-Falle

Wie viele Bilder brauchst du eigentlich wirklich? Weil eine Filmklappe einen hohen visuellen Kontrast und eine starre, klar definierte Struktur hat, brauchst du keine Millionen Bilder für solide Performance.

  • Proof of Concept: 200-300 Bilder (etwa 8-12 vollständig annotierte Takes) reichen, um ein Basismodell zum Laufen zu bringen und die gesamte Pipeline zu validieren.
  • Der Production-Grade-Sweetspot: 500-1.000 Bilder (20-40 Takes plus Backgrounds). Ab hier bekommst du echte Varianz bei Licht, Brennweite und Motion-Blur - genug, um auch mit unordentlichen Realweltbedingungen klarzukommen.
  • Ist mehr immer besser? (Die 2.000+-Bilder-Frage): Technisch gesehen kannst du ein modernes YOLO-Modell bei 2.000+ Bildern nicht komplett overfitten. Aber du landest schnell im Bereich, in dem mehr daten keinen großen Ertrag bringen. Filmklappen und Set-Umgebungen sind von Natur aus visuell repetitiv, weshalb dir tausende zusätzliche, ähnliche Frames nur sehr wenig zusätzlichen mAP (Mean Average Precision - die Standard-Genauigkeitsmetrik für Detection-Modelle, gemittelt über Klassen und Konfidenz-Schwellenwerte) einbringen, dafür aber jede Menge zusätzliche Annotationszeit kosten. Ein diverses, gut gesampeltes Set aus 600-800 Bildern schlägt in der Regel ein größeres, aber repetitives Set.
  • Diese Zahlen gelten pro Klasse, nicht pro Dataset. Mit slate_open und slate_closed als zwei getrennten Klassen braucht jede ihren eigenen Anteil an soliden Beispielen - 600 Bilder, die sich 90/10 auf beide verteilen, sind kein 600-Bilder-Dataset, sondern faktisch ein 60-Bilder-Dataset für den unterrepräsentierten Zustand. Da eine geschlossene Klappe pro Take nur einen Bruchteil der Zeit im Bild ist, die eine offene Klappe im Bild ist (das Sampling-Intervall aus Abschnitt 3 fängt naturgemäß mehr „offen"- als „geschlossen"-Frames ein), behalte die Klassen-Anzahl unterwegs im Blick, nicht nur die Gesamtsumme.


6. Annotationsqualität: enge Boxen, konsistente Ecken

Volumen und Sampling-Strategie sorgen für diverse Daten - das hier ist es, was jede einzelne Annotation tatsächlich wertvoll macht.

  • Ziehe die Boxen eng an die physischen Kanten der Klappe, nicht an ihren Motion-Blur-Schleier. Das ist bei OBB wichtiger als es je bei achsenparallelen Boxen war, weil das Modell nicht nur „Objekt hier" lernt, sondern aus deiner Eckenplatzierung den exakten Rotationswinkel - schlampige Ecken bringen ihm einen schlampigen Winkel bei.
  • Halte die Reihenfolge der Eckpunkte über alle Frames hinweg konsistent. Da OBB als vier explizite Eckpunkte gespeichert wird, kodiert die Reihenfolge dieser Punkte implizit die Ausrichtung. Kippt diese Reihenfolge von einem Frame zum nächsten (was bei unachtsamer manueller Korrektur exportierter Labels passieren kann), bringst du dem Modell für eine eigentlich glatte, kontinuierliche Rotation zwei widersprüchliche Vorstellungen davon bei, wohin die Box „zeigt". Die meisten Annotation-Tools halten die Reihenfolge standardmäßig automatisch konsistent - der Fehler entsteht so gut wie immer durch nachträgliches manuelles Bearbeiten der Label-Dateien, nicht durch das Tool selbst.
  • Nutze Interpolation bei Video, aber vertrau ihr nicht blind. Die meisten modernen Annotation-Tools können die Position einer Box zwischen zwei manuell gesetzten Keyframes interpolieren - bei einer bewegten Klappe eine riesige Zeitersparnis. Stichprobe die interpolierten Frames trotzdem, besonders im schnellen Teil der Bewegung rund um den Aufschlag - genau dort neigt lineare Interpolation dazu, von der tatsächlichen Position abzudriften.
  • Labeln mehrere Personen, schreibt eure Regeln auf (siehe Abschnitt 2) und macht regelmäßig Stichproben im Team. Drift zwischen den Personen, die labeln, bei einem unscharfen Grenzfall bleibt unsichtbar - bis du vor einer Confusion Matrix sitzt und dich fragst, warum sich das Modell nicht entscheiden kann.



Quellen und hilfreiche Videos

Dataset mit CVAT erstellen | YOLO Object-Detection-Modelle trainieren | CVAT - Annotation mit Hugging Face beschleunigen