chroma key (绿背景抠图)

ChromaKey

1.创建掩图(mask.

  根据输入的绿背景图,我们可以访问其每一个像素,获取每一个像素RGB值,用th来表示 -(g-(r+b))的值,然后我们寻找到某一个界点值k,当th的值大于k的时候表示src图上该点的是绿色,生成的mask图对应的位置就用黑色标定,当th的值小于k的时候表示src图不是绿色,那么mask图上对应位置的像素用白色来表示。在图形学中,我们常用黑色来表示背景,用白色来表示前景。

 

2.利用第一步生成好mask图,把src复制(copyTo)到一张新的背景图中,在新的背景图中只显示我们要扣出来的object

   

3.因为在第一步生成mask也不是那么完美,可能还有某些绿色没有去掉,我们还需要再访问图片中每一个像素点,因为rgb图上绿色点的rgb的值是有范围的,那么我们就根据这个范围找出残留在图片上绿色的点,然后我们去掉该点。



#include
#include
#include
using namespace std;
using namespace cv;

//int main()
//{
//	IplImage *src = 0;
//	IplImage *histimg = 0;
//	if ((src = cvLoadImage("screen.jpg", 0)) == NULL) // force to gray image
//		return -1;
//	cvNamedWindow("Histogram", 3);   //创建直方图窗口
//	histimg = cvCreateImage(cvGetSize(src), src->depth, 3);
//	//改变背景色
//	for (int h = 0; h < histimg->height; h++)
//	{
//		for (int w = 0; w < histimg->width * 3; w++)
//		{
//			((uchar*)((int)histimg->imageData + histimg->widthStep*h))[w] = (uchar)125;  //将背静改为白色
//		}
//	}
//	cvShowImage("Histogram", histimg);
//	cvWaitKey(0);
//}


int main()
{
	Mat img = imread("foreground1.png");
	//imshow("Lena Original", img);
	for (int row = 0; row < img.rows; row++)
	{
		for (int col = 0; col < img.cols; col++)
		{
			/* 注意 Mat::at 函数是个模板函数, 需要指明参数类型, 因为这张图是具有红蓝绿三通道的图,
			所以它的参数类型可以传递一个 Vec3b, 这是一个存放 3 个 uchar 数据的 Vec(向量). 这里
			提供了索引重载, [2]表示的是返回第三个通道, 在这里是 Red 通道, 第一个通道(Blue)用[0]返回 */
			if ( img.at(row, col)[1]>140)
				{if(img.at(row, col)[0]<128) 
					if(img.at(row, col)[2]<128)
					{
						img.at(row, col)[0] = 255;
						img.at(row, col)[1] = 255;
						img.at(row, col)[2] = 255;
				 }
			}
// 			else
// 			{
// 				img.at(row, col)[0] = 0;
// 				img.at(row, col)[1] = 0;
// 				img.at(row, col)[2] = 0;
// 			}
				
		}
	}
	imshow("result", img);
	imwrite("result.png",img);

// 	cv::Mat result;
// 	result = imread("display1.bmp");
// 	cv::Mat forground= imread("screen.jpg",-1);
// 	//cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);
// 	cv::Mat forground1(forground.size(),CV_8UC3,cv::Scalar(255,255,255));
// 	forground.copyTo(forground1,result); // bg pixels not copied
// 	cv::namedWindow("Segmented Image");
// 	cv::imshow("Segmented Image",forground1);
// 	cv::imwrite("foreground1.png",forground1);
	cvWaitKey();
	return 0;
}


你可能感兴趣的:(opencv进化之旅)