time:2015年 10月 03日 星期六 12:03:45 CST

opencv笔记2:图像ROI


ROI

ROI意思是Region Of Interests,感兴趣区域,是一个图中的一个子区域。

OpenCV中定义的ROI是矩形的。

ROI的用处包括而不限于:提取出ROI区域做进一步处理(比如人脸识别、车牌识别);将另一张图片贴放到ROI区域。

这里以第二种用处为例,将一个logo图像添加到一张大图上指定的ROI区域。

图像贴放

粗略想想,包括这四个步骤

  • 定义大图和小图
  • 在大图上定义ROI区域
  • 小图贴放到ROI区域
  • 显示新的大图

这里在fedora22下使用dnf(yum)安装了opencv3.0,如下代码可以运行良好

#include <iostream>
#include <opencv2/opencv.hpp> using namespace std;
using namespace cv; int main() {
//【1】定义大图和小图
//【2】在大图上定义ROI区域
//【3】小图贴放到ROI区域
//【4】显示新的大图 //【1】定义大图和小图
Mat srcImage = imread("/home/chris/workspace/clion/dota_pa.jpg");
Mat logoImage = imread("/home/chris/workspace/clion/dota_ss.png");
if(!srcImage.data){
cerr << "读取srcImage错误!" << endl;
exit;
}
if(!logoImage.data){
cerr << "读取logoImage错误!" << endl;
exit;
} //【2】在大图上定义ROI区域
Mat imageROI = srcImage(Rect(20, 25, logoImage.cols, logoImage.rows)); //【3】小图贴放到ROI区域
logoImage.copyTo(imageROI); //【4】显示新的大图
imshow("利用ROI实现图像叠加示例窗口", srcImage);
waitKey(0);
destroyAllWindows();
return 0;
}

这里copyTo()函数中只用到一个参数,浅墨的教程上有第二个参数:图像掩模(mask),我尝试了下,发现不用mask也没关系,mask的定义也不一定要是灰度图(即imread第二个参数设定为0)。对此,我表示不理解,反正能用就好了。

图像线性混合

直接把logo图替换掉ROI区域的做法通常不是很好,如果能把两者各按一定比例进行混合就显得更好些,这需要用到图像混合技术。

图像线性混合,其实就是不同图片(这里以两张图为例),各自按照一定比例系数进行相加,没什么神奇的地方:

result = alpha*src1 + beta*src2 + gamma

使用函数addWeighted(src1, alpha, src2, beta, gamma, dstImage, dtype=-1)

这里dtype参数,是输出阵列的可选深度,有默认值-1。;当两个输入数组具有相同的深度时,这个参数设置为-1(默认值),即等同于src1.depth()。

OK,粗略想下线性混合的步骤:

  • 定义两幅图像
  • 定义权重和偏置量等参数
  • 按参数做图像混合
  • 显示结果

上代码:

#include <iostream>
#include <opencv2/opencv.hpp> using namespace std;
using namespace cv; int main() {
//【1】定义两幅图像
//【2】定义权重和偏置量等参数
//【3】按参数做图像混合
//【4】显示结果 //【1】定义两幅图像
Mat srcImage1 = imread("/home/chris/workspace/clion/mogu.jpg");
Mat srcImage2 = imread("/home/chris/workspace/clion/rain.jpg"); //【2】定义权重和偏置量等参数
double alpha = 0.5; //第一幅图的权重
double beta = 1- alpha; //第二幅图的权重
double gamma = 0.0; //偏置量 //【3】按参数做图像混合
Mat dstImage; //目标图像,存放结果
addWeighted(srcImage1, alpha, srcImage2, beta, gamma, dstImage); //【4】显示结果
imshow("线性混合结果", dstImage);
waitKey(0);
destroyAllWindows(); return 0; }

好吧,其实这东西很简单。应用到ROI区域,对应的代码为:

#include <iostream>
#include <opencv2/opencv.hpp> using namespace std;
using namespace cv; int main() {
//【1】定义两幅图像
//【2】定义ROI区域
//【3】定义权重和偏置量等参数
//【4】按参数做图像混合
//【5】显示结果 //【1】定义两幅图像
Mat srcImage1 = imread("/home/chris/workspace/clion/dota_pa.jpg");
Mat srcImage2 = imread("/home/chris/workspace/clion/dota_ss.png"); //【2】定义ROI区域
Mat imageROI = srcImage1(Rect(20, 25, srcImage2.cols, srcImage2.rows)); //【3】定义权重和偏置量等参数
double alpha = 0.5; //第一幅图的权重
double beta = 1- alpha; //第二幅图的权重
double gamma = 0.0; //偏置量 //【4】按参数做图像混合
addWeighted(imageROI, alpha, srcImage2, beta, gamma, imageROI); //【5】显示结果
imshow("线性混合结果", srcImage1);
waitKey(0);
destroyAllWindows(); return 0; }

多通道的分离和混合

既然前面把图像混合讲到了,那么按照通道进行混合也就可以做了!比如要把看起来是白色的logo图,和指定背景图上ROI区域混合,并且希望logo图显示为红色。这就需要ROI图本身为红色通道,logo图读取为灰度图像(保证都是单通道),然后混合,这之后由于ROI区域就是原图中的一个通道上的一个区域,原图像的红色通道变化了,现在把三个通道重新合并回去,就能够得到想要的效果图了。

粗略想下,步骤为:

  • 定义义两幅图像
  • 分离通道
  • 在通道图上定义ROI区域
  • 定义权重和偏置量等参数
  • 按参数做图像混合
  • 合并通道
  • 显示结果

对应的代码为:

#include <iostream>
#include <opencv2/opencv.hpp> using namespace std;
using namespace cv; int main() {
//义两幅图像
//【2】分离通道
//【3】在通道图上定义ROI区域
//【4】定义权重和偏置量等参数
//【5】按参数做图像混合
//【6】合并通道
//【7】显示结果 //【1】定义两幅图像
Mat srcImage = imread("/home/chris/workspace/clion/dota_pa.jpg");
Mat logoImage = imread("/home/chris/workspace/clion/dota_logo.jpg", 0); //【2】分离通道
vector<Mat> channels;
split(srcImage, channels); //【3】在通道图上定义ROI区域
Mat redChannelImage = channels.at(2);
Mat imageROI = redChannelImage(Rect(50, 25, logoImage.cols, logoImage.rows)); //【4】定义权重和偏置量等参数
double alpha = 1.0;
double beta = 0.5;
double gamma = 0.0; //【5】按参数做图像混合
addWeighted(imageROI, alpha, logoImage, beta, gamma, imageROI); //【6】合并通道
merge(channels, srcImage); //【7】显示结果
imshow("0通道", srcImage);
waitKey(0);
destroyAllWindows(); return 0; }

opencv笔记2:图像ROI的更多相关文章

  1. Python下opencv使用笔记(图像频域滤波与傅里叶变换)

    Python下opencv使用笔记(图像频域滤波与傅里叶变换) 转载一只程序喵 最后发布于2018-04-06 19:07:26 阅读数 1654  收藏 展开 本文转载自  https://blog ...

  2. OpenCV学习笔记(3)——图像的基本操作

    获取图像的像素值并修改 获取图像的属性(信息) 图像的ROI() 图像通道的拆分及合并 1.获取并修改像素值 先读入图像装入一个图像实体,然后该实体相当于一个多维list,可以直接用数组操作提取像素信 ...

  3. opencv笔记6:角点检测

    time:2015年10月09日 星期五 23时11分58秒 # opencv笔记6:角点检测 update:从角点检测,学习图像的特征,这是后续图像跟踪.图像匹配的基础. 角点检测是什么鬼?前面一篇 ...

  4. OpenCV笔记大集锦(转载)

    整理了我所了解的有关OpenCV的学习笔记.原理分析.使用例程等相关的博文.排序不分先后,随机整理的.如果有好的资源,也欢迎介绍和分享. 1:OpenCV学习笔记 作者:CSDN数量:55篇博文网址: ...

  5. opencv笔记5:频域和空域的一点理解

    time:2015年10月06日 星期二 12时14分51秒 # opencv笔记5:频域和空域的一点理解 空间域和频率域 傅立叶变换是f(t)乘以正弦项的展开,正弦项的频率由u(其实是miu)的值决 ...

  6. opencv笔记4:模板运算和常见滤波操作

    time:2015年10月04日 星期日 00时00分27秒 # opencv笔记4:模板运算和常见滤波操作 这一篇主要是学习模板运算,了解各种模板运算的运算过程和分类,理论方面主要参考<图像工 ...

  7. opencv笔记3:trackbar简单使用

    time:2015年 10月 03日 星期六 13:54:17 CST # opencv笔记3:trackbar简单使用 当需要测试某变量的一系列取值取值会产生什么结果时,适合用trackbar.看起 ...

  8. opencv笔记1:opencv的基本模块,以及环境搭建

    opencv笔记1:opencv的基本模块,以及环境搭建 安装系统 使用fedora22-workstation-x86_64 安装opencv sudo dnf install opencv-dev ...

  9. opencv-学习笔记(6)图像梯度Sobel以及canny边缘检测

    opencv-学习笔记(6)图像梯度Sobel以及canny边缘检测 这章讲了 sobel算子 scharr算子 Laplacion拉普拉斯算子 图像深度问题 Canny检测 图像梯度 sobel算子 ...

随机推荐

  1. linux下删除文件名乱码文件

    linux下通过rm命令来删除文件,但是如果要删除文件名乱码的文件,就不能直接使用rm命令了,因为压根就无法输出文件名来.不过借助find命令可以实现对其删除.在linux下对于每个文件都一个对应的不 ...

  2. UIImageJPEGRepresentation和UIImagePNGRepresentation

    UIImageJPEGRepresentation方法在耗时上比较少 而UIImagePNGRepresentation耗时操作时间比较长 -(void)imagePickerController:( ...

  3. H5 canvas绘制出现模糊的问题

    在之前做移动端小游戏幸运转盘.九宫格转盘,使用到了 canvas ,也是第一次在项目中使用 canvas 来实现. 近期测试人员反应 canvas 绘制的内容太模糊,心想着用 canvas 绘制出来的 ...

  4. WEB 安全之 SQL注入<一> 盲注

    SQL注入是一个比较"古老"的话题,虽然现在存在这种漏洞的站点比较少了,我们还是有必要了解一下它的危害,及其常用的手段,知己知彼方能百战不殆.进攻与防守相当于矛和盾的关系,我们如果 ...

  5. 【Andorid------手势识别】GestureDetector和SimpleOnGestureListener的使用教程(转)——

    FROM:http://www.cnblogs.com/transmuse/archive/2010/12/02/1894833.html 1. 当用户触摸屏幕的时候,会产生许多手势,例如down,u ...

  6. C++ STL之vector详解

    转自http://blog.sina.com.cn/s/blog_9f1c0931010180cy.html Vectors   vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作 ...

  7. C语言 百炼成钢17

    //题目49:老师将糖果分成若干份,让学生按任意次序领取,第一个领取的,得到1份加上剩余糖果的1/10, //第二个领取的,得到2份加上剩余糖果的1/10,第三个领取的,得到3份加上剩余糖果的1/10 ...

  8. Sublime 将 Tab 转为空格

    最近在使用 vue-cli 搭建项目,但每次用 Hbuilder 编写 vue 文件的时候,如果存在<script>部分就会报错,错误信息大意是说空格有问题.仔细研究了之后才知道,这是因为 ...

  9. C# WinForm PropertyGrid用法

    关于C# PropertyGrid的用法没有找到,找到一个C++的用法.模仿着使用了一下,感觉挺不错,分享一下.基本用法:拖个PropertyGrid,绑定一个属性类就行了. 大气象 Code hig ...

  10. 突然想起android与mfc差异

    两者都可以算作是客户端程序,都是做上位机用的.而且都是被动执行. 相同点: 1.MFC中,它是由 project的名字 里面的某个成员函数来初始化,窗体,以及窗体里面的变量. 后面都是监听消息循环.数 ...