1 #include <opencv2/opencv.hpp>
2 #include <iostream>
3
4 using namespace cv;
5 using namespace std;
6
7 Mat replace_and_blend(Mat &frame, Mat &mask);
8 Mat background_01;//背景1
9 Mat background_02;//背景2
10 int main(int argc, char** argv) {
11 // start here...
12 background_01 = imread("bg_01.jpg");
13 background_02 = imread("bg_02.jpg");
14 VideoCapture capture;//视频抓取
15 capture.open("01.mp4");
16 if (!capture.isOpened()) {
17 printf("could not find the video file...\n");
18 return -1;
19 }
20 const char* title = "input video";
21 const char* resultWin = "result video";
22 namedWindow(title, CV_WINDOW_AUTOSIZE);
23 namedWindow(resultWin, CV_WINDOW_AUTOSIZE);
24 Mat frame, hsv, mask;
25 int count = 0;
26 //测试视频读取
27 //while (capture.read(frame)) {//判断读取视频单帧是否成功,读取单帧图像复制给frame对象
28 // imshow(title, frame);
29 // char c =waitKey(50);
30 // if (c == 27) {
31 // break;
32 // }
33
34 //}
35 ///
36 mask测试
37 //while (capture.read(frame)) {
38 // cvtColor(frame, hsv, COLOR_BGR2HSV);//转换为HSV
39 // //原背景选择HSV--绿色
40 // inRange(hsv, Scalar(35, 43, 46), Scalar(60, 255, 255), mask);//mask数据调整60
41 // imshow("mask",mask);//显示mask
42 // count++;
43 // imshow(title, frame);//显示输入video
44 // char c = waitKey(1);
45 // if (c == 27) {
46 // break;
47 // }
48 //}
49 /
50 while (capture.read(frame)) {//判断读取视频单帧是否成功,读取单帧图像复制给frame对象
51 cvtColor(frame, hsv, COLOR_BGR2HSV);//转换为HSV
52 inRange(hsv, Scalar(35, 43, 46), Scalar(60, 255, 255), mask);
53 // 形态学操作,3*3进行腐蚀,然后高斯进行3*3的模糊,边界不变
54 Mat k = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
55 morphologyEx(mask, mask, MORPH_CLOSE, k);
56 erode(mask, mask, k);
57 GaussianBlur(mask, mask, Size(3, 3), 0, 0);
58 //背景替换和混合
59 Mat result = replace_and_blend(frame, mask);
60 char c = waitKey(1);
61 if (c == 27) {
62 break;
63 }
64 imshow(resultWin, result);//显示处理结果video
65 imshow(title, frame);//显示输入video
66 }
67
68 waitKey(0);
69 return 0;
70 }
71 //背景替换和混合
72 Mat replace_and_blend(Mat &frame, Mat &mask) {
73 Mat result = Mat::zeros(frame.size(), frame.type());
74 int h = frame.rows;
75 int w = frame.cols;
76 int dims = frame.channels();
77
78 // replace and blend
79 int m = 0;
80 double wt = 0;
81
82 int r = 0, g = 0, b = 0;
83 int r1 = 0, g1 = 0, b1 = 0;
84 int r2 = 0, g2 = 0, b2 = 0;
85
86 for (int row = 0; row < h; row++) {
87 uchar* current = frame.ptr<uchar>(row);//当前
88 uchar* bgrow = background_01.ptr<uchar>(row);//背景2
89 uchar* maskrow = mask.ptr<uchar>(row);//面罩 行
90 uchar* targetrow = result.ptr<uchar>(row);//目标 行
91 for (int col = 0; col < w; col++) {
92 m = *maskrow++;
93 if (m == 255) { // 赋值为背景
94 *targetrow++ = *bgrow++;
95 *targetrow++ = *bgrow++;
96 *targetrow++ = *bgrow++;
97 current += 3;
98
99 } else if(m==0) {// 赋值为前景
100 *targetrow++ = *current++;
101 *targetrow++ = *current++;
102 *targetrow++ = *current++;
103 bgrow += 3;
104 } else {
105 b1 = *bgrow++;
106 g1 = *bgrow++;
107 r1 = *bgrow++;
108
109 b2 = *current++;
110 g2 = *current++;
111 r2 = *current++;
112
113 // 权重
114 wt = m / 255.0;
115
116 // 混合
117 b = b1*wt + b2*(1.0 - wt);
118 g = g1*wt + g2*(1.0 - wt);
119 r = r1*wt + r2*(1.0 - wt);
120
121 *targetrow++ = b;
122 *targetrow++ = g;
123 *targetrow++ = r;
124 }
125 }
126 }
127
128 return result;
129 }