Instanzsegmentierung beschriften und trainieren
Erstelle Polygonbeschriftungen, prüfe sie im Code, trainiere yolo26n-seg.pt mit COCO8-seg und diagnostiziere ein Modell anhand der Abweichung zwischen seinen Box- und Maskenmetriken.
Bei der Instanzsegmentierung erhält jedes Objekt seinen eigenen Umriss. Das brauchst du, wenn die Fläche, Überlappung oder eine Grenze die Entscheidung bestimmt. Polygone sind die aufwendigsten Beschriftungen, für die die meisten Teams bezahlen, und eine fehlerhafte Zeile lässt das Training nicht abstürzen – sie trainiert unbemerkt mit der falschen Form. In dieser Lektion lernst du das richtige Zeilenformat kennen, prüfst einen Beschriftungsdatensatz im Code und trainierst ein erstes Modell. So siehst du, was die zusätzliche Beschriftungsarbeit bringt: eine zweite Metrik, die Umrisse statt nur Positionen bewertet.
Praxisnah
Die Polygonbeschriftungszeile#

Eine Segmentierungs-Beschriftungsdatei enthält eine Zeile pro Objekt, wie eine Beschriftungsdatei für die Objekterkennung. Statt einer Box führt sie jedoch den Umriss des Objekts als normalisierte Scheitelpunktpaare auf. Eine gekürzte echte Zeile aus COCO8-seg:
45 0.782016 0.986521 0.937078 0.874167 0.957297 0.782021 0.950562 0.739333 0.825844 0.561792 ...| Position | Erkennungszeile | Segmentierungszeile |
|---|---|---|
| 1 | Klassenindex (45 ist bowl) | Klassenindex |
| 2–5 | x_center y_center width height | die ersten beiden Scheitelpunkte, x1 y1 x2 y2 |
| 6+ | — | weitere Scheitelpunkte, so viele wie für den Umriss nötig |
| Einheiten | normalisiert auf 0–1 | normalisiert auf 0–1 (Pixel-x ÷ Bildbreite, Pixel-y ÷ Bildhöhe) |
Drei Regeln sind besonders wichtig: mindestens drei Scheitelpunkte pro Objekt, Koordinaten geteilt durch die Bildgröße und eine Zeile pro Instanz, selbst wenn sich zwei Objekte derselben Klasse berühren. Die Anleitung zu Segmentierungsdatensätzen enthält die vollständige Spezifikation.
Polygone sind eine Obermenge von Box--Labels. Mit demselben Label-Ordner trainierst du yolo26n.pt (Ultralytics leitet jede Box aus dem jeweiligen Polygon ab) und yolo26n-sem.pt (die Polygone werden in Klassenkarten umgewandelt) – wir haben beide mit coco8-seg.yaml trainiert. Wenn sich der Plan nach dem Beschriften ändert, ist das Budget nicht verloren.
Beschriftungen vor dem Training prüfen#
Eine Zeile mit einer ungeraden Anzahl von Werten, eine in Pixeln angegebene Koordinate oder ein Umriss um das falsche Objekt hält das Training nicht auf. Dieses Prüfskript lädt den Datensatz mit Ultralytics' eigenem Loader, weist fehlerhafte Zeilen zurück und gibt die Fläche jedes Polygons neben der Box aus, die Ultralytics daraus ableitet:
from pathlib import Path
import numpy as np
from ultralytics.data.utils import check_det_dataset
data = check_det_dataset("coco8-seg.yaml") # resolves paths, downloads if needed
for label in sorted(Path(data["path"], "labels", "train").glob("*.txt"))[:2]:
for n, row in enumerate(label.read_text().splitlines(), 1):
cls, *coords = row.split()
if len(coords) % 2 or len(coords) < 6:
print(f"{label.name}:{n} BAD: needs an even number of values and at least 3 vertices")
continue
xy = np.array(coords, dtype=float).reshape(-1, 2)
if xy.min() < 0 or xy.max() > 1:
print(f"{label.name}:{n} BAD: coordinates must be normalized to 0-1")
continue
x, y = xy[:, 0], xy[:, 1]
area = 0.5 * abs(np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1))) # shoelace formula
w, h = xy.max(0) - xy.min(0) # the box Ultralytics derives from the polygon
name = data["names"][int(cls)]
print(f"{label.stem} {name:9s} {len(xy):3d} vertices polygon {area:.3f} box {w * h:.3f} fill {area / (w * h):.2f}")000000000009 bowl 12 vertices polygon 0.391 box 0.569 fill 0.69
000000000009 bowl 14 vertices polygon 0.145 box 0.238 fill 0.61
000000000009 broccoli 50 vertices polygon 0.161 box 0.252 fill 0.64
000000000009 bowl 55 vertices polygon 0.079 box 0.531 fill 0.15
000000000009 orange 13 vertices polygon 0.007 box 0.011 fill 0.64
000000000009 orange 13 vertices polygon 0.005 box 0.009 fill 0.61
000000000009 orange 18 vertices polygon 0.012 box 0.019 fill 0.61
000000000009 orange 12 vertices polygon 0.010 box 0.022 fill 0.44
000000000025 giraffe 82 vertices polygon 0.072 box 0.234 fill 0.31
000000000025 giraffe 19 vertices polygon 0.010 box 0.027 fill 0.38Flächen sind als Anteil des Bildes angegeben. Die erste Schüssel bedeckt also 39 % ihres Fotos. Füllgrad ist die Polygonfläche geteilt durch die Boxfläche. Auf diese Spalte solltest du achten:
- Die meisten kompakten Objekte (Schüsseln, Orangen, Brokkoli) liegen bei etwa 0,6–0,7.
- Der Wert 0,31 für die Giraffe ist plausibel: Lange Beine und ein langer Hals lassen den größten Teil ihrer Box leer. Genau deshalb braucht dieses Objekt überhaupt eine Maske.
- Der Wert 0,15 für die dritte Schüssel ist die Zeile, die ein Reviewer öffnen sollte. Von der Schüssel ist um das Essen herum nur ein schmaler Rand sichtbar, ihr Umriss bildet also ein schmales Band innerhalb einer großen Box. Das ist hier korrekt. Bei deinen Daten weist ein derart niedriger Füllgrad jedoch genauso oft darauf hin, dass der Umriss um das falsche Objekt gezogen wurde.
Korrigiere vor dem Training jede fehlerhafte Zeile. Sortiere anschließend nach Füllgrad und öffne für jede Klasse die untersten paar Prozent der Zeilen in einem Annotationswerkzeug: Ein niedriger Füllgrad bedeutet entweder ein dünnes oder verdecktes Objekt (beibehalten) oder eine fehlerhafte Kontur (korrigieren).
Polygone erhalten, ohne jede Kante nachzuzeichnen#
Das manuelle Nachzeichnen von Umrissen ist der aufwendige Teil der Datenbeschriftung. Prüfe, welche Abkürzung infrage kommt, bevor jemand damit anfängt:
| Du hast bereits | Werkzeug |
|---|---|
| COCO-JSON mit Segmentierung | convert_coco(labels_dir, use_segments=True) aus ultralytics.data.converter |
| PNG-Masken (Pixelwert = Klassenindex + 1, 0 = Hintergrund) | convert_segment_masks_to_yolo_seg(masks_dir, output_dir, classes) – sich berührende Objekte derselben Klasse werden zu einem Polygon zusammengefasst. Trenne sie bei der Überprüfung. |
| Nur Boxbeschriftungen | yolo_bbox2segment(im_dir) – übergibt SAM jede Box als Prompt, um ein Polygon zu erzeugen |
| Noch nichts | Intelligente Annotation und Stapelbeschriftung – einmal klicken, Polygon überprüfen |
Im Ultralytics Platform führt der intelligente Modus SAM aus: Ein positiver Klick auf das Objekt und ein negativer Klick auf das, was ausgeschlossen werden soll, erzeugen eine Maske, die du anschließend überprüfst.

Eine Maske, die in den Hintergrund übergeht, bringt dem Modell genau das Gleiche bei. Prüfe maschinell erzeugte Polygone anhand der Qualitätskriterien unter Boxen oder Masken und führe anschließend die obige Labelprüfung erneut aus.
Mit COCO8-seg trainieren#

Das Training folgt dem Arbeitsablauf für die Objekterkennung, verwendet aber ein -seg-Modell und einen Segmentierungsdatensatz. Eine Epoche mit imgsz=320 auf einer Laptop-CPU ist in wenigen Sekunden abgeschlossen – genug, um die gesamte Pipeline zu überprüfen:
from ultralytics import YOLO
model = YOLO("yolo26n-seg.pt")
model.train(data="coco8-seg.yaml", epochs=1, imgsz=320, device="cpu")
metrics = model.val()
print(f"box mAP50-95: {metrics.box.map:.3f}")
print(f"mask mAP50-95: {metrics.seg.map:.3f}") Class Images Instances Box(P R mAP50 mAP50-95) Mask(P R mAP50 mAP50-95)
all 4 17 0.909 0.449 0.661 0.482 0.685 0.409 0.557 0.377
horse 1 2 1 0.993 0.995 0.564 0.619 0.857 0.663 0.199
box mAP50-95: 0.482
mask mAP50-95: 0.377Bei vier Validierungsbildern sind diese Zahlen nur Rauschen. Wichtig ist, dass der Lauf abgeschlossen wird und weights/best.pt unter runs/segment/ gespeichert wird. Für echte Daten befolgst du die Anleitung zur Segmentierungsaufgabe und trainierst den vollständigen Zeitplan auf einer GPU.
Box- und Maskenmetriken nebeneinander betrachten#
Die Validierungstabelle hat zwei Bereiche. Box bewertet jede vorhergesagte Box im Vergleich zur Box, die sich aus der Beschriftung ergibt; Maske vergleicht die vorhergesagten Pixel mit dem beschrifteten Polygon. Beide verwenden dieselbe mAP-Berechnung. Nur die IoU unterscheidet sich.
Die Masken-mAP50-95 ist fast immer niedriger als die Box-mAP50-95, denn die Pixel-IoU ist strenger: Eine um einige Pixel verschobene Box überlappt immer noch gut, während eine Maske, der ein Arm fehlt oder die auf die Straße übergreift, bei den Schwellenwerten von 0,75–0,95 schnell IoU verliert. Die Zeile horse zeigt den Extremfall: Box-mAP50-95 0,564, Maske 0,199. Das Modell hat beide Pferde gefunden und gut eingerahmt, aber Beine und Schwänze nicht umrissen. Nutze die Abweichung, um zu entscheiden, was korrigiert werden muss:
- Beide niedrig: Das Problem liegt darin, Objekte zu finden, nicht sie zu umreißen. Ergänze zuerst Daten zu den Bedingungen, unter denen Objekte übersehen werden.
- Box gut, Maske deutlich schlechter: Das Modell findet Objekte, umreißt sie aber schlecht. Prüfe die Beschriftungen, probiere ein größeres Modell aus oder trainiere und validiere mit einem höheren
imgsz. - Maske verbessert sich, während die Box stagniert: Das ist in Ordnung – bei einem Segmentierungsprodukt ist die Masken-mAP50-95 das Freigabekriterium.
overlap_mask=True führt beim Training Instanzmasken in einem Bild zusammen, und mask_ratio=4 verkleinert Trainingsmasken. Beides verändert nicht die Auflösung vorhergesagter Masken – dafür ist retina_masks zuständig, das in der nächsten Lektion behandelt wird. Lass beide Einstellungen unverändert, sofern du keinen gemessenen Grund für eine Änderung hast.
Lösung anzeigen
Um alle Aufteilungen zu prüfen, ersetze den Ordner in der Schleife durch Path(data["path"], "labels").rglob("*.txt"). Trainiere dann:
from ultralytics import YOLO
model = YOLO("yolo26n-seg.pt")
model.train(data="coco8-seg.yaml", epochs=1, imgsz=320, device="cpu")
metrics = model.val()
print(f"box mAP50-95: {metrics.box.map:.3f}") # 0.482 in our run
print(f"mask mAP50-95: {metrics.seg.map:.3f}") # 0.377 in our runDie Abweichung von 0,1 ist zu erwarten: Die Masken-IoU bestraft jedes Pixel an der Grenze, die Box-IoU nur die vier Kanten. In unserem Lauf hat horse die größte Abweichung (Box 0,564, Maske 0,199). Die Box-mAP ist gut und die Maske liegt deutlich darunter. Das Entscheidungsdiagramm weist daher auf die Qualität der Umrisse hin: Prüfe zuerst diese Polygone, dann probiere ein größeres Modell oder ein höheres imgsz.