Opencv GrabCut C++

0
747
views

Bu yazımda Opencv C++ kullanarak bir resmin en hızlı ve kolay şekilde arka planını silerek ön plandaki ana resmi çıkarmayı anlatmaya çalışacağım. Bunun için bir takım arkadaş bir araya gelmiş ve bize bu güzel algoritmayı tasarlamışlar. Bize de kullanmak düşer. Teori kısmını hızlı geçeceğim.

Bu algoritma, öncelikle arka planını silmek istediğiniz resmin etrafına bir dikdörtgen çizer. Daha sonra algoritma en iyi sonucu almak için tekrar tekrar parçalara ayırıyor. Bu işlemlerin sonucunda isteğimiz sonuçlanmış oluyor. Fakat karşınıza istemediğiniz bir sonuç çıkabilir. Mesela arka plan ile ön plan resminde bazı kesişimler olmuş olabilir. Bu duruma şu şekilde örnek verilebilir. Ön plandaki resmimiz beyaz tonlarda ve arka plan resimde beyaz tonlarda olursa bazı yerler arka planla beraber silinebilir. Bu yüzden buna uygun hale getirmek için ufak dokunuşlar yapmamız gerekir.

 

Evet burada görüldüğü gibi arka plandaki yolu silerek yarışçıyı çekmiş olduk. Bunu yaparken kullandığımız kodlara bir bakalım isterseniz.

Öncelikle GrabCut fonksiyonunu bir inceleyelim.

 

void grabCut(InputArray img,

                     InputOutputArray mask,

                     Rect rect,

                     InputOutputArray bgdModel,

                     InputOutputArray fgdModel,

                     int iterCount,

                     int mode)

//InputArray img;

                Mat resim;

                resim =imread(“grabcut.jpg”);

                Mat resim2;

                resize(resim, resim2, Size(500, 300));

imread: resimiz nerede ise yolunu alıyoruz.

Resize: Resim boyutu büyük olursa işlem süresi o kadar uzayacağı için resmimizin boyutunu küçültüyoruz. Bu şekilde inputArray img oluşturmuş oluyoruz.

//InputOutputArray mask;

mask – Giriş/Çıkış 8-bit tek kanal maskesi. Bu maske eğer mod GC_INIT_WITH_RECT ayarlanırsa çalışmaya başlar. Ve bu değerlerden birine sahiptir.

  • GC_BGD           Belirgin arka plan pikselleri tanımlar.
  • GC_FGD           Belirgin ön plan pikselleri tanımlar.
  • GC_PR_BGD    Olası bir arka plan pikseli tanımlar.
  • GC_PR_FGD    Olası bir ön plandaki pikseli tanımlar.

compare(sonuc, GC_PR_FGD, sonuc, CMP_EQ);

İşte burada ön plandaki pixelleri tarıyor ve bir karşılaştırma yapıyor. Eğer aynıysa pixeller hiç dokunmuyor ve geriye kalan bütün pikselleri temizliyor.

//Rect rect;

  Rect rect (x, y, w, h);

 

Burada “rect” methodu ile çizeceğimiz dikdörtgenin “x,y,w,h” olarak değerlerini giriyoruz

//InputOutputArray bgdModel

Arka plan modeli için geçici dizi. Aynı görüntü üzerinde çalışırken değişiklik yapmayın.

// InputOutputArray fgdModel

Ön plan modeli için geçici dizi. Aynı görüntü üzerinde çalışırken değişiklik yapmayın

//int iterCount

Algoritmanın yapması gereken yenilemelerin sayısı.

//int mode

  • GC_INIT_WITH_RECT  –   Belirlenen dikdörtgeni kullanarak durumu ve maskeyi başlatır. Daha sonra algoritma iterCount tekrarlamalarını çalıştırır.
  • GC_INIT_WITH_MASK  –   Fonksiyon belirlenen maskeyi kullanarak durumu başlatır. GC_INIT_WITH_RECT ve GC_INIT_WITH_MASK  birleştirilebilir. Bu işlemden sonra belirgin arka plan dışındaki bütün pikseller otomatik olarak GC_BGD ile başlatılır
  • GC_EVAL   –   Algoritmanın devam etmesi gerektiğini gösteren değerdir.

#include “stdafx.h”

#include “opencv2/opencv.hpp”

#include <iostream>

using namespace cv;

using namespace std;

int main()

{

 

 // InputArray img

 Mat image;

 image = imread(“grabcut.jpg”);

 

 Mat resized;

 resize(image, resized, Size(500, 300));

 

       if (!resized.data)

       {

             cout << “Image could not open! << endl;

             return -1;

       }

 

// RECTANGLE

int border = 10;

int border2= sınır + sınır;

Rect rectangle(border, border, border2.cols – border2, border2.rows –border2);

 

Mat result;

Mat bgModel, fgModel;

 

       // GrabCut

       grabCut(resized,    // InputArray img

                      result,   // InputOutputArray mask

                      rectangle,// Rect rectangle

                      bgModel, // InputOutputArray

                      fgModel, // InputOutputArray

                      1,        //iterCount

                      GC_INIT_WITH_RECT); mode

 

// Get the pixels marked as likely foreground

compare(result, GC_PR_FGD, result, CMP_EQ);

 

// Generate output image

Mat foreground(resized.size(), CV_8UC3, Scalar(0, 0, 0));

resim2.copyTo(foreground, result);

 

// draw rectangle on original image

rectangle(resized, rectangle, cv::Scalar(255, 255, 255), 1);

namedWindow(“Original Image”);

imshow(“Original Image “, resized);

 

// display result

namedWindow(“GrabCut Image “);

imshow(“GrabCut Image “, foreground);

 

waitKey();

return 0;

}

 


 

http://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html?highlight=grabcut#grabcut

http://docs.opencv.org/3.1.0/d8/d83/tutorial_py_grabcut.html

https://www.microsoft.com/en-us/research/publication/grabcut-interactive-foreground-extraction-using-iterated-graph-cuts/

CEVAP VER

Please enter your comment!
Please enter your name here