最近心血来潮,想具体的去学习一下图像处理,所以报了知识星球的一个OpenCV研习社,将自己每天的学习,分享一下。写个 blog 加深一下知识。
知识点: 色彩空间与色彩空间转换
API知识点
CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
参数一:输入的图片
参数二:输出的图片(大小和深度和输入图片一致)
参数三:色彩空间转换码
参数四:目标图像中的通道数; 如果参数为0,则从输入图片(src)和色彩空间转换码(code)自动导出通道数。
功能:将图像从一个颜色空间转换为另一个颜色空间。
CV_EXPORTS_W void inRange(InputArray src, InputArray lowerb,
InputArray upperb, OutputArray dst);
参数一:第一个输入数组。
参数二:包含下边界数组或标量。
参数三:包含上边界阵列或标量。
参数四:输出数组与src和CV_8U类型相同。
功能:检查数组元素是否位于另外两个数组的元素之间。
补充:当比较结果为真时,outputarray的相应元素设置为 255,否则设置为 0 。
int main(int argc, char* argv[])
{
Mat src = imread("C:/Users/XMuser/Desktop/Opencv/cat.jpg");
if (src.empty())
{
printf("could not load image ...\n");
return -1;
}
namedWindow("input", WINDOW_AUTOSIZE);
imshow("input", src);
// RGB to HSV
Mat hsv;
cvtColor(src, hsv, COLOR_BGR2HSV);
imshow("hsv", hsv);
// RGB to YUV
Mat yuv;
cvtColor(src, yuv, COLOR_BGR2YUV);
imshow("yuv", yuv);
// RGB to YCrCb 一般用于皮肤检测(有色人种很明显)
Mat ycrcb;
cvtColor(src, ycrcb, COLOR_BGR2YCrCb);
imshow("ycrcb", ycrcb);
Mat src2 = imread("C:/Users/XMuser/Desktop/Opencv/greenback.png");
imshow("src2", src2);
Mat mask;
cvtColor(src2, hsv, COLOR_BGR2HSV);
//提取色彩指定区域 示例为绿色范围
inRange(hsv, Scalar(35, 43, 46), Scalar(77,255,255), mask);
imshow("mask", mask);
waitKey(0);
return 0;
}
传送门:官方教程 ---- cvtColor
传送门:官方教程 ---- inRange
既然我们现在可以将图片根据颜色范围值提取出我们想要的模块,根据前面所学的知识,我们就可以将图片中的人物换一个背景。
int main(int argc, char* argv[])
{
Mat hsv;
Mat src2 = imread("C:/Users/XMuser/Desktop/Opencv/greenback.png");
namedWindow("src2", WINDOW_NORMAL);
imshow("src2", src2);
Mat mask;
cvtColor(src2, hsv, COLOR_BGR2HSV);
inRange(hsv, Scalar(35, 43, 46), Scalar(77,255,255), mask);
Mat dst,dst1,dst2,dst3,dst4;
//这里取反,人物图像模块抠出来,即人物模块显示白色,背景显示黑色
bitwise_not(mask, dst1);
//这里dst1不可以和src2 直接 与,与操作前提是两者具有相同大小
//src2和dst1的flags属性值是不一样的,所以channels() 返回值也不一样
bitwise_and(src2, src2, dst2, dst1);
//创建一个空白的图像,背景色设为黄色
dst3 = Mat::zeros(src2.size(), src2.type());
Rect rect(0, 0, src2.cols, src2.rows);
dst3(rect) = Scalar(0, 255, 255);
//扣除中间人物图像
bitwise_or(dst3, dst3, dst4, mask);
//将两个图片融合
bitwise_or(dst4, dst2, dst);
//这里尝试用加法,发现结果是一样的,只是一个逻辑运算,一个是算术运算
//add(dst2, dst4, dst);
imshow("dst", dst);
waitKey(0);
return 0;
}