Opencv 学习笔记(五)绿幕视频背景替换(抠图)

菜鸟一枚,
这是我的第五个博客,
刚刚入门Opencv,
想将自己的学习过程分享给大家!!!

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>    //Opencv highgui 模块
#include <opencv2/imgproc/imgproc.hpp>    //Opencv 图像处理头文件

using namespace cv;
using namespace std;

Mat background_1 = imread("D:/opencv/opencvSRC/篮球场.jpg");
Mat background_2;
Mat result_ble(Mat &frame,Mat &mask);

int main()
{
	
	VideoCapture capture;
	capture.open("D:/opencv/opencvSRC/video.avi");
	if (!capture.isOpened())
	{
		printf("could not input the video file....");
		return -1;
	}
	background_1 = imread("D:/opencv/opencvSRC/篮球场.jpg");
	Mat frame, hsv, mask;
	while (capture.read(frame))
	{
		resize(background_1, background_2, Size(frame.cols, frame.rows));   //使背景图与视频素材大小相同,不然会报错

		cvtColor(frame, hsv, COLOR_BGR2HSV);
		inRange(hsv, Scalar(35, 43, 46), Scalar(77, 255, 255), mask);
		//形态学操作
		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 result1 = result_ble(frame, mask);

		imshow("mask", result1);
		imshow("frame", frame);
		char c = waitKey(50);
		if (c == 27)
		{
			break;
		}
	}
	
	waitKey(0);
	return 0;

}


Mat result_ble(Mat &frame, Mat &mask)
{
	Mat result = Mat::zeros(frame.size(), frame.type());
	int h = frame.rows;
	int w = frame.cols;
	int dims = frame.channels();

	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<uchar>(row);
		uchar* bgrow = background_2.ptr<uchar>(row);
		uchar* maskrow=mask.ptr<uchar>(row);
		uchar* targetrow = result.ptr<uchar>(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++;
				r1 = *bgrow++;
				g1 = *bgrow++;

				b2 = *current++;
				b2 = *current++;
				b2 = *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;
}

程序运行结果:
在这里插入图片描述
注:视频源于B站绿幕素材

谢谢同学们的阅读!!!

发布了28 篇原创文章 · 获赞 15 · 访问量 1047

猜你喜欢

转载自blog.csdn.net/qq_43765237/article/details/105080918