· Hakan Çelik · OpenCV / Görüntü İşleme · 5 dk okuma

GrabCut ile Etkileşimli Ön Plan Çıkarma

GrabCut algoritmasını kullanarak görüntülerdeki ön planı çıkarmayı öğrenin. cv2.grabCut() fonksiyonu ile dikdörtgen ve maske modlarında çalışmayı anlattım.
OpenCV Serisi 31/64
  1. 1. Boya Fırçası Olarak Fare
  2. 2. Canny Kenar Algılama
  3. 3. Görüntü Geçişleri
  4. 4. Görüntü Piramitleri
  5. 5. Görüntülerde Aritmetik İşlemler
  6. 6. Görüntülerle İlgili Temel İşlemler
  7. 7. Görüntünün Geometrik Dönüşümleri
  8. 8. Görüntüyü Yumuşatma - ( Smoothing Images )
  9. 9. Histogramlar
  10. 10. Konturler ( Contours )
  11. 11. Morfolojik Dönüşümler
  12. 12. Opencv Nedir Ve Kurulumu
  13. 13. Opencv Resim Işlemleri
  14. 14. Opencv Video Işlemleri
  15. 15. Opencv'de Çizim Fonksiyonları
  16. 16. Performans Ölçüm Ve Geliştirme Teknikleri
  17. 17. Renk Alanlarını Değiştirme
  18. 18. Renk Paleti Olarak Parça Çubuğu ( Trackbar )
  19. 19. Resim Eşikleme
  20. 20. Şablon Eşleştirme
  21. 21. Hough Doğru Dönüşümü
  22. 22. Hough Daire Dönüşümü
  23. 23. Fourier Dönüşümü
  24. 24. Histogram Eşitleme
  25. 25. 2B Histogramlar
  26. 26. Histogram Geri Projeksiyonu
  27. 27. Kontur Özellikleri
  28. 28. Kontur Nitelikleri
  29. 29. Konturlerle Daha Fazla İşlev
  30. 30. Kontur Hiyerarşisi
  31. 31. GrabCut ile Etkileşimli Ön Plan Çıkarma
  32. 32. Watershed Algoritması ile Görüntü Segmentasyonu
  33. 33. Özellikleri Anlamak
  34. 34. Harris Köşe Tespiti
  35. 35. Shi-Tomasi Köşe Dedektörü ve İzlenecek İyi Özellikler
  36. 36. SIFT'e Giriş (Ölçek Değişmez Özellik Dönüşümü)
  37. 37. SURF'e Giriş (Hızlandırılmış Sağlam Özellikler)
  38. 38. Köşe Tespiti için FAST Algoritması
  39. 39. BRIEF — İkili Sağlam Bağımsız Temel Özellikler
  40. 40. ORB (Yönlü FAST ve Döndürülmüş BRIEF)
  41. 41. Özellik Eşleştirme
  42. 42. Özellik Eşleştirme + Nesneleri Bulmak için Homografi
  43. 43. Meanshift ve Camshift ile Nesne Takibi
  44. 44. Optik Akış
  45. 45. Arka Plan Çıkarma
  46. 46. Kamera Kalibrasyonu
  47. 47. Poz Tahmini
  48. 48. Epipolar Geometri
  49. 49. Stereo Görüntülerden Derinlik Haritası
  50. 50. k-En Yakın Komşuyu Anlamak
  51. 51. kNN ile El Yazısı OCR
  52. 52. SVM'yi Anlamak
  53. 53. SVM ile El Yazısı OCR
  54. 54. K-Ortalamalar Kümeleme'yi Anlamak
  55. 55. OpenCV'de K-Ortalamalar Kümeleme
  56. 56. Görüntü Gürültü Giderme
  57. 57. Görüntü Onarımı (Inpainting)
  58. 58. Yüksek Dinamik Aralık (HDR) Görüntüleme
  59. 59. Haar Cascade ile Yüz Tespiti
  60. 60. pip ile OpenCV Kurulumu
  61. 61. Ubuntu'da OpenCV-Python Kurulumu
  62. 62. Fedora'da OpenCV-Python Kurulumu
  63. 63. Windows'ta OpenCV-Python Kurulumu
  64. 64. OpenCV-Python Bağlayıcıları Nasıl Çalışır?

GrabCut ile Etkileşimli Ön Plan Çıkarma

Hedefler

Bu bölümde:

  • Görüntülerde ön planı çıkarmak için GrabCut algoritmasını göreceğiz
  • Bu amaçla etkileşimli bir uygulama oluşturacağız

Teori

GrabCut algoritması, Microsoft Research Cambridge’den Carsten Rother, Vladimir Kolmogorov ve Andrew Blake tarafından “GrabCut”: iterative graph cut kullanarak etkileşimli ön plan çıkarma adlı makalede tasarlanmıştır. Minimal kullanıcı etkileşimiyle ön plan çıkarma için bir algoritma gerekiyordu ve sonuç GrabCut oldu.

Kullanıcı açısından nasıl çalışır? Başlangıçta kullanıcı, ön plan bölgesinin etrafına bir dikdörtgen çizer (ön plan bölgesi tamamen dikdörtgenin içinde olmalıdır). Ardından algoritma, en iyi sonucu elde etmek için bunu yinelemeli olarak segmentler. Tamam. Ancak bazı durumlarda segmentasyon iyi olmayabilir; örneğin bazı ön plan bölgelerini arka plan olarak, bazı arka plan bölgelerini ön plan olarak işaretlemiş olabilir. Bu durumda kullanıcının bazı ince düzenlemeler yapması gerekir. Hatalı sonuçların olduğu görüntü üzerinde çizgiler çizmeniz yeterlidir. Bu çizgiler temelde şunu söyler: “Hey, bu bölge ön plan olmalı, arka plan olarak işaretledin, bir sonraki iterasyonda düzelt” ya da tam tersi. Bir sonraki iterasyonda daha iyi sonuçlar alırsınız.

Aşağıdaki görüntüye bakın. İlk olarak oyuncu ve top mavi bir dikdörtgenin içine alınır. Ardından beyaz çizgilerle (ön planı gösteren) ve siyah çizgilerle (arka planı gösteren) bazı son düzenlemeler yapılır. Ve güzel bir sonuç elde edilir:

GrabCut çıktısı

Peki arka planda ne oluyor?

  • Kullanıcı dikdörtgeni girer. Bu dikdörtgenin dışındaki her şey kesin arka plan olarak alınır (bu yüzden dikdörtgeninizin tüm nesneleri içermesi gerektiği daha önce belirtilmiştir). Dikdörtgenin içindeki her şey bilinmeyendir. Benzer şekilde, kullanıcının ön planı veya arka planı belirten girdiler “sabit etiketleme” olarak kabul edilir; bu, süreçte değişmeyecekleri anlamına gelir.
  • Bilgisayar, verdiğimiz verilere göre başlangıç etiketlemesi yapar. Ön plan ve arka plan piksellerini etiketler.
  • Şimdi ön planı ve arka planı modellemek için bir Gauss Karışım Modeli (GMM) kullanılır.
  • Verdiğimiz verilere bağlı olarak, GMM yeni piksel dağılımları öğrenir ve oluşturur. Yani bilinmeyen pikseller, renk istatistikleri açısından diğer sabit etiketlenmiş piksellerle ilişkilerine bağlı olarak muhtemel ön plan veya muhtemel arka plan olarak etiketlenir (sadece kümeleme gibi).
  • Bu piksel dağılımından bir grafik oluşturulur. Grafikteki düğümler piksellerdir. İki ek düğüm eklenir: Kaynak düğüm ve Havuz düğümü. Her ön plan pikseli Kaynak düğümüne, her arka plan pikseli ise Havuz düğümüne bağlanır.
  • Pikselleri kaynak/son düğüme bağlayan kenarların ağırlıkları, pikselin ön plan/arka plan olma olasılığıyla tanımlanır. Pikseller arasındaki ağırlıklar, kenar bilgisi veya piksel benzerliğiyle tanımlanır. Piksel renginde büyük bir fark varsa, aralarındaki kenar düşük bir ağırlık alır.
  • Ardından, grafiği segmentlemek için bir minimum kesme (mincut) algoritması kullanılır. Minimum maliyet fonksiyonuyla kaynak düğümü ve havuz düğümünü ayırarak grafiği iki parçaya böler. Maliyet fonksiyonu, kesilen tüm kenarların ağırlıklarının toplamıdır. Kesimden sonra Kaynak düğümüne bağlı tüm pikseller ön plan, Havuz düğümüne bağlı olanlar ise arka plan olur.
  • Sınıflandırma yakınsayana kadar süreç devam eder.

Aşağıdaki görüntüde bu süreç gösterilmektedir (Görüntü kaynağı: http://www.cs.ru.ac.za/research/g02m1682/):

GrabCut şeması

Demo

Şimdi OpenCV ile GrabCut algoritmasına geçelim. OpenCV bunun için cv.grabCut() fonksiyonuna sahiptir. Argümanlarına bakalım:

  • img — Giriş görüntüsü
  • mask — Hangi alanların arka plan, ön plan veya muhtemel arka plan/ön plan olduğunu belirttiğimiz maske görüntüsü. Bu cv.GC_BGD, cv.GC_FGD, cv.GC_PR_BGD, cv.GC_PR_FGD bayraklarıyla veya görüntüye 0, 1, 2, 3 geçirerek yapılır.
  • rect — Ön plan nesnesini içeren dikdörtgenin koordinatları: (x, y, w, h) formatında
  • bdgModel, fgdModel — Algoritma tarafından dahili olarak kullanılan diziler. Sadece boyutu (1, 65) olan iki np.float64 tipi sıfır dizisi oluşturun.
  • iterCount — Algoritmanın çalışması gereken iterasyon sayısı
  • modecv.GC_INIT_WITH_RECT veya cv.GC_INIT_WITH_MASK ya da birleşimi olmalıdır; dikdörtgen mi yoksa son dokunuş çizgileri mi çizdiğimize karar verir.

Önce dikdörtgen modunu görelim. Görüntüyü yüklüyoruz, benzer bir maske görüntüsü oluşturuyoruz, fgdModel ve bgdModel oluşturuyoruz, dikdörtgen parametrelerini veriyoruz ve algoritmayı 5 iterasyon çalıştırıyoruz:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('messi5.jpg')
assert img is not None, "file could not be read, check with os.path.exists()"
mask = np.zeros(img.shape[:2], np.uint8)

bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)

rect = (50, 50, 450, 290)
cv.grabCut(img, mask, rect, bgdModel, fgdModel, 5, cv.GC_INIT_WITH_RECT)

mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
img = img * mask2[:, :, np.newaxis]

plt.imshow(img), plt.colorbar(), plt.show()

Sonuçlara bakın:

GrabCut dikdörtgen modu

Messi’nin saçları gitti. Kim Messi’yi saçsız sever? Geri getirmemiz gerekiyor. Yani orada 1-piksel (kesin ön plan) ile ince bir dokunuş yapacağız. Aynı zamanda resme giren zemin ve logo gibi istemediğimiz kısımlar da var. Onları kaldırmamız gerekiyor, bunlar için 0-piksel (kesin arka plan) dokunuşu yapıyoruz:

# newmask el ile etiketlediğim maske görüntüsüdür
newmask = cv.imread('newmask.png', cv.IMREAD_GRAYSCALE)
assert newmask is not None, "file could not be read, check with os.path.exists()"

# beyaz işaretli yerleri (kesin ön plan) mask=1 yap
# siyah işaretli yerleri (kesin arka plan) mask=0 yap
mask[newmask == 0] = 0
mask[newmask == 255] = 1

mask, bgdModel, fgdModel = cv.grabCut(img, mask, None, bgdModel, fgdModel, 5, cv.GC_INIT_WITH_MASK)

mask = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
img = img * mask[:, :, np.newaxis]
plt.imshow(img), plt.colorbar(), plt.show()

Sonuca bakın:

GrabCut maske modu

İşte bu kadar. Dikdörtgen modunda başlatmak yerine, doğrudan maske moduna geçebilirsiniz. Sadece maske görüntüsündeki dikdörtgen alanını 2-piksel veya 3-piksel (muhtemel arka plan/ön plan) ile işaretleyin. Ardından ikinci örnekteki gibi kesin_ön_planı 1-piksel ile işaretleyin. Sonra GrabCut fonksiyonunu doğrudan maske moduyla uygulayın.

Alıştırmalar

  1. OpenCV örnekleri, GrabCut kullanan etkileşimli bir araç olan grabcut.py’yi içerir. Kontrol edin. Ayrıca nasıl kullanıldığına dair bu youtube videosunu izleyin.
  2. Burada, fare ile dikdörtgen ve çizgiler çizerek bu uygulamayı etkileşimli bir örneğe dönüştürebilirsiniz; çizgi genişliğini ayarlamak için kaydırma çubuğu ekleyebilirsiniz.

Kaynak: OpenCV Python Tutorials — Orijinal Döküman

Back to Blog

Related Posts

View All Posts »
OpenCV-Python Bağlayıcıları Nasıl Çalışır?

OpenCV-Python Bağlayıcıları Nasıl Çalışır?

OpenCV · 3 dk

OpenCV-Python bağlayıcılarının nasıl oluşturulduğunu öğrenin. C++ modüllerinin Python'a nasıl aktarıldığını, CV_EXPORTS_W, CV_WRAP gibi makroları ve gen2.py üreteci ile hdr_parser.py başlık ayrıştırıcısını anlattım.

Haar Cascade ile Yüz Tespiti

Haar Cascade ile Yüz Tespiti

OpenCV · 3 dk

OpenCV'de Haar Cascade sınıflandırıcılarını kullanarak yüz ve göz tespiti yapın. cv.CascadeClassifier ile gerçek zamanlı nesne tespitinin temellerini anlattım.

Görüntü Onarımı (Inpainting)

Görüntü Onarımı (Inpainting)

OpenCV · 2 dk

Eski fotoğraflardaki hasarları, çizikleri ve lekeleri OpenCV'nin cv.inpaint() fonksiyonu ile nasıl onaracağınızı öğrenin. Telea ve Navier-Stokes algoritmalarını anlattım.