基于hsv颜色空间的实时背景替换:
-
#include
-
using namespace cv;
-
Mat replace_and_blend(Mat &frame, Mat&mask);
-
Mat background,frame, hsv, mask,result;
-
int main(int arc, char** argv) {
-
background = imread("2.jpg");
-
namedWindow("input", CV_WINDOW_AUTOSIZE);
-
imshow("src", background);
-
VideoCapture capture;
-
capture.open("1.mp4");
-
while (capture.read(frame)) {
-
imshow("input", frame);
-
cvtColor(frame, hsv, CV_BGR2HSV);
-
inRange(hsv, Scalar(35, 43, 46), Scalar(77, 255, 255), mask);//颜色过滤,得到mask绿色部分为1,其它部分都为0
-
imshow("mask", mask);
-
Mat kernel = getStructuringElement(MORPH_RECT,Size(3,3));
-
morphologyEx(mask, mask, MORPH_DILATE, kernel);
-
GaussianBlur(mask, mask, Size(3, 3), 0, 0);//0,0会根据Size自动算的
-
result = replace_and_blend(frame, mask);
-
char c = waitKey(1);
-
if (c == 27) {
-
break;
-
}
-
imshow("input", frame);
-
imshow("result", result);
-
}
-
waitKey(0);
-
return 0;
-
}
-
Mat replace_and_blend(Mat &frame, Mat&mask) {
-
result = Mat::zeros(frame.size(), frame.type());
-
int h = frame.rows;
-
int w = frame.cols;
-
int dims = frame.channels();
-
int m ;
-
double wt ;
-
int b , g, r;
-
int b1, g1, r1;
-
int b2 , g2, r2 ;
-
//指针操作速度最快,直接访问地址
-
for (int row = 0; row < h; row++) {
-
uchar* current = frame.ptr(row);
-
uchar* bgrow = background.ptr(row);
-
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 = wt*b1 + (1 - wt)*b2;
-
g = wt*g1 + (1 - wt)*g2;
-
r = wt*r1 + (1 - wt)*r2;
-
*targetrow++ = b;
-
*targetrow++ = g;
-
*targetrow++ = r;
-
}
-
}
-
}
-
return result;
-
}
参考文献:https://blog.csdn.net/huanghuangjin/article/details/81461040