opencv(16) ROI区域图像叠加图像混合
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区域图像叠加图像混合相关推荐
- 《OpenCV3编程入门》学习笔记5 Core组件进阶(二) ROI区域图像叠加图像混合
第5章 Core组件进阶 5.2 ROI区域图像叠加&图像混合 5.2.1 感兴趣区域ROI(region of interest) 1.定义ROI区域两种方法: (1)定义矩形区域Rect: ...
- opencv 手选roi区域_【OpenCV】选择ROI区域
问题描述:在测试目标跟踪算法时,需要选择不同区域作为目标,进行目标跟踪,测试目标跟踪的效果. 解决思路: 1.OpenCV中提供了鼠标交互控制,利用setMouseCallback()给固定的窗口设置 ...
- (OpenCV — 7)ROI 区域图像叠加&图像混合
1 感兴趣区域: ROI 在图像处理领域,我们常常需要设置感兴趣区域 ( ROI. region of interest) ,来专注或者简化工作过程 . 也就是从图像中选择的一个图像区域,这个区域是图 ...
- opencv 手选roi区域_【opencv学习笔记六】图像的ROI区域选择与复制
图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感兴趣区域ROI.今天我们来看一下如何设置图像的感兴趣区域ROI.以及对ROI区域图像 ...
- python opencv图像叠加/图像融合/mask掩模
目录 1.图像叠加 2.图像融合 3.图像mask掩模(包括按位AND,OR,NOT和XOR运算) 1.图像叠加 可以通过OpenCV函数cv.add()或简单地通过numpy操作添加两个图像,res ...
- python opencv 图像叠加,python opencv图像叠加/图像融合/mask掩模
目录python 一.图像叠加 能够经过OpenCV函数cv.add()或简单地经过numpy操做添加两个图像,res = img1 + img2.两个图像应该具备相同的深度和类型,或者第二个图像能够 ...
- opencv 手选roi区域_如何用opencv实现感兴趣区域ROI的选取
OpenCV中感兴趣区域的选取与检测 感兴趣区域(Region of Interest, ROI)的选取,一般有两种情形:1)已知ROI在图像中的位置:2)ROI在图像中的位置未知. 1)第一种情形 ...
- opencv 手选roi区域_利用opencv进行眼动检测
- [Python从零到壹] 三十七.图像处理基础篇之图像融合处理和ROI区域绘制
欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...
- 【opencv】(1) 基础操作:图像视频读取、图像截取、颜色通道
主要内容有:图像及视频的读取和保存.图像显示.转换灰度图.图像截取.颜色通道提取和组合 那我们开始吧. 1. 图像操作 首先我们导入opencv库,彩色图像一般都是由RGB(红绿蓝)三颜色通道构成,灰 ...
最新文章
- 《Oracle高性能SQL引擎剖析:SQL优化与调优机制详解》一1.1 生成执行计划
- Oracle 表的访问方式(2)-----索引扫描
- ubuntu 使用FFTW快速计算离散傅里叶变换
- OAuth2.0文档
- Linux操作系统下软件的安装方法大全
- S3 Texture Compression
- 为何在wpf中textbox的值有时不会实时的变化
- Maven 多环境配置profile
- python 字典处理_python之高效处理字典、序列的一些语法
- matplotlib快速画图
- webservice框架 java_java开发webservice的几种方式详解
- JL 杰理 AC692N系列TWS 蓝牙音箱 开发
- BZOJ 1778: [Usaco2010 Hol]Dotp 驱逐猪猡 (高斯消元)
- DirectX11--教程项目无法编译、运行的解决方法
- 使用gluLookAt发生无法解析符号的错误
- 高频电路之LC并联谐振回路
- HTML之FrameSet,Frame和Iframe区别
- 终极解码2013春节版在windows7上使用
- Linux配置无密登录
- Laravel自定义artisan命令在Sell中运行
热门文章
- JAVA中分号用中文还是英文_【英文中有分号(;)吗?怎么用呢?】作业帮
- 设置部署服务器的运行端口,以太坊swarm配置bzz运行常见问题解决方案
- PAT 1055 集体照
- 一般描绘性形容词_描绘性形容词和限制性形容词
- c语言贪吃蛇答辩项目,贪吃蛇项目V1答辩.PDF
- 新电视显示服务器失败,电视网络连接失败原因是什么
- Python入门基础-七、案例4 52周存钱挑战 #列表(list)#math 库#for循环#range()用法#函数的参数传递#datetime库
- 周怎么换算成月_时间序列数据,只找到了周数据,怎么把它转化成月数据?
- 无线路由器dns服务器是什么意思,无线路由器dns是什么
- 华为服务器型号分类,解析华为服务器