İçeriğe geç

Segmentasyon Nesnelerini İzole Etme

Segment Görevini gerçekleştirdikten sonra, bazen çıkarım sonuçlarından izole edilmiş nesneleri çıkarmak istenebilir. Bu kılavuz, Ultralytics Predict Modunu kullanarak bunun nasıl gerçekleştirileceğine dair genel bir tarif sunmaktadır.

Örnek İzole Nesne Segmentasyonu

Tarif Gezintisi

  1. Gerekli ithalatlarla başlayın

    from pathlib import Path
    
    import cv2
    import numpy as np
    from ultralytics import YOLO
    
    Ultralytics Kurulum

    Gerekli kütüphanelerin kurulumuna ilişkin hızlı bir kılavuz için Ultralytics Hızlı Başlangıç Kurulumu bölümüne bakın.


  2. Bir model yükleyin ve çalıştırın predict() yöntemini bir kaynak üzerinde kullanabilirsiniz.

    from ultralytics import YOLO
    
    # Load a model
    model = YOLO('yolov8n-seg.pt')
    
    # Run inference
    results = model.predict()
    

    Tahmin Argümanı Yok mu?

    Bir kaynak belirtilmediğinde, kütüphanedeki örnek görüntüler kullanılacaktır:

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

    Bu, aşağıdakilerle hızlı test için yararlıdır predict() yöntem.

    Segmentasyon Modelleri hakkında daha fazla bilgi için Segment Görevi sayfa. Hakkında daha fazla bilgi edinmek için predict() yöntemi için bkz. Tahmin Modu Dokümantasyon bölümü.


  3. Şimdi sonuçlar ve konturlar üzerinde yineleme yapın. Bir görüntüyü dosyaya kaydetmek isteyen iş akışları için, kaynak görüntü base-name ve tespit class-label daha sonra kullanılmak üzere alınır (isteğe bağlı).

    # (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. Tespit sonuçlarıyla çalışma hakkında daha fazla bilgi edinmek için Tahmin Modu için Kutular Bölümüne bakın.
    2. Hakkında daha fazla bilgi edinmek için predict() sonuçlar bakınız Tahmin Modu için Sonuçlarla Çalışma
    For-Loop

    Tek bir görüntü ilk döngüyü yalnızca bir kez yineleyecektir. Yalnızca tek bir algılamaya sahip tek bir görüntü, her döngüyü yalnızca bir kez yineleyecektir.


  4. Kaynak görüntüden ikili bir maske oluşturarak başlayın ve ardından maskenin üzerine dolgulu bir kontur çizin. Bu, nesnenin görüntünün diğer kısımlarından izole edilmesini sağlayacaktır. Bir örnek bus.jpg tespit edilenlerden biri için person sınıf nesneleri sağda gösterilmektedir.

    İkili Maske Görüntüsü

    # 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. Daha fazla bilgi için c.masks.xy bkz. Tahmin Modundan Maskeler Bölümü.

    2. Burada değerler np.int32 ile uyumluluk için drawContours() OpenCV'den fonksiyon.

    3. OpenCV drawContours() fonksiyonu konturların şu şekle sahip olmasını bekler [N, 1, 2] daha fazla ayrıntı için aşağıdaki bölümü genişletin.

    Tanımlarken neler olduğunu anlamak için genişletin contour değişken.

    • c.masks.xy :: Maske kontur noktalarının koordinatlarını şu formatta sağlar (x, y). Daha fazla ayrıntı için bkz. Tahmin Modundan Maskeler Bölümü.

    • .pop() :: Gibi masks.xy tek bir eleman içeren bir liste ise, bu eleman pop() yöntem.

    • .astype(np.int32) :: Kullanma masks.xy veri türü ile dönecektir. float32ancak bu OpenCV ile uyumlu olmayacaktır drawContours() işlevini kullanacağız, bu nedenle veri türünü int32 uyumluluk için.

    • .reshape(-1, 1, 2) :: Verileri istenen şekilde yeniden biçimlendirir [N, 1, 2] nerede N kontur noktalarının sayısıdır ve her nokta tek bir girişle temsil edilir 1ve giriş şunlardan oluşur 2 değerler. Bu değerler -1 bu boyut boyunca değer sayısının esnek olduğunu belirtir.

    Açıklama için genişletin drawContours() Yapılandırma.

    • Kapsülleme contour köşeli parantez içindeki değişken, [contour]'nin test sırasında istenen kontur maskesini etkili bir şekilde oluşturduğu görülmüştür.

    • Değer -1 için belirtilen drawContours() parametresi, işleve görüntüde bulunan tüm konturları çizme talimatı verir.

    • Bu tuple (255, 255, 255) bu ikili maskede kontur çizmek için istenen renk olan beyaz rengi temsil eder.

    • Eklenmesi cv2.FILLED kontur sınırı tarafından çevrelenen tüm pikselleri aynı şekilde renklendirir; bu durumda, çevrelenen tüm pikseller beyaz olacaktır.

    • Bkz. OpenCV Dokümantasyonu drawContours() daha fazla bilgi için.


  5. Daha sonra, bu noktadan sonra görüntüyle nasıl ilerleneceğine dair 2 seçenek ve her biri için bir sonraki seçenek vardır.

    Nesne İzolasyonu Seçenekleri

    # Create 3-channel mask
    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    
    # Isolate object with binary mask
    isolated = cv2.bitwise_and(mask3ch, img)
    
    Bu nasıl çalışıyor?
    • İlk olarak, ikili maske tek kanallı bir görüntüden üç kanallı bir görüntüye dönüştürülür. Bu dönüştürme, maskenin ve orijinal görüntünün birleştirildiği sonraki adım için gereklidir. Karıştırma işlemiyle uyumlu olması için her iki görüntünün de aynı sayıda kanala sahip olması gerekir.

    • Orijinal görüntü ve üç kanallı ikili maske OpenCV işlevi kullanılarak birleştirilir bitwise_and(). Bu işlem aşağıdakileri korur sadece sıfırdan büyük piksel değerleri (> 0) her iki görüntüden de. Maske pikselleri sıfırdan büyük olduğu için (> 0) sadece Kontur bölgesi içinde, orijinal görüntüden kalan pikseller konturla örtüşen piksellerdir.

    Siyah Piksellerle İzole Et: Alt seçenekler

    Tam Boyutlu Görüntü

    Tam boyutlu görüntüyü saklamak için ek bir adım gerekmez.

    Örnek Tam Boyutlu İzole Nesne Görüntüsü Siyah Arka Plan
    Örnek tam boyutlu çıktı

    Kırpılmış nesne görüntüsü

    Görüntüyü yalnızca nesne bölgesini içerecek şekilde kırpmak için ek adımlar gerekir.

    Örnek Kırpılmış İzole Nesne Görüntüsü Siyah Arka Plan

    # (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. Sınırlayıcı kutu sonuçları hakkında daha fazla bilgi için Tahmin Modundan Kutular Bölümüne bakın
    Bu kod ne işe yarıyor?
    • Bu c.boxes.xyxy.cpu().numpy() çağrısı, sınırlayıcı kutuları bir NumPy dizisi olarak xyxy biçimi, burada xmin, ymin, xmaxve ymax sınırlayıcı kutu dikdörtgeninin koordinatlarını temsil eder. Bkz. Tahmin Modundan Kutular Bölümü daha fazla ayrıntı için.

    • Bu squeeze() işlemi NumPy dizisindeki gereksiz boyutları kaldırarak dizinin beklenen şekle sahip olmasını sağlar.

    • Koordinat değerlerini kullanarak dönüştürme .astype(np.int32) kutu koordinatları veri türünü float32 için int32Bu da onları dizin dilimleri kullanarak görüntü kırpma için uyumlu hale getirir.

    • Son olarak, sınırlayıcı kutu bölgesi dizin dilimleme kullanılarak görüntüden kırpılır. Sınırlar şu şekilde tanımlanır [ymin:ymax, xmin:xmax] algılama sınırlayıcı kutusunun koordinatları.

    # Isolate object with transparent background (when saved as PNG)
    isolated = np.dstack([img, b_mask])
    
    Bu nasıl çalışıyor?
    • NumPy'yi Kullanma dstack() fonksiyonu (derinlik ekseni boyunca dizi istifleme) oluşturulan ikili maske ile birlikte dört kanallı bir görüntü oluşturacaktır. Bu, nesne konturunun dışındaki tüm piksellerin görüntü olarak kaydedilirken şeffaf olmasını sağlar. PNG Dosya.

    Şeffaf Piksellerle İzole Et: Alt seçenekler

    Tam Boyutlu Görüntü

    Tam boyutlu görüntüyü saklamak için ek bir adım gerekmez.

    Örnek Tam Boyutlu İzole Nesne Görüntüsü Arka Plan Yok
    Örnek tam boyutlu çıktı + şeffaf arka plan

    Kırpılmış nesne görüntüsü

    Görüntüyü yalnızca nesne bölgesini içerecek şekilde kırpmak için ek adımlar gerekir.

    Örnek Kırpma İzole Nesne Görüntüsü Arka Plan Yok

    # (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. Sınırlayıcı kutu sonuçları hakkında daha fazla bilgi için Tahmin Modundan Kutular Bölümüne bakın
    Bu kod ne işe yarıyor?
    • Kullanırken c.boxes.xyxy.cpu().numpy()kullanılarak sınırlayıcı kutular bir NumPy dizisi olarak döndürülür. xyxy noktalarına karşılık gelen kutu koordinatları biçimi xmin, ymin, xmax, ymax sınırlayıcı kutu (dikdörtgen) için bkz. Tahmin Modundan Kutular Bölümü daha fazla bilgi için.

    • Ekleme squeeze() NumPy dizisinden gereksiz boyutların kaldırılmasını sağlar.

    • Koordinat değerlerini kullanarak dönüştürme .astype(np.int32) kutu koordinatları veri türünü float32 için int32 indeks dilimleri kullanarak görüntüyü kırparken uyumlu olacaktır.

    • Son olarak, sınırlayıcı kutu için görüntü bölgesi dizin dilimleme kullanılarak kırpılır ve burada sınırlar [ymin:ymax, xmin:xmax] algılama sınırlayıcı kutusunun koordinatları.

    Arka plan dahil kırpılmış nesneyi istersem ne olur?

    Bu, Ultralytics kütüphanesi için yerleşik bir özelliktir. Bkz. save_crop için argüman Tahmin Modu Çıkarım Argümanları detaylar için.


  6. Bundan sonra ne yapılacağı tamamen geliştirici olarak size bırakılmıştır. Olası bir sonraki adımın (görüntüyü ileride kullanmak üzere dosyaya kaydetme) temel bir örneği gösterilmektedir.

    • NOT: bu adım isteğe bağlıdır ve özel kullanım durumunuz için gerekli değilse atlanabilir.
    Örnek Son Adım
    # Save isolated object to file
    _ = cv2.imwrite(f'{img_name}_{label}-{ci}.png', iso_crop)
    
    • Bu örnekte, aşağıdaki img_name kaynak görüntü dosyasının temel adıdır, label algılanan sınıf adıdır ve ci nesne tespitinin indeksidir (aynı sınıf adına sahip birden fazla örnek olması durumunda).

Tam Örnek kod

Burada, önceki bölümdeki tüm adımlar tek bir kod bloğunda birleştirilmiştir. Tekrarlanan kullanımlar için, aşağıdaki komutların bir kısmını ya da tamamını yerine getirecek bir fonksiyon tanımlamak en uygunudur for-Döngüler, ancak bu okuyucuya bırakılmış bir alıştırmadır.

from pathlib import Path

import cv2
import numpy as np
from ultralytics import YOLO

m = YOLO('yolov8n-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. Dolduran satır contour yukarıda birden fazla satıra bölünmüşken burada tek bir satırda birleştirilmiştir.
  2. Buraya ne koyacağınız size kalmış!
  3. Daha fazla bilgi için Tahmin Modu bölümüne bakın.
  4. Daha fazla bilgi için Segment Görevi bölümüne bakın.
  5. Sonuçlarla Çalışma hakkında daha fazla bilgi edinin
  6. Segmentasyon Maskesi Sonuçları hakkında daha fazla bilgi edinin


Oluşturma 2023-11-27, Güncelleme 2024-04-27
Yazarlar: glenn-jocher (6), RizwanMunawar (1), Burhan-Q (1)

Yorumlar