Ultralytics YOLO ile Segmentasyon Nesnelerini Ayırma#
Örnek segmentasyonu, algılanan her nesne için piksel düzeyinde hassas bir maske oluşturur; bu da her nesneyi görüntüden tek başına çıkarabileceğin anlamına gelir. Bu kılavuzda, PNG olarak kaydetmek üzere düz siyah veya şeffaf arka plan kullanarak Tahmin Modu ve OpenCV ile Ultralytics YOLO segmentasyon sonuçlarını yalıtılmış nesnelere dönüştürme açıklanmaktadır.
Watch: How to Remove Background and Isolate Objects with Ultralytics YOLO Segmentation & OpenCV in Python 🚀
Segmentasyon Nesneleri Neden Ayrılır?#
Tek tek nesneleri görüntüden çıkarmak, çeşitli sonraki iş akışlarının önünü açar:
- Ürün fotoğrafları, kataloglar veya yaratıcı düzenlemeler için arka plan kaldırma.
- Algıladığın nesnelerden sınıflandırma veri kümeleri oluşturmak için nesne başına kırpma.
- OCR, renk analizi veya ölçüm gibi sonraki adımların çevredeki sahneyi değil yalnızca nesneyi görmesi için odaklanmış işleme.
- Nesneleri yeni arka planlar üzerine birleştirmek için şeffaf PNG dışa aktarma.
Bu yöntem, herhangi bir Ultralytics YOLO segmentasyon modeliyle çalışır ve dört aşamayı izler: çıkarım çalıştır → her konturu çıkar → nesneyi ayır → sonucu kaydet.
Segmentasyon Çıkarımını Çalıştırma#
Gerekli kütüphaneleri yükle, ardından bir segmentasyon modeli (-seg soneki maske üretmek için gereklidir) yükle ve kaynak görüntünde tahmin çalıştır:
from ultralytics import YOLO
# Load a segmentation model
model = YOLO("yolo26n-seg.pt")
# Run inference on a source
results = model.predict(source="path/to/image.jpg")model.predict() çağrısını bir source olmadan yaparsan Ultralytics, paketle birlikte gönderilen örnek görüntülere (bus.jpg ve zidane.jpg) geri döner; bu, iş akışını hızlıca test etmek için kullanışlıdır.
Nesne Konturlarını Çıkarma#
results içindeki her öğe bir görüntüye karşılık gelir ve bir sonuç üzerinde yineleme yapmak her seferinde bir algılama döndürür. Her algılama için özgün görüntüyü kopyala, sınıf etiketini oku ve nesnenin maskesinin konturunu boş bir ikili maske üzerine çiz. Bu maskenin beyaz bölgesi, tam olarak hangi piksellerin nesneye ait olduğunu gösterir.
Bu bölümdeki ve sonraki bölümdeki kod parçacıklarını aşağıdaki algılama döngüsünün içinde çalıştır; eksiksiz, kopyalanıp yapıştırılabilir betik Tam Örnek bölümündedir.
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 # source image base-name
# Iterate each detected object in the image
for ci, c in enumerate(r):
label = c.names[c.boxes.cls.tolist().pop()] # class name
# Build a binary mask and draw the object contour onto it
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], bu tek algılama sonucundaki nesne için maskenin konturunu(x, y)nokta koordinatları olarak döndürür..astype(np.int32), noktaları OpenCV'nin kabul etmediğifloat32biçimindendrawContours()biçimine dönüştürür..reshape(-1, 1, 2), noktalarıdrawContours()'nin beklediği[N, 1, 2]düzenine yeniden şekillendirir; buradaN, kontur noktalarının sayısıdır.
[contour] değerini -1 diziniyle geçirmek, verilen konturun tüm noktalarını çizer; cv2.FILLED ise çevrelenen her pikseli beyaza doldurur.
Nesneyi Ayırma#
İkili maske hazır olduğunda onu özgün görüntüyle birleştir. Arka planın nasıl olmasını istediğine bağlı olarak iki yaygın yöntem vardır:
Maskeyi üç kanala dönüştür ve yalnızca nesneyle örtüşen pikselleri koru. Konturun dışındaki her şey siyaha dönüşür:
# Isolate object with a black background
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)
Tam boyutlu görüntü yerine yalnızca nesnenin bölgesini korumak için görüntüyü algılamanın sınırlayıcı kutusuna göre dilimle:
# Bounding box coordinates
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
# Crop the isolated image to the object region
iso_crop = isolated[y1:y2, x1:x2]
Bu özellik yerleşik olarak bulunur. save_crop=True değerini predict() öğesine geçir; Ultralytics, maskeleme gerektirmeden sınırlayıcı kutu kırpmalarını otomatik olarak kaydeder.
Sonucu Kaydetme (isteğe bağlı)#
Her yalıtılmış nesneyle ne yapacağın sana kalmış. Yaygın bir sonraki adım, nesneyi daha sonra kullanmak üzere diske yazmaktır:
# Save the isolated object to file
cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated)Burada img_name kaynak görüntünün gövde adıdır, label sınıf adıdır ve ci algılama dizinidir; böylece aynı sınıfın birden fazla örneği benzersiz dosya adlarına sahip olur. Yukarıdaki isteğe bağlı kırpmayı uyguladıysan isolated yerine iso_crop kullan.
Tam Örnek#
Aşağıdaki betik her adımı tek bir çalıştırılabilir blokta birleştirir. Varsayılan olarak siyah arka plan kullanır; bunun yerine şeffaf PNG için np.dstack([img, b_mask]) kullanmak üzere işaretli tek satırı değiştir:
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])Tekrarlı kullanım için döngü gövdesini bir işlev içine al; böylece bu işlevi birçok görüntü üzerinde çağırabilirsin.
Sonuç#
Artık Ultralytics YOLO ile segmentasyon nesnelerini ayırmak için eksiksiz bir yöntemin var: çıkarımı çalıştır, her konturdan bir ikili maske oluştur, ardından nesneyi siyah veya şeffaf bir arka planda çıkar ve isteğe bağlı olarak sınırlayıcı kutusuna göre kırp. İş akışını kendi sınıflarına uyarlamak için Segmentasyon Görevi ve Tahmin Modu belgelerinin tamamını incele.
SSS#
Bir segmentasyon modeli yükle, çıkarım çalıştır, her algılamanın konturundan bir ikili maske oluştur ve bunu özgün görüntüyle birleştir:
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)Algılama başına döngünün tamamı için Tam Örnek bölümüne bak.
İki temel yöntem vardır. Siyah arka plan için maskeyi üç kanala dönüştür ve
cv2.bitwise_and()kullan. Şeffaf arka plan için (PNG olarak kaydederken) maskeyinp.dstack([img, b_mask])ile dördüncü alfa kanalı olarak ekle. Her iki yöntem de Nesneyi Ayırma bölümünde gösterilir.Sınırlayıcı kutu koordinatlarını algılamadan oku ve yalıtılmış görüntüyü dilimle:
x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32) iso_crop = isolated[y1:y2, x1:x2]Sınırlayıcı kutu sonuçları hakkında daha fazla bilgi için Tahmin Modu belgelerine bak.
Ultralytics YOLO, doğru maske ve sınırlayıcı kutu üretiminin yanı sıra hızlı, gerçek zamanlı örnek segmentasyonu sağlar; basit Python API'si, birkaç satır OpenCV koduyla çıkarım sonuçlarını yalıtılmış nesnelere dönüştürür.
Evet. Sınırlayıcı kutu kırpmalarını özgün arka planlarıyla kaydetmek için
predict()içindesave_cropbağımsız değişkenini kullan:results = model.predict(source="path/to/your/image.jpg", save_crop=True)Daha fazla bilgi için Tahmin Modu Çıkarım Bağımsız Değişkenleri bölümünü incele.