Zum Inhalt springen

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.

Beispiel für die Segmentierung isolierter Objekte

Rezeptdurchlauf

  1. Im AbschnittUltralytics Quickstart Installation finden Sie eine kurze Anleitung zur Installation der erforderlichen Bibliotheken.


  2. 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:

    'ultralytics/assets/bus.jpg'
    'ultralytics/assets/zidane.jpg'
    

    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.


  3. 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 Erkennung class-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()]
    
    1. Weitere Informationen zur Arbeit mit Erkennungsergebnissen finden Sie im Abschnitt Boxen für den Vorhersagemodus.
    2. 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.


  4. 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 entdeckten person Klassenobjekte ist rechts dargestellt.

    Binäres Maskenbild

    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)
    
    1. Für weitere Informationen über c.masks.xy siehe Maskenabschnitt aus dem Vorhersagemodus.

    2. Hier werden die Werte in np.int32 für die Kompatibilität mit drawContours() Funktion von OpenCV.

    3. 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() :: Als masks.xy eine Liste ist, die ein einzelnes Element enthält, wird dieses Element mit der Methode pop() Methode.

    • .astype(np.int32) :: Verwendung von masks.xy wird mit einem Datentyp von float32aber das ist nicht kompatibel mit dem OpenCV drawContours() Funktion, so dass sich der Datentyp in int32 für Kompatibilität.

    • .reshape(-1, 1, 2) :: Formatiert die Daten in die gewünschte Form von [N, 1, 2] wobei N die Anzahl der Konturpunkte, wobei jeder Punkt durch einen einzigen Eintrag dargestellt wird 1und der Eintrag setzt sich zusammen aus 2 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 die drawContours() 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.


  5. 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.

    Beispiel Volles Format Isoliertes Objekt Bild Schwarzer Hintergrund
    Beispiel für die Ausgabe in voller Größe

    Ausgeschnittenes Objekt Bild

    Zusätzliche Schritte sind erforderlich, um das Bild so zuzuschneiden, dass es nur den Objektbereich enthält.

    Beispiel Bild mit isoliertem Objekt und schwarzem Hintergrund beschneiden

    # (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]
    

    1. 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 der xyxy Format, wobei xmin, ymin, xmaxund ymax 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 von float32 zu int32Dadurch 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 als PNG 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.

    Beispiel in voller Größe Isoliertes Objektbild ohne Hintergrund
    Beispiel: Ausgabe in voller Größe + transparenter Hintergrund

    Ausgeschnittenes Objekt Bild

    Zusätzliche Schritte sind erforderlich, um das Bild so zuzuschneiden, dass es nur den Objektbereich enthält.

    Beispiel für das Zuschneiden eines isolierten Objektbildes ohne Hintergrund

    # (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]
    

    1. 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 die xyxy Box-Koordinatenformat, die den Punkten entsprechen xmin, 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 von float32 zu int32 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.


  6. 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
    # Save isolated object to file
    _ = cv2.imwrite(f"{img_name}_{label}-{ci}.png", iso_crop)
    
    • In diesem Beispiel ist die img_name ist der Basisname der Quellbilddatei, label ist der erkannte Klassenname, und ci 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)
  1. Die Zeile, die contour ist hier in einer einzigen Zeile zusammengefasst, während sie oben auf mehrere Zeilen aufgeteilt war.
  2. Was hier hingehört, entscheiden Sie selbst!
  3. Weitere Informationen finden Sie unter Vorhersagemodus.
  4. Siehe Segmentaufgabe für weitere Informationen.
  5. Erfahren Sie mehr über das Arbeiten mit Ergebnissen
  6. 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:

  1. Laden Sie das Modell und führen Sie die Inferenz durch:

    from ultralytics import YOLO
    
    model = YOLO("yolo11n-seg.pt")
    results = model.predict(source="path/to/your/image.jpg")
    
  2. Erzeugen Sie eine binäre Maske und zeichnen Sie Konturen:

    import cv2
    import numpy as np
    
    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)
    
  3. Isolieren Sie das Objekt mit Hilfe der binären Maske:

    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    isolated = cv2.bitwise_and(mask3ch, img)
    

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:

  1. Mit schwarzem Hintergrund:

    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    isolated = cv2.bitwise_and(mask3ch, img)
    
  2. Mit einem transparenten Hintergrund:

    isolated = np.dstack([img, b_mask])
    

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:

  1. Abrufen von Bounding-Box-Koordinaten:

    x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32)
    
  2. Schneiden Sie das isolierte Bild zu:

    iso_crop = isolated[y1:y2, x1:x2]
    

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:

results = model.predict(source="path/to/your/image.jpg", save_crop=True)

Lesen Sie mehr über die save_crop Argument in der Argumente für die Vorhersage des Modus Inferenz Abschnitt.

📅 Erstellt vor 1 Jahr ✏️ Aktualisiert vor 2 Monaten

Kommentare