需求:在背景图上贴人像,贴图为纯色背景的人像图。
1、通过imread读取原图
cv::Mat src_IMG = cv::imread("C:\\Img\\front.bmp");//读取被贴图
cv::Mat logo_IMG = cv::imread("C:\\Img\\head.jpg");//读取贴图
2、处理贴图(获取贴图的掩码图)
cv::Scalar lower(250, 250, 250); // 较低的颜色阈值
cv::Scalar upper(255, 255, 255); // 较高的颜色阈值
cv::Mat mask;
cv::inRange(logo_IMG, lower, upper, mask);
inRange函数解析:筛选图中自己设定的颜色范围[lower,upper],若像素点颜色在范围内,则在生成矩阵中相应位置设为255(白色),否则为0(黑色)。
3、反转掩码图的值(为后续贴图做准备)
// 反转掩膜,使颜色范围内的像素变为0,范围外的像素变为255
cv::Mat logo_IMG_mask;
cv::bitwise_not(mask, logo_IMG_mask);
bitwise_not函数解析:函数对mask的每个元素执行按位非操作。(在这里0变255,255变0)
4、裁剪出背景图中要贴图的部分ROI
cv::Mat src_IMG_ROI = src_IMG(cv::Rect(500, 200, logo_IMG.cols, logo_IMG.rows));
5、贴图(前面要获取掩码和反转掩码的原因来了)
logo_IMG.copyTo(src_IMG_ROI, logo_IMG_mask);
copyTo函数解析:copyTo(OutputArray dst, InputArray mask) 可通过mask来设定贴图中会被复制的区域
mask为可选参数,没有mask时,直接贴图。
有mask时,当mask像素点为0时,不复制像素点的数值,
非0时,复制像素点的值。(去贴图纯色背景)
6、效果展示
(贴图)
(inrange获取的掩码图)
(bitwise_not翻转的掩码图)
(背景图)
(结果图)
(copyTo无mask的结果图)
存在的问题:
如果贴图中主要部分存在背景色的像素点,也会被改为设置为不需要复制贴图的部分。