#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
using namespace cv;
int main()
{
Mat first = imread("E:/hh.jpg");
Mat second = imread("E:/cc.jpg");
namedWindow("first");
namedWindow("second");
imshow("first",first);
imshow("second", second);
Mat ROI;
ROI = second(Rect(0, 0,first.cols , first.rows));
addWeighted(first, 0.5, ROI, 0.5, 0.0, ROI);
namedWindow("RO",CV_WINDOW_NORMAL);
imshow("RO", ROI);
waitKey(0);
return 0;
}
ps:个人水平有限,如有发现错误,还请指出,感谢感谢。
Mat first = imread("E:/hh.jpg");
注意点1
一开始还以为这一句太简单,没什么好注意的,后来调试的时候才发现,个人基础真的是很差。
写路径的时候斜杠究竟是向左还是向右呢?
在自己电脑文件夹里地址栏看路径的时候发现斜杠好像都是向右的?
所以要注意下,程序路径里的斜杠都是向左的,如果斜杠向右,编译会提醒中断,然后输出两张“灰色”的图片。
Mat ROI;
ROI = second(Rect(0, 0,first.cols , first.rows));
addWeighted(first, 0.5, ROI, 0.5, 0.0, ROI);
注意点2
这一次所做的图像混合用到的是addWeighted()函数。它使用的时候有一个注意点,两张图片大小必须一样才能进行混合。这一点很重要,第一次用没有注意到,编译一直报错,浪费了很多时间。
addWeighted()函数
第一个参数是是第一幅图片,即想要进行混合的图片的名称。
第二个参数是第一幅图片“给”最终混合图片的像素权重。
第三个与第四个参数参考第一个与第二个。
第五个参数是合成图像时的偏移量,在最终效果上表现为,偏移量越大,图像越白亮。
第六个参数是最终输出的图像的位置,就是告诉程序输出到哪一个mat。
还有几个问题,是写博客的时候偶然想到的,想想还挺有意思的。
两幅图像权重之和一定要是1吗?单个权重值能随意变化吗?权重调的很大,比如达到100,图片会是什么效果呢?偏移量能为负值吗?权重能为负吗?
1.首先权重之和不一定要为1,我们可以随意调整,但是超出一定范围后,效果会差强人意,毕竟从根本来说只是数学计算。
从图像来说,单个权重越高,则该图像“给与的部分”曝光值会越大(也就是越白),最终会过曝。
2.那如果两个权重都很低,比如0.1和0.1时会怎么样?输出图片会变得很暗,可以理解成程序给剩下的图像空区填充了黑色。
3.如果单个权重出现负值,另一个正常,那么最终输出的效果就是图像反相效果,也就是常说的底片。
4.偏移量很大时,也会出现过曝。偏移量为负值时,亮度则会开始降低。
上面说使用addWeighted()函数,两张图片的尺寸需要相同,万一要是不同呢?实际上这种情况才是常态。
这也是我们用到Rect()函数的原因。
我们需要用到Rect()函数来截取两张图片中比较大的那一张的一部分来完成混合。它截取的是矩形,如果是其他图形,也有对应的函数。
函数之前的mat名表示程序从哪一张图片截取。
第一个参数和第二个参数需要联合起来看,表明截取区的左上角的点在原图上的坐标。
第三个第四个参数也要联合起来看,表示截取的矩形的长和宽,cols为行,rows为列。
并不是每一个函数都需要理解的很透彻,学会抓住重点才能在有限的时间里学到更多。