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. 注册其它地区Apple ID

    不同地区Apple Id需求 iPhone 最近换上了iPhone,想要下载其它国家地区的游戏,需要登录该国的Apple Id才能在itunes里下载. 下面记录一下我注册日本地区的Apple Id过 ...

  2. Unity 物理引擎动力学关节

    Unity物理引擎中的各个动力学关节 Hinge Joint (铰链关节) Fixed Joint (固定关节) Spring Joint (弹簧关节) Character Joint(角色关节) C ...

  3. 转:程序员必须知道的几个Git代码托管平台

    http://www.open-open.com/lib/view/open1420704561390.html

  4. Pro Git(中文版)

    Pro Git(中文版) 返回 Git @ OSC 目录 1.起步 1.1 关于版本控制 1.2 Git 简史 1.3 Git 基础 1.4 安装 Git 1.5 初次运行 Git 前的配置 1.6 ...

  5. jq 获取table元素,ajax 静态填加数据

    知识点: 1.jq如何操作table->操作html内的元素 2. this 怎么使用 问题: 1.点击 修改 后,自动刷新了.判断取值,提示错误.正确出不来 2.ajax传值操作如何保密 ht ...

  6. 立即执行函数与window.onload作用类似

    (function(){ }()); // 立即执行函数 或者用window.onload=function(){}也可以  

  7. K2与OData和Swagger的集成

    最近K2陆续发布了一些好消息,从与Box的集成到今年取得的融资.这儿还有一个:K2近期宣布获得了DData和Swagger REST的支持,保障K2 Appit和Blackpearl的用户能建立基于工 ...

  8. Jenkins + NuGet + MSBuild

    Jenkins + NuGet + MSBuild 背景 项目上需要做UWP的自动安装包,在以前的公司接触的是TFS来做自动build. 公司要求用Jenkins来做,别笑话我,之前还真不晓得这个东西 ...

  9. Linux 网络编程八(epoll应用--大并发处理)

    //头文件 pub.h #ifndef _vsucess #define _vsucess #ifdef __cplusplus extern "C" { #endif //服务器 ...

  10. php基础29:打开目录

    <?php //1.打开一个目录 $dir = opendir("E:\AppServ\www\php"); //读取目录,使用一个循环来读出 while (!!$file= ...