由于毕设基本搞定,不用再在Linux下Qt中进行开发。现在转战VS继续OpenCV的学习,今天在学习过程中遇到了OpenCV对于图像的混合以及叠加的处理。混合和叠加是我定义的两种不同的图片处理方式,下面通过实战加以区分。
图片的混合是将两张图片进行线性混合,而产生一种你中有我,我中有你的朦胧感,就好像P图是的滤镜。OpenCV中使用的是addWeighted方法,主要参数按序分别为:图片x,权值alpha,图片y,权值beta,偏差值gamma,输出图片z。输出图片的计算公式为:z=x*alpha+y*beta+gamma,完成线性混合。需要注意的是图片x和图片y是要求尺寸大小相同的才可以进行融合处理。
#include
#include
#include
using namespace cv;
int WinMain()
{
Mat x = imread("F:\\demo.png");//720*682的车牌图像
Mat y(x.rows, x.cols, CV_8UC3, Scalar(0, 0, 255));//显式地定义一张和x尺寸相同的全红三通道图像
Mat dst;
addWeighted(x, 0.5, y, 0.5, 0.0, dst);
namedWindow("add", WINDOW_NORMAL);
imshow("add", dst);
waitKey(0);
return 0;
}
效果如截图:
图片的叠加又是另外一种概念了,大概的效果就是在一张大的图像上添加上希望添加的其他小图片,就好像P图的时候把自己从一个场景P到另外一个场景中去。实现方法也很简单,使用Rect在原图上截取ROI感兴趣图块,然后把和ROI区域相同大小的图片复制到ROI区域,那么原图中就会出现你想叠加的那个图片。实现代码如下:
#include
#include
#include
using namespace cv;
int WinMain()
{
Mat x = imread("F:\\demo.png");//720*682的车牌图像
Mat y = imread("F:\\logo.jpg");//509*212的小图像
Mat ROIx = x(Rect(100, 100, y.cols, y.rows));
y.copyTo(ROIx);
namedWindow("x", WINDOW_NORMAL);
imshow("x", x);
waitKey(0);
return 0;
}
效果如下:(图片上传都重新给了高宽,所以有所出入)
关于叠加这个问题,在网上看别人写的还有一种mask掩膜的方法,就是在copyTo( )加入第二个参数mask,大家可能对这个mask不是很懂。根据mask参数的定义可以知道,其实mask的效果就是这个英语单词的中文意思”面具“的效果。mask可以被定义为在一张全黑(像素值均为0)的图像上设置一块或多块其他颜色的图块(像素值非0),这些像素值非0的地方你可以理解为透光的孔,当把这张mask叠加在原图上时,只有在透光的孔的地方才能显示出原图的内容,而其他地方都是黑的。
所以例如x.copyTo(y,mask);这条语句的意思就是把mask叠加在图像x上,然后透过那些孔能够显示出来的部分复制给y,就是这么简单。所以在我看来mask的作用主要是用来通俗地说就是抠出一张图像中你感兴趣的部分,还可以起到屏蔽作用。