一、 split()通道分离函数

split()函数的C++版本有两个原型,他们分别是:


C++: void split(const Mat& src, Mat*mvbegin);//&为引用操作符
C++: void split(InputArray m,OutputArrayOfArrays mv);

两种定义用法相同,第一个参数填待分离的Mat型多通道矩阵(二维),第二个参数填分离后的Mat型单通道数组(三维)或一个vector<Mat>对象。应用实例如下:

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std; int main()
{
Mat image = imread("colorful.jpg");
if (image.data == 0)
{
cout << "读取错误" << endl;
}
imshow("原图", image); //使用Mat容器,用【】访问
//vector<Mat> channels;
//split(image, channels);
//imshow("B", channels[0]);
//imshow("G", channels[1]);
//imshow("R", channels[2]); //使用Mat容器,用at访问
vector<Mat> channels;
split(image, channels);
imshow("B", channels.at(0));
imshow("G", channels.at(1));
imshow("R", channels.at(2)); //使用Mat数组,只能用【】访问
//Mat aChannel[3];
//split(image, aChannel);
//imshow("B", aChannel[0]);
//imshow("G", aChannel[1]);
//imshow("R", aChannel[2]); waitKey();
return 0;
}

如果将分离后的信息填入vector<Mat> channels中,最后channels对象内会有3个元素,每个元素都是大小为image.rows X image.cols的二维Mat型矩阵,依次存放着原图像对应像素位置的B、G、R分量数据。每个元素(二维矩阵)可以通过【】索引或.at()访问。

如果将分离后的信息填入Mat aChannel[3]中,最后aChannel数组内会的3个元素也都是大小为image.rows X image.cols的二维Mat型矩阵,依次存放着原图像对应像素位置的B、G、R分量数据。每个元素(二维矩阵)只能通过【】索引,不能通过.at()访问。

同时需要注意,vector<Mat> channels和Mat aChannel[3]中的元素均为二维矩阵,因此channels对象和aChannel数组都是三维的矩阵。而输出操作符“<<”仅能输出二维矩阵,所以可以用"cout<<"输出channels对象或aChannel数组中的单个元素,而channels对象和aChannel数组本身不能被输出。

因为分离出来的3个元素都是大小为image.rows X image.cols的二维Mat型矩阵,所以用imshow()显示每个元素时,最后显示出来的都是单通道的灰度图。

上述程序运行结果如下:

二、merge()通道合并函数

merge()函数的C++版本有两个原型,他们分别是:

C++: void merge(const Mat* mv, size_tcount, OutputArray dst)
C++: void merge(InputArrayOfArrays mv,OutputArray dst)

若待合并通道放在Mat aChannel[ ]这样的数组里面,则使用第一种定义方法下的merge()函数。第一个参数填要传入数组的地址,可直接填入数组名aChannel;第二个参数填要合并矩阵的个数,通常情况下图像大都是单通道的灰度图或三通道的真彩图,因此要想合并后的输出dst能直接用imshow()显示的话,最好填1或3,填2也能进行数据的合并,但输出时会报错;最后一个参数填通道合并后的矩阵。

以下示例中,先用split()将图像三通道分离,将R红色分量全部置0后再将三通道用merge()融合。通道分离后,单通道矩阵存放于数组中,代码如下:

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std; int main()
{
Mat image = imread("colorful.jpg");
if (image.data == 0)
{
cout << "读取错误" << endl;
}
imshow("原图", image); //通道分离
Mat aChannel[3];
split(image, aChannel);
Mat BlueChannel = aChannel[0];
Mat GreenChannel = aChannel[1];
Mat RedChannel = aChannel[2]; //将R通道全部置0
Mat newAddChannel = aChannel[2].clone();
newAddChannel.setTo(0);
Mat newChannels[3] = { BlueChannel , GreenChannel , newAddChannel }; //通道合并
Mat mergedImage;
merge(newChannels, 3, mergedImage); imshow("Merged", mergedImage);
waitKey();
return 0;
}

若待合并通道放在vector<Mat> channels这样的Mat型容器对象中,则使用第二种定义方法下的merge()函数。第一个参数填对象名channels,第二个参数填通道合并后的矩阵。相较第一种定义方法来说,本定义方法无需说明需合并矩阵的个数,默认合并容器对象内所有元素。因此可以通过更改容器对象内元素的个数来改变合并矩阵的个数。

以下示例中,先用split()将图像三通道分离,将B绿色分量全部置0后再将三通道用merge()融合。通道分离后,单通道矩阵存放于容器对象中,代码如下:

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std; int main()
{
Mat image = imread("colorful.jpg");
if (image.data == 0)
{
cout << "读取错误" << endl;
}
imshow("原图", image); //通道分离
vector<Mat> channels;
split(image, channels);
Mat BlueChannel = channels.at(0);
Mat GreenChannel = channels.at(1);
Mat RedChannel = channels.at(2); //将B通道全部置0
Mat newAddChannel = channels.at(0).clone();
newAddChannel.setTo(0);
vector<Mat> newChannels;
newChannels.push_back(newAddChannel);
newChannels.push_back(GreenChannel);
newChannels.push_back(RedChannel); //通道合并
Mat mergedImage;
merge(newChannels, mergedImage); imshow("Merged", mergedImage);
waitKey();
return 0;
}

注:无论将单通道矩阵放在数组中还是容器对象中,都要按照B、G、R的顺序存放。

错误之处,敬请雅正!

C++ Opencv split()通道分离函数 merge()通道合并函数 使用操作详解的更多相关文章

  1. c++排序二叉树的出现的私有函数讨论,以及二叉树的删除操作详解

    c++排序二叉树的出现的私有函数讨论, 以及二叉树的删除操作详解 标签(空格分隔): c++ 前言 我在c++学习的过程中, 最近打了一个排序二叉树的题目,题目中出现了私有函数成员,当时没有理解清楚这 ...

  2. C++学习45 流成员函数put输出单个字符 cin输入流详解 get()函数读入一个字符

    在程序中一般用cout和插入运算符“<<”实现输出,cout流在内存中有相应的缓冲区.有时用户还有特殊的输出要求,例如只输出一个字符.ostream类除了提供上面介绍过的用于格式控制的成员 ...

  3. Python趣味入门9:函数是你走过的套路,详解函数、调用、参数及返回值

    1.概念 琼恩·雪诺当上守夜人的司令后,为训练士兵对付僵尸兵团,把成功斩杀僵尸的一系列动作编排成了"葵花宝典剑法",这就是函数.相似,在计算机世界,一系列前后连续的计算机语句组合在 ...

  4. Opencv YAML和XML格式文件操作详解

    本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/47660943 本文参考Opencv 2 ...

  5. javascript函数setInterval和setTimeout的使用区别详解

    setTimeout和setInterval的使用 这两个方法都可以用来实现在一个固定时间段之后去执行JavaScript.不过两者各有各的应用场景. 方 法 实际上,setTimeout和setIn ...

  6. JQuery的ready函数与JS的onload的区别详解

    JQuery的ready函数与JS的onload的区别:1.执行时间window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行.$(document).ready()是DOM结构绘制 ...

  7. Python open()函数文件打开、读、写操作详解

    一.Python open()函数文件打开操作 打开文件会用到open函数,标准的python打开文件语法如下:open(name[,mode[,buffering]])open函数的文件名是必须的, ...

  8. JQuery(一)---- JQ的选择器,属性,节点,样式,函数等操作详解

    JQuery的基本概念 JQuery是一个javascript库,JQuery凭借着简洁的语法和跨平台的兼容性,极大的简化了js操作DOM.处理事件.执行动画等操作.JQuery强调的理念是:'wri ...

  9. js函数在frame中的相互调用详解

    原文章:http://www.jb51.net/article/47557.htm   一个HTML页面可以有一个或多个子框架,这些子框架以<iframe>来标记,用来显示一个独立的HTM ...

随机推荐

  1. jmeter javamail 邮件格式再优化(由详情——>改为统计)

    前言:之前扩展的ant—jmeter支持邮件附件形式上传以及邮件内容的html文件格式. 如图: 由于邮件的内容格式是详情信息,也就是说直观的显示的是case,但由于case的增加,邮件内容越来越大! ...

  2. 输入ip和端口号python脚本py文件

    1.利用.py文件进行打开URL,编辑以下文件代码保存文件为login.py: # _*_ coding: cp936 _*__all_ = ['ip','port','root_id']ip='10 ...

  3. HTTP协议之url详解

    HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接.URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息 URL,全称是U ...

  4. Python建立时间事件引擎原理剖析

    作为python小白,学习量化交易的曲线是非常陡峭的,唯一好的办法就是一点点啃代码.以下代码案例来自vnpy的引擎代码. # encoding: UTF-8 #定义时间事件 EVENT_TIMER = ...

  5. PHP常用180函数总结【初学者必看】

    数学函数 1.abs(): 求绝对值 <span style="font-size: 14px;">$abs = abs(-4.2); //4.2<br>& ...

  6. Springboot & Mybatis 构建restful 服务五

    Springboot & Mybatis 构建restful 服务五 1 前置条件 成功执行完Springboot & Mybatis 构建restful 服务四 2 restful ...

  7. 洛谷P1386座位安排

    座位安排 今天,在机房里做了这道题目,我来整理一下思路. 首先读懂题意,这n个人是不需要按1到n来一次安排的,也就是说你可以先安排任意一个人. 那么有一种很好排除的情况,那就是对于大于等于i的作为的需 ...

  8. Python基础------列表,元组的调用方法

    Python基础------列表,元组的调用方法@@@ 一. 列表 Python中的列表和歌曲列表类似,也是由一系列的按特定顺序排列的元素组成的,在内容上,可以将整数,实数,字符串,列表,元组等任何类 ...

  9. KIDS采购销售管理系统

    {KIDS采购销售管理系统} 软件项目总结报告 编号:-{kpss}-CLOSUREREPORT 版本:1.0 变更记录 1 项目信息 2 项目说明 [本项目主要用于母婴店人事管理,采购管理,商品管理 ...

  10. Shiro学习

    Shiro学习资源 Shiro官网,http://shiro.apache.org/index.html 学习网站链接,http://blog.java1234.com/blog/articles/4 ...