图像分割系列10_绿幕视频的背景替换

OpenCV图像分割资料分享:贾志刚的OpenCV图像分割实战视频教程全套资料(包含配套视频、配套PPT的PDF文件、源码和用到的图片素材等)

案例实战——绿幕视频背景替换

 关键知识点

 分割算法选择
 背景融合 – 高斯模糊
 遮罩层生成

 

算法选择

 GMM或者Kmeans - ?? Bad idea, very slow!!!
 基于色彩的处理方法
 RGB与HSV色彩空间

                        

算法设计步骤

                                      

实例10:绿幕视频背景替换

如有资料等方面的问题,欢迎联系扣扣1837393417,共同探讨,共同进步!!!

#include 
#include 

using namespace cv;
using namespace std;

Mat replace_and_blend(Mat &frame, Mat &mask);
Mat background_01;//背景1
Mat background_02;//背景2
int main(int argc, char** argv) {
	// start here...	
	background_01 = imread("bg_01.jpg");
	background_02 = imread("bg_02.jpg");
	VideoCapture capture;//视频抓取
	capture.open("01.mp4");
	if (!capture.isOpened()) {
		printf("could not find the video file...\n");
		return -1;
	}
	const char* title = "input video";
	const char* resultWin = "result video";
	namedWindow(title, CV_WINDOW_AUTOSIZE);
	namedWindow(resultWin, CV_WINDOW_AUTOSIZE);
	Mat frame, hsv, mask;
	int count = 0;
	//测试视频读取
	//while (capture.read(frame)) {//判断读取视频单帧是否成功,读取单帧图像复制给frame对象
	//	imshow(title, frame);
	//	char c =waitKey(50);
	//	if (c == 27) {
	//		break;
	//	}

	//}
	///
	mask测试
	//while (capture.read(frame)) {
	//	cvtColor(frame, hsv, COLOR_BGR2HSV);//转换为HSV
	//	//原背景选择HSV--绿色
	//	inRange(hsv, Scalar(35, 43, 46), Scalar(60, 255, 255), mask);//mask数据调整60
	//	imshow("mask",mask);//显示mask
	//	count++;
	//	imshow(title, frame);//显示输入video
	//	char c = waitKey(1);
	//	if (c == 27) {
	//		break;
	//	}
	//}
	/
	while (capture.read(frame)) {//判断读取视频单帧是否成功,读取单帧图像复制给frame对象
		cvtColor(frame, hsv, COLOR_BGR2HSV);//转换为HSV
		inRange(hsv, Scalar(35, 43, 46), Scalar(60, 255, 255), mask);
		// 形态学操作,3*3进行腐蚀,然后高斯进行3*3的模糊,边界不变
		Mat k = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
		morphologyEx(mask, mask, MORPH_CLOSE, k);
		erode(mask, mask, k);
		GaussianBlur(mask, mask, Size(3, 3), 0, 0);
		//背景替换和混合
		Mat result = replace_and_blend(frame, mask);
		char c = waitKey(1);
		if (c == 27) {
			break;
		}
		imshow(resultWin, result);//显示处理结果video
		imshow(title, frame);//显示输入video
	}

	waitKey(0);
	return 0;
}
//背景替换和混合
Mat replace_and_blend(Mat &frame, Mat &mask) {
	Mat result = Mat::zeros(frame.size(), frame.type());
	int h = frame.rows;
	int w = frame.cols;
	int dims = frame.channels();

	// replace and blend
	int m = 0;
	double wt = 0;

	int r = 0, g = 0, b = 0;
	int r1 = 0, g1 = 0, b1 = 0;
	int r2 = 0, g2 = 0, b2 = 0;

	for (int row = 0; row < h; row++) {
		uchar* current = frame.ptr(row);//当前
		uchar* bgrow = background_01.ptr(row);//背景2
		uchar* maskrow = mask.ptr(row);//面罩 行
		uchar* targetrow = result.ptr(row);//目标 行
		for (int col = 0; col < w; col++) {
			m = *maskrow++;
			if (m == 255) { // 赋值为背景
				*targetrow++ = *bgrow++;
				*targetrow++ = *bgrow++;
				*targetrow++ = *bgrow++;
				current += 3;

			} else if(m==0) {// 赋值为前景
				*targetrow++ = *current++;
				*targetrow++ = *current++;
				*targetrow++ = *current++;
				bgrow += 3;
			} else {
				b1 = *bgrow++;
				g1 = *bgrow++;
				r1 = *bgrow++;

				b2 = *current++;
				g2 = *current++;
				r2 = *current++;

				// 权重
				wt = m / 255.0;
				
				// 混合
				b = b1*wt + b2*(1.0 - wt);
				g = g1*wt + g2*(1.0 - wt);
				r = r1*wt + r2*(1.0 - wt);

				*targetrow++ = b;
				*targetrow++ = g;
				*targetrow++ = r;
			}
		}
	}

	return result;
}

视频读取测试      视频播放

Mark测试

视频背景替换    视频背景替换播放

你可能感兴趣的:(openCV,图像分割,算法,opencv,计算机视觉)