您的位置:首页 > 运维架构

OpenCV 学习记录4 ROI区域图像叠加及线性图像混合

2017-04-17 00:40 621 查看

前言

主要参考学习了毛星云的著作及博客,大部分都是和原文类似的,所以也不多说什么,就说说自己的理解以及自己在学习过程中遇到的一些问题。附上浅墨的博客原文:原文传送门

文章主要学习了如何对图片取一个矩形区域然后针对这部分进行修改而不是整个图片修改,这块区域就叫做ROI( Region Of Interest )。

刚开始看的时候打算自己随便拿两张图片进行ROI区域图像叠加的,但是一直出现内存溢出的异常,想很久也没搞懂为什么错了,于是去找浅墨大大的源代码,发现是图片的问题,在取矩形区域的时候如果不注意图片本来的宽度和高度和容易会溢出,得到的图片大小比原来大,于是报错。所以也是建议第一次弄的话直接用大神的源码及图片吧,因为有一些参数就是和图片对应才设置成那个数值的,以免导致程序一直报错然后把时间都浪费在奇怪的地方,对正确的代码多思考,直接上代码吧,虽然是照着打的,但是也领悟到了一些东西,建议大家也自己打一遍。

#include <cv.h>
#include <highgui.h>
#include <iostream>

//-----------------------------------【命名空间声明部分】---------------------------------------
//     描述:包含程序所使用的命名空间
//-----------------------------------------------------------------------------------------------
using namespace cv;
using namespace std;

//-----------------------------------【全局函数声明部分】--------------------------------------
//     描述:全局函数声明
//-----------------------------------------------------------------------------------------------
bool ROI_AddImage();
bool LinearBlending();
bool ROI_LinearBlending();

int main() {

if (ROI_AddImage() && LinearBlending() && ROI_LinearBlending())
{
cout << endl << "嗯。好了,得出了你需要的图像~! : )";
}

waitKey(0);
return 0;

}
//ROI区域图像叠加
bool ROI_AddImage()
{
Mat srcImage1 = imread("dota_pa.jpg");
Mat logoImage = imread("dota_logo.jpg");

if (!srcImage1.data) { printf("读取srcImage1错误\n"); return false; }
if (!logoImage.data) { printf("读取logoImage错误\n");return false; }

Mat imageROI = srcImage1(Rect(200, 250, logoImage.cols, logoImage.rows));
/*这里imageROI是srcImage1的一个矩形区域,像前篇文章说的,这是对同一个图片的引用,
所以接下来imageROI改变会导致srcImage1改变,另外这里的参数注意,
看看图片的信息可以发现data_logo是200x200 , dota_pa.jpg是800x450
,所以y的参数取250时,画出来的矩形边界刚好是dota_pa.jpg的边界。
而一旦y>250,就会出现报错出现异常啦 */

Mat mask = imread("dota_logo.jpg");

logoImage.copyTo(imageROI, mask);
/*这里把mask完全复制给imageROI,所以imageROI指向的那块区域就变成mask的样子了 ,
所以srcImage1的某个矩形区域就变成了mask。
但这里有个问题不理解,为什么要用logoImage.copyTo,
因为感觉复制过程和logoImage没关系,
可把这个对象换成其他的Mat对象又会报错(如srcImage1.copyTo(imageROI, mask);)
有理解的朋友欢迎留言 */

imshow("<1>利用ROI实现图像叠加示例窗口", srcImage1);//最后把合成后的图片显示出来

return true;
}

bool LinearBlending()
{
double alphaValue = 0.5;
double betaValue;
Mat srcImage2, srcImage3, dstImage;
srcImage2 = imread("mogu.jpg");
srcImage3 = imread("rain.jpg");

if (!srcImage2.data) { printf("读取错误\n"); return false; }
if (!srcImage3.data) { printf("读取错误\n");return false; }

betaValue = (1.0 - alphaValue);
addWeighted(srcImage2, alphaValue, srcImage3, betaValue, 0.0, dstImage);
/*这是线性图像混合函数, 表示dstImage=srcImage2*alphaValue+srcImage3*betaValue+ 0.0
最后合成的图片保存到dstImage;
如果 alphaValue > betaValue ,那么合成后的dstImage主要是srcImage2的样子,srcImage3的样子会比较浅。
可以适当调整alphaValue、betaValue的值然后看看图片效果就明白了。*/

imshow("<2>线性混合示例窗口,效果图",dstImage);
imshow("<2>线性混合示例窗口,原图", srcImage2);

return true;
}
//这是取一个ROI区域进行线性图像混合
bool ROI_LinearBlending()
{
Mat srcImage4 = imread("dota_pa.jpg");
Mat logoImage = imread("dota_logo.jpg");

if (!srcImage4.data) { printf("读取错误\n"); return false; }
if (!logoImage.data) { printf("读取错误\n"); return false; }

Mat imageROI = srcImage4(Rect(200, 250, logoImage.cols, logoImage.rows));

addWeighted(imageROI, 0.5, logoImage, 0.3, 0.0, imageROI);
//将imageROI和logoImage混合后保存到imageROI,原来的被覆盖。

imshow("<3>区域线性图像混合示例窗口", srcImage4);

return true;
}


希望尽快学会主要功能然后完成项目吧,任务繁重,加油。

另外依旧,欢迎指出问题和交流意见。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opencv
相关文章推荐