Isolierung von Segmentierungsobjekten
Nach der Durchführung der Segmentaufgabe ist es manchmal wünschenswert, die isolierten Objekte aus den Inferenzergebnissen zu extrahieren. Diese Anleitung enthält ein allgemeines Rezept, wie dies mit dem Ultralytics Predict Mode erreicht werden kann.
Rezeptdurchlauf
-
Im AbschnittUltralytics Quickstart Installation finden Sie eine kurze Anleitung zur Installation der erforderlichen Bibliotheken.
-
Ein Modell laden und ausführen
predict()
Methode auf eine Quelle.from ultralytics import YOLO # Load a model model = YOLO("yolo11n-seg.pt") # Run inference results = model.predict()
Keine Vorhersage-Argumente?
Ohne Angabe einer Quelle werden die Beispielbilder aus der Bibliothek verwendet:
Dies ist hilfreich für schnelle Tests mit dem
predict()
Methode.Weitere Informationen über Segmentierungsmodelle finden Sie auf der Website Segment Aufgabe Seite. Erfahren Sie mehr über
predict()
Methode, siehe Vorhersage-Modus Abschnitt der Dokumentation.
-
Iterieren Sie nun über die Ergebnisse und die Konturen. Für Workflows, die ein Bild in einer Datei speichern wollen, muss das Quellbild
base-name
und die Erkennungclass-label
zur späteren Verwendung abgerufen werden (optional).from pathlib import Path import numpy as np # (2) Iterate detection results (helpful for multiple images) for r in res: img = np.copy(r.orig_img) img_name = Path(r.path).stem # source image base-name # Iterate each object contour (multiple detections) for ci, c in enumerate(r): # (1) Get detection class name label = c.names[c.boxes.cls.tolist().pop()]
- Weitere Informationen zur Arbeit mit Erkennungsergebnissen finden Sie im Abschnitt Boxen für den Vorhersagemodus.
- Um mehr zu erfahren über
predict()
Ergebnisse siehe Arbeiten mit Ergebnissen für den Vorhersagemodus
For-Schleife
Bei einem Einzelbild wird die erste Schleife nur einmal durchlaufen. Ein einzelnes Bild mit nur einer einzigen Erkennung durchläuft jede Schleife nur einmal.
-
Beginnen Sie mit der Erstellung einer binären Maske aus dem Quellbild und zeichnen Sie dann eine gefüllte Kontur auf die Maske. Dadurch kann das Objekt von den anderen Teilen des Bildes isoliert werden. Ein Beispiel aus
bus.jpg
für einen der entdecktenperson
Klassenobjekte ist rechts dargestellt.import cv2 # Create binary mask b_mask = np.zeros(img.shape[:2], np.uint8) # (1) Extract contour result contour = c.masks.xy.pop() # (2) Changing the type contour = contour.astype(np.int32) # (3) Reshaping contour = contour.reshape(-1, 1, 2) # Draw contour onto mask _ = cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
-
Für weitere Informationen über
c.masks.xy
siehe Maskenabschnitt aus dem Vorhersagemodus. -
Hier werden die Werte in
np.int32
für die Kompatibilität mitdrawContours()
Funktion von OpenCV. -
Die OpenCV
drawContours()
Funktion erwartet, dass die Konturen eine Form von[N, 1, 2]
erweitern Sie den Abschnitt unten für weitere Details.
Erweitern Sie, um zu verstehen, was passiert, wenn Sie die
contour
variabel.-
c.masks.xy
:: Liefert die Koordinaten der Maskenkonturpunkte im Format(x, y)
. Weitere Einzelheiten finden Sie in der Maskenabschnitt aus dem Vorhersagemodus. -
.pop()
:: Alsmasks.xy
eine Liste ist, die ein einzelnes Element enthält, wird dieses Element mit der Methodepop()
Methode. -
.astype(np.int32)
:: Verwendung vonmasks.xy
wird mit einem Datentyp vonfloat32
aber das ist nicht kompatibel mit dem OpenCVdrawContours()
Funktion, so dass sich der Datentyp inint32
für Kompatibilität. -
.reshape(-1, 1, 2)
:: Formatiert die Daten in die gewünschte Form von[N, 1, 2]
wobeiN
die Anzahl der Konturpunkte, wobei jeder Punkt durch einen einzigen Eintrag dargestellt wird1
und der Eintrag setzt sich zusammen aus2
Werte. Die Website-1
bedeutet, dass die Anzahl der Werte entlang dieser Dimension flexibel ist.
Erweitern Sie für eine Erklärung der
drawContours()
Konfiguration.-
Verkapselung der
contour
Variable in eckigen Klammern,[contour]
wurde bei den Tests festgestellt, dass sie die gewünschte Konturenmaske effektiv erzeugt. -
Der Wert
-1
angegeben für diedrawContours()
weist die Funktion an, alle im Bild vorhandenen Konturen zu zeichnen. -
Die
tuple
(255, 255, 255)
steht für die Farbe Weiß, die für das Zeichnen der Kontur in dieser binären Maske gewünscht ist. -
Der Zusatz von
cv2.FILLED
färbt alle von der Konturbegrenzung eingeschlossenen Pixel gleich ein, in diesem Fall sind alle eingeschlossenen Pixel weiß. -
Siehe OpenCV-Dokumentation auf
drawContours()
für weitere Informationen.
-
-
Als nächstes gibt es 2 Optionen, wie mit dem Bild von diesem Punkt aus weiter verfahren werden soll, und eine weitere Option für jede.
Optionen zur Objektisolierung
Beispiel
# Create 3-channel mask mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR) # Isolate object with binary mask isolated = cv2.bitwise_and(mask3ch, img)
Wie funktioniert das?
-
Zunächst wird die binäre Maske von einem einkanaligen Bild in ein dreikanaliges Bild umgewandelt. Diese Umwandlung ist für den nachfolgenden Schritt erforderlich, bei dem die Maske und das Originalbild kombiniert werden. Beide Bilder müssen die gleiche Anzahl von Kanälen haben, um mit dem Überblendvorgang kompatibel zu sein.
-
Das Originalbild und die binäre Dreikanalmaske werden mit der OpenCV-Funktion
bitwise_and()
. Dieser Vorgang bewahrt nur Pixelwerte, die größer als Null sind(> 0)
aus beiden Bildern. Da die Maskenpixel größer als Null sind(> 0)
nur innerhalb der Konturregion sind die vom Originalbild übrig gebliebenen Pixel diejenigen, die sich mit der Kontur überschneiden.
Mit schwarzen Pixeln isolieren: Unteroptionen
Bild in voller Größe
Es sind keine weiteren Schritte erforderlich, wenn Sie das Bild in voller Größe behalten.
Ausgeschnittenes Objekt Bild
Zusätzliche Schritte sind erforderlich, um das Bild so zuzuschneiden, dass es nur den Objektbereich enthält.
# (1) Bounding box coordinates x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32) # Crop image to object region iso_crop = isolated[y1:y2, x1:x2]
- Weitere Informationen zu Bounding-Box-Ergebnissen finden Sie unter Abschnitt Boxen im Vorhersagemodus
Was bewirkt dieser Code?
-
Die
c.boxes.xyxy.cpu().numpy()
Aufruf ruft die Bounding Boxes als NumPy-Array in derxyxy
Format, wobeixmin
,ymin
,xmax
undymax
stellen die Koordinaten des Begrenzungsrechtecks dar. Siehe Boxen Abschnitt aus dem Vorhersagemodus für weitere Einzelheiten. -
Die
squeeze()
Operation entfernt alle unnötigen Dimensionen aus dem NumPy-Array und stellt sicher, dass es die erwartete Form hat. -
Umrechnung der Koordinatenwerte mit
.astype(np.int32)
ändert den Datentyp der Feldkoordinaten vonfloat32
zuint32
Dadurch sind sie für das Zuschneiden von Bildern mithilfe von Indexschnitten geeignet. -
Schließlich wird die Bounding-Box-Region mit Hilfe von Index-Slicing aus dem Bild ausgeschnitten. Die Begrenzungen werden durch den
[ymin:ymax, xmin:xmax]
Koordinaten des Erkennungsbegrenzungsrahmens.
# Isolate object with transparent background (when saved as PNG) isolated = np.dstack([img, b_mask])
Wie funktioniert das?
- Die Verwendung des NumPy
dstack()
(Array-Stapelung entlang der Tiefenachse) in Verbindung mit der erzeugten Binärmaske ein Bild mit vier Kanälen. Dies ermöglicht, dass alle Pixel außerhalb der Objektkontur beim Speichern alsPNG
Datei.
Mit transparenten Pixeln isolieren: Unteroptionen
Bild in voller Größe
Es sind keine weiteren Schritte erforderlich, wenn Sie das Bild in voller Größe behalten.
Ausgeschnittenes Objekt Bild
Zusätzliche Schritte sind erforderlich, um das Bild so zuzuschneiden, dass es nur den Objektbereich enthält.
# (1) Bounding box coordinates x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32) # Crop image to object region iso_crop = isolated[y1:y2, x1:x2]
- Weitere Informationen zu Bounding-Box-Ergebnissen finden Sie unter Abschnitt Boxen im Vorhersagemodus
Was bewirkt dieser Code?
-
Bei der Verwendung von
c.boxes.xyxy.cpu().numpy()
werden die Boundingboxen als NumPy-Array zurückgegeben, wobei diexyxy
Box-Koordinatenformat, die den Punkten entsprechenxmin, ymin, xmax, ymax
für den Begrenzungsrahmen (Rechteck), siehe Boxen Abschnitt aus dem Vorhersagemodus für weitere Informationen. -
Hinzufügen von
squeeze()
stellt sicher, dass alle überflüssigen Dimensionen aus dem NumPy-Array entfernt werden. -
Umrechnung der Koordinatenwerte mit
.astype(np.int32)
ändert den Datentyp der Feldkoordinaten vonfloat32
zuint32
die beim Zuschneiden des Bildes mit Hilfe von Indexscheiben kompatibel sind. -
Schließlich wird der Bildbereich für die Bounding Box mit Hilfe von Index Slicing beschnitten, wobei die Grenzen mit Hilfe der Funktion
[ymin:ymax, xmin:xmax]
Koordinaten des Erkennungsbegrenzungsrahmens.
Was ist, wenn ich das ausgeschnittene Objekt einschließlich des Hintergrunds haben möchte?
Dies ist eine eingebaute Funktion der Bibliothek Ultralytics . Siehe die
save_crop
Argument für Argumente für die Vorhersage des Modus Inferenz für Einzelheiten.
-
-
Was als nächstes zu tun ist, bleibt ganz Ihnen als Entwickler überlassen. Ein einfaches Beispiel für einen möglichen nächsten Schritt (Speichern des Bildes in einer Datei zur späteren Verwendung) wird gezeigt.
- HINWEIS: Dieser Schritt ist optional und kann übersprungen werden, wenn er für Ihren speziellen Anwendungsfall nicht erforderlich ist.
Beispiel Letzter Schritt
- In diesem Beispiel ist die
img_name
ist der Basisname der Quellbilddatei,label
ist der erkannte Klassenname, undci
ist der Index der Objekterkennung (im Falle mehrerer Instanzen mit demselben Klassennamen).
Vollständiger Beispielcode
Hier werden alle Schritte aus dem vorherigen Abschnitt in einem einzigen Codeblock zusammengefasst. Bei wiederholter Verwendung wäre es optimal, eine Funktion zu definieren, die einige oder alle Befehle aus dem for
-Schleifen, aber das ist eine Übung, die dem Leser überlassen bleibt.
from pathlib import Path
import cv2
import numpy as np
from ultralytics import YOLO
m = YOLO("yolo11n-seg.pt") # (4)!
res = m.predict() # (3)!
# Iterate detection results (5)
for r in res:
img = np.copy(r.orig_img)
img_name = Path(r.path).stem
# Iterate each object contour (6)
for ci, c in enumerate(r):
label = c.names[c.boxes.cls.tolist().pop()]
b_mask = np.zeros(img.shape[:2], np.uint8)
# Create contour mask (1)
contour = c.masks.xy.pop().astype(np.int32).reshape(-1, 1, 2)
_ = cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
# Choose one:
# OPTION-1: Isolate object with black background
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)
# OPTION-2: Isolate object with transparent background (when saved as PNG)
isolated = np.dstack([img, b_mask])
# OPTIONAL: detection crop (from either OPT1 or OPT2)
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
iso_crop = isolated[y1:y2, x1:x2]
# TODO your actions go here (2)
- Die Zeile, die
contour
ist hier in einer einzigen Zeile zusammengefasst, während sie oben auf mehrere Zeilen aufgeteilt war. - Was hier hingehört, entscheiden Sie selbst!
- Weitere Informationen finden Sie unter Vorhersagemodus.
- Siehe Segmentaufgabe für weitere Informationen.
- Erfahren Sie mehr über das Arbeiten mit Ergebnissen
- Erfahren Sie mehr über die Ergebnisse der Segmentierungsmaske
FAQ
Wie isoliere ich Objekte mit Ultralytics YOLO11 für Segmentierungsaufgaben?
Gehen Sie folgendermaßen vor, um Objekte mit Ultralytics YOLO11 zu isolieren:
-
Laden Sie das Modell und führen Sie die Inferenz durch:
-
Erzeugen Sie eine binäre Maske und zeichnen Sie Konturen:
-
Isolieren Sie das Objekt mit Hilfe der binären Maske:
Weitere Informationen finden Sie in der Anleitung zum Vorhersagemodus und zur Segmentaufgabe.
Welche Möglichkeiten gibt es, die isolierten Objekte nach der Segmentierung zu speichern?
Ultralytics YOLO11 bietet zwei Hauptoptionen für die Speicherung isolierter Objekte:
-
Mit schwarzem Hintergrund:
-
Mit einem transparenten Hintergrund:
Weitere Einzelheiten finden Sie im Abschnitt Vorhersagemodus.
Wie kann ich isolierte Objekte mit Ultralytics YOLO11 auf ihre Begrenzungsrahmen zuschneiden?
Zum Beschneiden isolierter Objekte auf ihre Begrenzungsrahmen:
-
Abrufen von Bounding-Box-Koordinaten:
-
Schneiden Sie das isolierte Bild zu:
Weitere Informationen über Bounding-Box-Ergebnisse finden Sie in der Dokumentation zum Vorhersagemodus.
Warum sollte ich Ultralytics YOLO11 für die Objektisolierung bei Segmentierungsaufgaben verwenden?
Ultralytics YOLO11 bietet:
- Hochgeschwindigkeits-Objekterkennung und -segmentierung in Echtzeit.
- Präzise Boundingbox- und Maskengenerierung für eine genaue Objektisolierung.
- Umfassende Dokumentation und benutzerfreundliche API für eine effiziente Entwicklung.
Informieren Sie sich über die Vorteile der Verwendung von YOLO in der Dokumentation zur Segmentaufgabe.
Kann ich isolierte Objekte einschließlich des Hintergrunds mit Ultralytics YOLO11 speichern?
Ja, dies ist eine integrierte Funktion in Ultralytics YOLO11 . Verwenden Sie die save_crop
Argument in der predict()
Methode. Zum Beispiel:
Lesen Sie mehr über die save_crop
Argument in der Argumente für die Vorhersage des Modus Inferenz Abschnitt.