Hoşgeldin Misafir

OpenCV ile Arka Plan Çıkarma (C++)

SurHan

28 Kas 2017
4,186 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
arka-plan-cikarma-opencv.jpg


-Açıklama:--


Arka plan çıkarma işlemi; video’lardan yada kameradan, hareketsiz görüntülerin temizlenerek sadece hareket eden nesnelerin yakalanmasıdır.-
Bu işlemi c++ ve opencv ikilisiyle aşağıdaki kod yardımıyla yapabilirsiniz.-
Programı başlatırken kameranın önünden çekilin.-
Program ilk yakaladığı kareyi arka plan kabul edecektir.-
Sonraki kareleri ise hareketli nesne kabul edecek.-

Program arka plan ve hareketli nesne bilgilerini referans alarak bir maske oluşturacaktır.-
Bu maske vasıtasıyla da ekrana sonradan çıkan bütün nesneler yakalanacaktır.-

-Uyarı:--

arkaPlanCikarmaYontemi->apply(goruntu, arkaPlanMaskesi, false); fonksiyonundaki false ifadesini true yaparak belirli sürelerle arkaplanın güncellenmesini sağlayabilirsiniz.-
Bu ne işe yarar diyecek olursanız.-
Bu durum şunu ifade eder;-
Ekrana sonradan çıkan bir nesne belirli bir süre sabit durursa, program onuda artık arka plan olarak algılayacak ve program maskeyi güncelleyecektir.-

-Artık Yeşil Perdeye Gerek Yok:)--

-
ye%C5%9Fil-perde-opencv-arka-plan-cikarma.jpg
-
-



---Dikkat:----


OpenCV arka plan çıkarmada eskiden BackgroundSubtractorMOG ve BackgroundSubtractorGMG gibi yöntemleride / algoritmalarıda destekliyormuş. Şuan bu algoritmalar desteklenmiyor.-

Biz programımızda BackgroundSubtractorMOG2 algoritmasını kullandık.-

Ayrıca createBackgroundSubtractorMOG2() ifadesinin bulunduğu yere createBackgroundSubtractorKNN() yazarak BackgroundSubtractorKNN() algoritmasını kullanabilirsiniz.-

Benim tavsiyem BackgroundSubtractorMOG2 algoritmasını kullanmanız.-

Bu konu çok önemli bir konu.-
--Kişi sayma, araba sayma gibi işlemlerde bile kullanılıyor.---

--PROGRAM KODLARI:---




Kod:
#include "opencv2/core.hpp"
#include <opencv2/core/utility.hpp>
#include "opencv2/imgproc.hpp"
#include "opencv2/video/background_segm.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include <stdio.h>
 
using namespace std;
using namespace cv;
 
//yöntem olarak createBackgroundSubtractorKNN() 'de seçilebilir
Ptr<BackgroundSubtractor> arkaPlanCikarmaYontemi = createBackgroundSubtractorMOG2();
 
Mat goruntu; //kameradan alınan görüntü
Mat arkaPlanMaskesi; //maske
Mat	arkaPlaniCikarilmisGoruntu;
Mat arkaPlanGoruntusu; //arka plan
 
int main()
{
	//arkaPlaniCikarilmisGoruntu yü yumuşatmak ve pürüzler kaldırmak isterseniz burayı true olarak değiştiriniz
	bool puruzleriKaldir = true; 
 
	VideoCapture yakala(0);
 
	while (waitKey(30) != 27) 	//esc'ye basılmadığı sürece döngü çalışsın
	{
		yakala >> goruntu;
		flip(goruntu, goruntu, 1); //goruntu nün yatayda simetrisi aliniyor
 
		if (arkaPlaniCikarilmisGoruntu.empty()) //arkaPlaniCikarilmisGoruntu eğer yoksa oluşturuldu
			arkaPlaniCikarilmisGoruntu.create(goruntu.size(), goruntu.type());
 
		//burası true olursa belirli bir süre sabit duran yeni görüntüler artık arkaplan olarak kabul edilecektir
		arkaPlanCikarmaYontemi->apply(goruntu, arkaPlanMaskesi, false);
 
		if (puruzleriKaldir)
		{
			//histogram eşitlemesi yapıldı
			equalizeHist(arkaPlanMaskesi, arkaPlanMaskesi);
			
			//resim bulanıklaştırılıyor yani
			//bir nevi yumuşatılıyor
			GaussianBlur(arkaPlanMaskesi, arkaPlanMaskesi, Size(11, 11), 3.5, 3.5);
		
			//belli eşik değerinin altındaki pikseller siyah, diğerleri beyaz yapılıyor
			threshold(arkaPlanMaskesi, arkaPlanMaskesi, 100, 255, THRESH_BINARY);
 
			//morfolojik acma yapiliyor
			//resimdeki beyaz gurultuler engelleniyor
			//once asindirma sonra genisletme yapiliyor
			erode(arkaPlanMaskesi, arkaPlanMaskesi, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
			dilate(arkaPlanMaskesi, arkaPlanMaskesi, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
 
			//morfolojik kapanma yapiliyor
			//beyaz olan nesnelerin arasindaki kucuk siyah holler temizleniyor
			//once genisletme sonra asindirma yapiliyor
			dilate(arkaPlanMaskesi, arkaPlanMaskesi, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
			erode(arkaPlanMaskesi, arkaPlanMaskesi, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
		}
 
		arkaPlaniCikarilmisGoruntu = Scalar::all(0);//arkaplanın tüm pikselleri 0 yani siyah ayarlandı
 
		//burada goruntu üzerine arkaPlanMaskesi uygulanarak arkaPlaniCikarilmisGoruntu elde edildi
		//goruntu giriş matrisi, arkaPlaniCikarilmisGoruntu çıkış matrisi, arkaPlanMaskesi maske
		goruntu.copyTo(arkaPlaniCikarilmisGoruntu, arkaPlanMaskesi); 
	
		arkaPlanCikarmaYontemi->getBackgroundImage(arkaPlanGoruntusu); //arka plan arkaPlanGoruntusu nesnesine aktarıldı
		imshow("Arka Plan Görüntüsü", arkaPlanGoruntusu); //arka plan pencerede gösteriliyor
 
		imshow("Kameradan Alınan Görüntü", goruntu); //kameradan alınan görüntü pencerede gösteriliyor
		imshow("Maske Görüntüsü", arkaPlanMaskesi); //arkaPlanMaskesi pencerede gösteriliyor
		imshow("Arka Planı Çıkarılmış Görüntü", arkaPlaniCikarilmisGoruntu); //arka planı çıkarılmış görüntü pencerede gösteriliyor
 
	}
	return 0;
}