如有资料等方面的问题,欢迎联系扣扣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;
}