基于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
