Hoşgeldin Misafir

OpenCV ile Resim Üzerine Transparan Resim Ekleme (C++)

SurHan

28 Kas 2017
4,185 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
-Açıklama:--


Yaptığımız görüntü işleme projelerinde bazen bir resim üzerine png formatında transparan yani saydam resim eklemek isteriz.-
Maalesef bu işlemi yapan hazır bir opencv komutu yok.-
Fakat sizinle paylaşacağımız kod şuan internette paylaşılan, normal resimle transparan resmi birleştirme işlemi yapan tek koddur (Kod bize ait değil İngilizce bir siteden alıntıdır).-


-Transparan Resimle Birleşmiş Resim:--

resim-uzerine-transparan-resim-ekleme.jpg


-Png Formatında Transparan Resim:--

foreground.png


-Not 1:--


Bu resmin bulunduğu klasörde farklı renklerde balonlarda var.-
İsterseniz kullanabilirsiniz.-

ARKA PLAN RESMİ :-

background.jpg
-

--Not 2:---


Bu örneği kullanarak kendi artırılmış gerçeklik oyununuzu yapabilirsiniz, nasıl mı?-

Arka plan çıkarma yöntemiyle arka planı çıkarıp buradaki arka planı ekleyiniz.-

Daha sonra havadan rastgele balonlar yere doğru aşağı insin.-

Sizde elinizle (kameradaki görüntüyle) bu balonları patlatın.-

Hatta yapabilirseniz iki kişilik kapışmalı bir oyun yapın.-
-Buda size ödevimiz olsun:)--

---Program Kodu:--
-
-

Kod:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream> //cout için gerekli
 
using namespace cv;
using namespace std;
 
void resimleriBirleştir(const cv::Mat &background, const cv::Mat &foreground,
	cv::Mat &output, cv::Point2i location)
{
	background.copyTo(output);
 
	// start at the row indicated by location, or at row 0 if location.y is negative.
	for (int y = std::max(location.y, 0); y < background.rows; ++y)
	{
		int fY = y - location.y; // because of the translation
 
		// we are done of we have processed all rows of the foreground image.
		if (fY >= foreground.rows)
			break;
 
		// start at the column indicated by location, 
 
		// or at column 0 if location.x is negative.
		for (int x = std::max(location.x, 0); x < background.cols; ++x)
		{
			int fX = x - location.x; // because of the translation.
 
			// we are done with this row if the column is outside of the foreground image.
			if (fX >= foreground.cols)
				break;
 
			// determine the opacity of the foregrond pixel, using its fourth (alpha) channel.
			double opacity = ((double)foreground.data[fY * foreground.step + fX * foreground.channels() + 3]) / 255.;
 
			// and now combine the background and foreground pixel, using the opacity, 
 
			// but only if opacity > 0.
			for (int c = 0; opacity > 0 && c < output.channels(); ++c)
			{
				unsigned char foregroundPx =
					foreground.data[fY * foreground.step + fX * foreground.channels() + c];
				unsigned char backgroundPx =
					background.data[y * background.step + x * background.channels() + c];
				output.data[y*output.step + output.channels()*x + c] =
					backgroundPx * (1. - opacity) + foregroundPx * opacity;
			}
		}
	}
}
 
int main(int argc, char *argv[])
{
	// add the second parameter "-1" as flag, to make sure the transparancy channel is read!
	cv::Mat saydamResim = imread("foreground.png", -1);
	cv::Mat arkaPlan = imread("background.jpg");
	
	//saydam resim, arka planın üzerine eklendikten sonra oluşan resim
	cv::Mat birlesmisResim;
 
	//arkaplanın üstüne resim burada ekleniyor
	resimleriBirleştir(arkaPlan, saydamResim, birlesmisResim, cv::Point(0, 0));
	
	cv::imshow("result", birlesmisResim);
	waitKey(0);
}