Segmentierungsobjekte mit Ultralytics YOLO isolieren#
Instanzsegmentierung erzeugt für jedes erkannte Objekt eine pixelgenaue Maske. Dadurch kannst du jedes Objekt einzeln aus einem Bild herauslösen. Diese Anleitung zeigt dir, wie du Segmentierungsergebnisse von Ultralytics YOLO mit dem Vorhersagemodus und OpenCV in isolierte Objekte umwandelst – mit schwarzem oder transparentem Hintergrund, um sie als PNG zu speichern.
Ansehen: So entfernst du den Hintergrund und stellst Objekte mit Ultralytics YOLO-Segmentierung und OpenCV in Python frei 🚀
Warum Segmentierungsobjekte isolieren?#
Einzelne Objekte aus einem Bild herauszulösen, eröffnet zahlreiche nachgelagerte Arbeitsabläufe:
- Hintergrundentfernung für Produktfotos, Kataloge oder kreative Bearbeitung.
- Zuschnitte einzelner Objekte, um aus deinen Erkennungen Klassifizierungsdatensätze zu erstellen.
- Gezielte Verarbeitung, damit spätere Schritte wie OCR, Farbanalyse oder Vermessung nur das Objekt und nicht die umgebende Szene erfassen.
- Export als transparentes PNG, um Objekte auf neue Hintergründe zu setzen.
Die Methode funktioniert mit jedem Ultralytics-YOLO-Segmentierungsmodell und umfasst vier Schritte: Inferenz ausführen → jede Kontur extrahieren → das Objekt isolieren → das Ergebnis speichern.
Segmentierungsinferenz ausführen#
Installiere die erforderlichen Bibliotheken, lade dann ein Segmentierungsmodell (das Suffix -seg ist erforderlich, um Masken zu erzeugen) und führe eine Vorhersage für dein Quellbild aus:
from ultralytics import YOLO
# Segmentierungsmodell laden
model = YOLO("yolo26n-seg.pt")
# Inferenz für eine Quelle ausführen
results = model.predict(source="path/to/image.jpg")Wenn du model.predict() ohne source aufrufst, verwendet Ultralytics die mit dem Paket gelieferten Beispielbilder (bus.jpg und zidane.jpg). Das ist praktisch, um den Arbeitsablauf schnell zu testen.
Objektkonturen extrahieren#
Jedes Element in results entspricht einem Bild. Beim Durchlaufen eines Ergebnisses erhältst du jeweils eine Erkennung. Kopiere für jede Erkennung das Originalbild, lies die Klassenbezeichnung aus und zeichne die Maskenkontur des Objekts auf eine leere Binärmaske. Der weiße Bereich dieser Maske markiert genau die Pixel, die zum Objekt gehören.
Die Codeausschnitte in diesem und im nächsten Abschnitt werden innerhalb der folgenden Erkennungsschleife ausgeführt. Das vollständige Skript zum Kopieren und Einfügen findest du unter Vollständiges Beispiel.
from pathlib import Path
import cv2
import numpy as np
for r in results:
img = np.copy(r.orig_img)
img_name = Path(r.path).stem # Basisname des Quellbilds
# Jedes erkannte Objekt im Bild durchlaufen
for ci, c in enumerate(r):
label = c.names[c.boxes.cls.tolist().pop()] # Klassenname
# Binärmaske erstellen und die Objektkontur darauf zeichnen
b_mask = np.zeros(img.shape[:2], np.uint8)
contour = c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)
cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)c.masks.xy[0]gibt die Kontur der Maske als Punktkoordinaten vom Typ(x, y)für das Objekt in diesem Einzelerkennungsergebnis zurück..astype(np.int32)wandelt die Punkte ausfloat32um, die OpenCVsdrawContours()nicht akzeptiert..reshape(-1, 1, 2)bringt die Punkte in das Layout[N, 1, 2], dasdrawContours()erwartet, wobeiNdie Anzahl der Konturpunkte ist.
Wenn du [contour] mit dem Index -1 übergibst, werden alle Punkte der angegebenen Kontur gezeichnet und cv2.FILLED füllt jedes eingeschlossene Pixel weiß aus.
Das Objekt isolieren#
Sobald die Binärmaske fertig ist, kombinierst du sie mit dem Originalbild. Je nachdem, welchen Hintergrund du möchtest, gibt es zwei gängige Varianten:
Wandle die Maske in drei Kanäle um und behalte nur die Pixel, die das Objekt überlagern. Alles außerhalb der Kontur wird schwarz:
# Objekt vor schwarzem Hintergrund isolieren
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)
Wenn du nur den Bereich des Objekts statt des gesamten Bildes behalten möchtest, schneide das Bild anhand des Begrenzungsrahmens der Erkennung zu:
# Koordinaten des Begrenzungsrahmens
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
# Isoliertes Bild auf den Objektbereich zuschneiden
iso_crop = isolated[y1:y2, x1:x2]
Das ist bereits integriert. Übergib save_crop=True an predict(), und Ultralytics speichert automatisch Zuschnitte der Begrenzungsrahmen – ganz ohne Maskierung.
Ergebnis speichern (optional)#
Was du mit jedem isolierten Objekt machst, bleibt dir überlassen. Ein häufiger nächster Schritt ist, das Objekt zur späteren Verwendung auf der Festplatte zu speichern:
# Save the isolated object to file
cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated)Hier ist img_name der Dateistamm des Quellbilds, label der Klassenname und ci der Erkennungsindex. So erhalten mehrere Instanzen derselben Klasse eindeutige Dateinamen. Ersetze isolated durch iso_crop, wenn du den optionalen Zuschnitt oben angewendet hast.
Vollständiges Beispiel#
Das folgende Skript fasst alle Schritte zu einem einzigen ausführbaren Codeblock zusammen. Standardmäßig wird ein schwarzer Hintergrund verwendet. Ändere die eine markierte Zeile zu np.dstack([img, b_mask]), um stattdessen ein transparentes PNG zu erhalten:
from pathlib import Path
import cv2
import numpy as np
from ultralytics import YOLO
model = YOLO("yolo26n-seg.pt")
results = model.predict(source="path/to/image.jpg")
for r in results:
img = np.copy(r.orig_img)
img_name = Path(r.path).stem
for ci, c in enumerate(r):
label = c.names[c.boxes.cls.tolist().pop()]
# Build a binary mask from the object contour
b_mask = np.zeros(img.shape[:2], np.uint8)
contour = c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)
cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
# Isolate the object (black background)
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img) # transparent PNG: isolated = np.dstack([img, b_mask])
# Save or add your custom post-processing here
cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated)
# Optional: crop to the bounding box before saving
# x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
# cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated[y1:y2, x1:x2])Wenn du den Ablauf wiederholt verwenden möchtest, fasse den Schleifenrumpf in einer Funktion zusammen, die du für viele Bilder aufrufen kannst.
Fazit#
Du hast nun eine vollständige Anleitung zum Isolieren segmentierter Objekte mit Ultralytics YOLO: Führe Inferenz aus, erstelle aus jeder Kontur eine Binärmaske und extrahiere anschließend das Objekt vor schwarzem oder transparentem Hintergrund. Optional kannst du es auf seinen Begrenzungsrahmen zuschneiden. In der Dokumentation zu Segmentierungsaufgaben und zum Vorhersagemodus erfährst du, wie du den Arbeitsablauf an deine eigenen Klassen anpasst.
Häufig gestellte Fragen#
Lade ein Segmentierungsmodell, führe Inferenz aus, erstelle aus der Kontur jeder Erkennung eine Binärmaske und kombiniere sie mit dem Originalbild:
import cv2 import numpy as np from ultralytics import YOLO model = YOLO("yolo26n-seg.pt") results = model.predict(source="path/to/your/image.jpg") img = np.copy(results[0].orig_img) b_mask = np.zeros(img.shape[:2], np.uint8) contour = results[0].masks.xy[0].astype(np.int32).reshape(-1, 1, 2) cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED) mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR) isolated = cv2.bitwise_and(mask3ch, img)Das vollständige Beispiel zeigt die vollständige Schleife für jede Erkennung.
Es gibt zwei Hauptvarianten. Für einen schwarzen Hintergrund wandelst du die Maske in drei Kanäle um und verwendest
cv2.bitwise_and(). Für einen transparenten Hintergrund (beim Speichern als PNG) fügst du die Maske mitnp.dstack([img, b_mask])als vierten Alpha-Kanal hinzu. Beide Varianten werden unter Das Objekt isolieren gezeigt.Lies die Koordinaten des Begrenzungsrahmens aus der Erkennung aus und schneide das isolierte Bild entsprechend zu:
x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32) iso_crop = isolated[y1:y2, x1:x2]Weitere Informationen zu den Ergebnissen der Begrenzungsrahmen findest du in der Dokumentation zum Vorhersagemodus.
Ultralytics YOLO ermöglicht eine schnelle Instanzsegmentierung in Echtzeit und erzeugt präzise Masken und Begrenzungsrahmen. Eine einfache Python-API macht aus Inferenz-Ergebnissen mit wenigen Zeilen OpenCV-Code freigestellte Objekte.
Ja. Verwende das Argument
save_cropinpredict(), um Zuschnitte der Begrenzungsrahmen mit ihrem ursprünglichen Hintergrund zu speichern:results = model.predict(source="path/to/your/image.jpg", save_crop=True)Weitere Informationen findest du im Abschnitt Argumente für die Inferenz im Vorhersagemodus.