1. 感兴趣区域:ROI

在图像处理领域,我们常常需要设置感兴趣区域(ROI,regionofmterest),来专注或者简化工作过程。也就是从图像中选择的一个图像区域,这个区域是图像分析所关注的重点。我们圈定这个区域,以便进行进一步处理。而且,使用ROI指定想读入的目标,可以减少处理时间,增加精度,给图像处理来带不小的便利。

定义ROI区域有两种方法:第一种是使用表示矩形区域的Rect。它指定矩形的左上角坐标(构造函数的前两个参数)和矩形的长宽(构造函数的后两个参数)以定义一个矩形区域。

其中,image为己经载入好的图片。

//定义一个Mat类型并给其设定ROI区域
Mat imageROI;
//方法一
imageROI=image(Rect(500,250,logo.cols,logo.rows));

另一种定义ROI的方式是指定感兴趣行或列的范围(Range)。Range是指从起始索引到终止索引(不包括终止索引)的一连段连续序列。cRange可以用来定义Range。如果使用Range来定义ROI,那么前例中定义ROI的代码可以重写为:

//方法二
imageROI=image(Range(250,250+IogoImage.rows),Range(200,200+logolmage.cols));

下面我们来看一个实例,显示如何利用ROI将一幅图加到另一幅图的指定位置。大家如果需要复制以下函数中的代码直接运行,可以自己建一个基于console的程序,然后把函数体中的内容复制到main函数中,然后找两幅大小合适的图片,
加入到工程目录下,并和代码中读取的文件名一致即可。

在下面的代码中,我们通过一个图像掩膜(mask),直接将插入处的像素设置为图像的像素值,这样效果会很逼真。

#include<opencv2\opencv.hpp>
using namespace cv;//利用感兴趣区域实现图像叠加
bool ROI_AddImage(){///读入图像Mat srcImage = imread("fengjing.jpg");Mat logoImage = imread("fengjing3.jpg");if (!srcImage.data){printf("读取srcImage失败!\n");return false;}if (!logoImage.data){printf("读取logoImage失败!\n");return false;}//定义一个Mat类型并设定ROI区域Mat imageROI = srcImage(Rect(100, 150, logoImage.cols, logoImage.rows));//加载掩膜(必须是灰度图)Mat mask = imread("fengjing3.jpg", 0);//将掩膜复制到ROIlogoImage.copyTo(imageROI, mask);//显示结果namedWindow("<1>利用ROI实现图像叠加到示例窗口");imshow("<1>利用ROI实现图像叠加到示例窗口",srcImage);return true;
}
int main(){ROI_AddImage();waitKey();
}

这个函数首先是载入了两张jpg图片到srclmagel和logolmage中,然后定义了一个Mat类型的imageROI,并使用Rect设置其感兴趣区域为srclmagel中的一块区域,将imageROI和srclmagel关联起来。接着定义了一个Mat类型的的mask
并读入fengjing3.jpg,顺势使用Mat::copyTo把mask中的内容复制到imageROl中,于是就得到了最终的效果图。namedWindow和imshow配合使用,显示出最终的结果。

2. 线性混合操作

线性混合操作是典型的二元(两个输入)大的像素操作,他的理论公式如下:
g(x)=(1−a)fa(x)+af3(x)g(x)=(1-a)f_{a}(x)+af_{3}(x)g(x)=(1−a)fa​(x)+af3​(x)
我们通过在范围0到1之家改变alpha的值,来对两幅图像(f0(x)和f1(x))或两段视频(同样为(f0(x)和fl(x))产生时间上的画面叠化(cross-dissolve)效果,就像幻灯片放映和电影制作中的那样,也就是在幻灯片翻页时设置的前后页缓慢过渡叠加效果,以及电影情节过渡时经常出现的画面叠加效果。

实现方面,主要运用了OpenCV中addWeighted函数,下面来一起全面地了解它。

3. 计算数组加权和:addWeighted()函数

这个函数的作用是计算两个数组(图像阵列)的加权和。原型如下:

void(InputArray src1,doubIe alpha,InputArray src2,double beta,double gamma,OutputArray dst,int dtype=-1);
  • 第一个参数,InputArray类型的src1,表示需要加权的第一个数组,常常填一个Mat;
  • 第二个参数,double类型的alpha,表示第一个数组的权重;
  • 第三个参数,InputArray类型的src2,表示第二个数组,它需要和第一个数组拥有相同的尺寸和通道数;
  • 第四个参数,double类型的beta,表示第二个数组的权重值;
  • 第五个参数,double类型的gamma,一个加到权重总和上的标量值。其含义通过接下来列出的式子自然会理解;
  • 第六个参数,OutputArray类型的dst,输出的数组,它和输入的两个数组拥有相同的尺寸和通道数;
  • 第七个参数,int类型的dtype,输出阵列的可选深度,有默认值-1。当两个输入数组具有相同的深度时,这个参数设置为-1(默认值),即等同于
    src1.depth()。

下面的数学公式表示:用addWeighted函数计算以下两个数组(src1和src2)的加权和,得到结果输出给第四个参数,也就是addWeighted函数的作用的矩阵表达式。

dst=src1[I]*alpha+src2[I]*beta+gemma;

其中I是多维数组的索引值。而且,在遇到多通道数组的时候,每个通道都需要独立地进行处理。另外需要注意的是,当输出数组的深度为CV_32S时,这个函数就不适用了,这时候就会内存溢出或者算出的结果压根不对。

#include<opencv2\opencv.hpp>
using namespace cv;//实现图像线性混合
bool LinearBlending(){//定义局部变量double alphaValue = 0.5;double betaValue;Mat srcImage2, srcImage3, dstImage;//读取图像srcImage2 = imread("fengjing.jpg");srcImage3 = imread("fengjing2.jpg");if (!srcImage2.data){printf("读取srcImage2失败!\n");}if (!srcImage3.data){printf("读取srcImage3失败!\n");}//做图像混合加权操作betaValue = (1.0 - alphaValue);addWeighted(srcImage2, alphaValue, srcImage3, betaValue, 0.0, dstImage);//创建并显示图像namedWindow("<2>线性混合示例窗口【原图】", 1);imshow("<2>线性混合示例窗口【原图】", srcImage2);namedWindow("<3>线性混合示例窗口【原图】", 1);imshow("<3>线性混合示例窗口【原图】", dstImage);return true;
}
int main(){LinearBlending();waitKey();
}


对以上代码进行解析:
(0)首先定义局部变量

//定义局部变量double alphaValue = 0.5;double betaValue;Mat srcImage2, srcImage3, dstImage;

(1)去除两幅图先给,并做错误处理。

//读取图像srcImage2 = imread("fengjing.jpg");srcImage3 = imread("fengjing2.jpg");if (!srcImage2.data){printf("读取srcImage2失败!\n");}if (!srcImage3.data){printf("读取srcImage3失败!\n");}

我们是对srcImage2和srcImage2进行求和,所以必须保障两个图片的尺寸大小是一样的。
(2)进行图像的混合加权操作。

//做图像混合加权操作betaValue = (1.0 - alphaValue);addWeighted(srcImage2, alphaValue, srcImage3, betaValue, 0.0, dstImage);

(3)显示图像

//创建并显示图像namedWindow("<2>线性混合示例窗口【原图】", 1);imshow("<2>线性混合示例窗口【原图】", srcImage2);namedWindow("<3>线性混合示例窗口【原图】", 1);imshow("<3>线性混合示例窗口【原图】", dstImage);

4. 初级图像混合

(ROI和addWeighte混合)

#include<opencv2\opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
//全局函数声明
bool ROI_AddImage();
bool LinearBlending();
bool ROI_LinearBlending();//利用感兴趣区域实现图像叠加
bool ROI_AddImage(){///读入图像Mat srcImage = imread("fengjing.jpg");Mat logoImage = imread("fengjing3.jpg");if (!srcImage.data){printf("读取srcImage失败!\n");return false;}if (!logoImage.data){printf("读取logoImage失败!\n");return false;}//定义一个Mat类型并设定ROI区域Mat imageROI = srcImage(Rect(100, 150, logoImage.cols, logoImage.rows));//加载掩膜(必须是灰度图)Mat mask = imread("fengjing3.jpg", 0);//将掩膜复制到ROIlogoImage.copyTo(imageROI, mask);//显示结果namedWindow("<1>利用ROI实现图像叠加到示例窗口");imshow("<1>利用ROI实现图像叠加到示例窗口",srcImage);return true;
}//实现图像线性混合
bool LinearBlending(){//定义局部变量double alphaValue = 0.5;double betaValue;Mat srcImage2, srcImage3, dstImage;//读取图像srcImage2 = imread("fengjing.jpg");srcImage3 = imread("fengjing2.jpg");if (!srcImage2.data){printf("读取srcImage2失败!\n");}if (!srcImage3.data){printf("读取srcImage3失败!\n");}//做图像混合加权操作betaValue = (1.0 - alphaValue);addWeighted(srcImage2, alphaValue, srcImage3, betaValue, 0.0, dstImage);//创建并显示图像namedWindow("<2>线性混合示例窗口【原图】", 1);imshow("<2>线性混合示例窗口【原图】", srcImage2);namedWindow("<3>线性混合示例窗口【原图】", 1);imshow("<3>线性混合示例窗口【原图】", dstImage);return true;
}//初级图像混合
bool ROI_LinearBlending(){//读取图像Mat srcImage4 = imread("fengjing.jpg", 1);Mat logoImage = imread("fengjing3.jpg");if (!srcImage4.data){printf("打开drcImage4失败!\n");}if (!logoImage.data){printf("开打logoImage失败!\n");}//定义一个感兴趣空间Mat imageROI;imageROI = srcImage4(Rect(100, 150, logoImage.cols, logoImage.rows));//将logoImage加到srcImage4上addWeighted(imageROI, 0.5, logoImage, 0.3, 0.0, imageROI);//显示结果namedWindow("<4>区域线性混合示例窗口");imshow("<4>区域线性混合示例窗口", srcImage4);return true;
}int main(){system("color 5E");if (ROI_AddImage()&&LinearBlending()&ROI_LinearBlending()){cout << endl << "运行成功!";}waitKey(0);return 0;
}

opencv(16) ROI区域图像叠加图像混合相关推荐

  1. 《OpenCV3编程入门》学习笔记5 Core组件进阶(二) ROI区域图像叠加图像混合

    第5章 Core组件进阶 5.2 ROI区域图像叠加&图像混合 5.2.1 感兴趣区域ROI(region of interest) 1.定义ROI区域两种方法: (1)定义矩形区域Rect: ...

  2. opencv 手选roi区域_【OpenCV】选择ROI区域

    问题描述:在测试目标跟踪算法时,需要选择不同区域作为目标,进行目标跟踪,测试目标跟踪的效果. 解决思路: 1.OpenCV中提供了鼠标交互控制,利用setMouseCallback()给固定的窗口设置 ...

  3. (OpenCV — 7)ROI 区域图像叠加&图像混合

    1 感兴趣区域: ROI 在图像处理领域,我们常常需要设置感兴趣区域 ( ROI. region of interest) ,来专注或者简化工作过程 . 也就是从图像中选择的一个图像区域,这个区域是图 ...

  4. opencv 手选roi区域_【opencv学习笔记六】图像的ROI区域选择与复制

    图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感兴趣区域ROI.今天我们来看一下如何设置图像的感兴趣区域ROI.以及对ROI区域图像 ...

  5. python opencv图像叠加/图像融合/mask掩模

    目录 1.图像叠加 2.图像融合 3.图像mask掩模(包括按位AND,OR,NOT和XOR运算) 1.图像叠加 可以通过OpenCV函数cv.add()或简单地通过numpy操作添加两个图像,res ...

  6. python opencv 图像叠加,python opencv图像叠加/图像融合/mask掩模

    目录python 一.图像叠加 能够经过OpenCV函数cv.add()或简单地经过numpy操做添加两个图像,res = img1 + img2.两个图像应该具备相同的深度和类型,或者第二个图像能够 ...

  7. opencv 手选roi区域_如何用opencv实现感兴趣区域ROI的选取

    OpenCV中感兴趣区域的选取与检测 感兴趣区域(Region of Interest, ROI)的选取,一般有两种情形:1)已知ROI在图像中的位置:2)ROI在图像中的位置未知. 1)第一种情形 ...

  8. opencv 手选roi区域_利用opencv进行眼动检测

  9. [Python从零到壹] 三十七.图像处理基础篇之图像融合处理和ROI区域绘制

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  10. 【opencv】(1) 基础操作:图像视频读取、图像截取、颜色通道

    主要内容有:图像及视频的读取和保存.图像显示.转换灰度图.图像截取.颜色通道提取和组合 那我们开始吧. 1. 图像操作 首先我们导入opencv库,彩色图像一般都是由RGB(红绿蓝)三颜色通道构成,灰 ...

最新文章

  1. 《Oracle高性能SQL引擎剖析:SQL优化与调优机制详解》一1.1 生成执行计划
  2. Oracle 表的访问方式(2)-----索引扫描
  3. ubuntu 使用FFTW快速计算离散傅里叶变换
  4. OAuth2.0文档
  5. Linux操作系统下软件的安装方法大全
  6. S3 Texture Compression
  7. 为何在wpf中textbox的值有时不会实时的变化
  8. Maven 多环境配置profile
  9. python 字典处理_python之高效处理字典、序列的一些语法
  10. matplotlib快速画图
  11. webservice框架 java_java开发webservice的几种方式详解
  12. JL 杰理 AC692N系列TWS 蓝牙音箱 开发
  13. BZOJ 1778: [Usaco2010 Hol]Dotp 驱逐猪猡 (高斯消元)
  14. DirectX11--教程项目无法编译、运行的解决方法
  15. 使用gluLookAt发生无法解析符号的错误
  16. 高频电路之LC并联谐振回路
  17. HTML之FrameSet,Frame和Iframe区别
  18. 终极解码2013春节版在windows7上使用
  19. Linux配置无密登录
  20. Laravel自定义artisan命令在Sell中运行

热门文章

  1. JAVA中分号用中文还是英文_【英文中有分号(;)吗?怎么用呢?】作业帮
  2. 设置部署服务器的运行端口,以太坊swarm配置bzz运行常见问题解决方案
  3. PAT 1055 集体照
  4. 一般描绘性形容词_描绘性形容词和限制性形容词
  5. c语言贪吃蛇答辩项目,贪吃蛇项目V1答辩.PDF
  6. 新电视显示服务器失败,电视网络连接失败原因是什么
  7. Python入门基础-七、案例4 52周存钱挑战 #列表(list)#math 库#for循环#range()用法#函数的参数传递#datetime库
  8. 周怎么换算成月_时间序列数据,只找到了周数据,怎么把它转化成月数据?
  9. 无线路由器dns服务器是什么意思,无线路由器dns是什么
  10. 华为服务器型号分类,解析华为服务器