版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/chenxun2009/article/details/38407903
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<iostream>
- #include<cv.h>
- #include<highgui.h>
- 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<Vec3b>(row, col)[1]>140)
- {if(img.at<Vec3b>(row, col)[0]<128)
- if(img.at<Vec3b>(row, col)[2]<128)
- {
- img.at<Vec3b>(row, col)[0] = 255;
- img.at<Vec3b>(row, col)[1] = 255;
- img.at<Vec3b>(row, col)[2] = 255;
- }
- }
- // else
- // {
- // img.at<Vec3b>(row, col)[0] = 0;
- // img.at<Vec3b>(row, col)[1] = 0;
- // img.at<Vec3b>(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;
- }