基于openCV3的颜色通道分离及多通道图像混合

注:文档摘至《OpenCV3编程入门》毛星云版
<1>通道分离: split()函数
split函数用于将一个多通道数组分离成几个单通道数组。这里的array 按语境翻译为数组或者阵列。split函数的C++版本有两个原型, 分别是:
• c ++: void split( const Mat& src, Mat*mvbegin);
• C++ : void split(InputArray m ,Outpu从nayOfArrays mv);
变量介绍如下:
· 第一个参数, InputArray 类型的m 或者const Mat&类型的src ,填我们需要进行分离的多通道数组。
· 第二个参数, OutputArrayOfArrays 类型的mv , 填函数的输出数组或者输出
的vector 容器。
split 函数分割多通道数组转换成独立的单通道数组,公式如下:
mv[c] (I)= src(I )c

<2>通道合并: merge()函数
merge() 函数是split() 函数的逆向操作将多个数组合并成一个多通道的数组。它通过组合一些给定的单通道数组,将这些孤立的单通道数组合并成一个多通道的数组,从而创建出一个由多个单通道阵列组成的多通道阵列。它有两个基于C十+的函数原型如下。
• C++: void merge(const Mat* mv, size_tcount, Ou阳山rray dst)
• C++: void merge( In putArrayO队rrays mv,OutputArray dst)
变量介绍如下。
· 第一个参数, mv 。填需要被合井的输入矩阵或vector 容器的阵列,这个mv 参数中所有的矩阵必须有着一样的尺寸和深度。
· 第二个参数, count。 当mv 为一个空白的C 数组时,代表输入矩阵的个数,这个参数显然必须大于1。
· 第三个参数, dst。即输出矩阵,和mv[0]拥有一样的尺寸和深度,井且通道的数量是矩阵阵列中的通道的总数。
函数解析如下。
merge 函数的功能是将一些数组合并成一个多通道的数组。关于组合的细节,输出矩阵中的每个元素都将是输出数组的串接。其中, 第i 个输入数组的元素被视为mv[i] 。 C 一般用其中的Mat: :at()方法对某个通道进行存取,也就是这样用:channels.at(0) 。
这里的Mat: :at()方法返回一个引用到指定的数组元素。注意是引用,相当于两者等价,也就是修改其中一个,另一个也会随之改变。
<实例>
头文件包含及命名空间

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;

实现多通道的图像混合

bool  MultiChannelBlending()
{
	//【0】定义相关变量
	Mat srcImage;
	Mat logoImage;
	vector<Mat> channels;
	Mat  imageBlueChannel;

	//=================【蓝色通道部分】=================
	//	描述:多通道混合-蓝色分量部分
	//============================================

	// 【1】读入图片
	logoImage= imread("dota_logo.jpg",0);
	srcImage= imread("dota_jugg.jpg");

	if( !logoImage.data ) { printf("Oh,no,读取logoImage错误~! \n"); return false; }
	if( !srcImage.data ) { printf("Oh,no,读取srcImage错误~! \n"); return false; }

	//【2】把一个3通道图像转换成3个单通道图像
	split(srcImage,channels);//分离色彩通道

	//【3】将原图的蓝色通道引用返回给imageBlueChannel,注意是引用,相当于两者等价,修改其中一个另一个跟着变
	imageBlueChannel= channels.at(0);
	//【4】将原图的蓝色通道的(500,250)坐标处右下方的一块区域和logo图进行加权操作,将得到的混合结果存到imageBlueChannel中
	addWeighted(imageBlueChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,logoImage,0.5,0,imageBlueChannel(Rect(500,250,logoImage.cols,logoImage.rows)));

	//【5】将三个单通道重新合并成一个三通道
	merge(channels,srcImage);

	//【6】显示效果图
	namedWindow(" <1>游戏原画+logo蓝色通道");
	imshow(" <1>游戏原画+logo蓝色通道",srcImage);


	//=================【绿色通道部分】=================
	//	描述:多通道混合-绿色分量部分
	//============================================

	//【0】定义相关变量
	Mat  imageGreenChannel;

	//【1】重新读入图片
	logoImage= imread("dota_logo.jpg",0);
	srcImage= imread("dota_jugg.jpg");

	if( !logoImage.data ) { printf("读取logoImage错误~! \n"); return false; }
	if( !srcImage.data ) { printf("读取srcImage错误~! \n"); return false; }

	//【2】将一个三通道图像转换成三个单通道图像
	split(srcImage,channels);//分离色彩通道

	//【3】将原图的绿色通道的引用返回给imageBlueChannel,注意是引用,相当于两者等价,修改其中一个另一个跟着变
	imageGreenChannel= channels.at(1);
	//【4】将原图的绿色通道的(500,250)坐标处右下方的一块区域和logo图进行加权操作,将得到的混合结果存到imageGreenChannel中
	addWeighted(imageGreenChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,logoImage,0.5,0.,imageGreenChannel(Rect(500,250,logoImage.cols,logoImage.rows)));

	//【5】将三个独立的单通道重新合并成一个三通道
	merge(channels,srcImage);

	//【6】显示效果图
	namedWindow("<2>游戏原画+logo绿色通道");
	imshow("<2>游戏原画+logo绿色通道",srcImage);



	//=================【红色通道部分】=================
	//	描述:多通道混合-红色分量部分
	//============================================

	//【0】定义相关变量
	Mat  imageRedChannel;

	//【1】重新读入图片
	logoImage= imread("dota_logo.jpg",0);
	srcImage= imread("dota_jugg.jpg");

	if( !logoImage.data ) { printf("Oh,no,读取logoImage错误~! \n"); return false; }
	if( !srcImage.data ) { printf("Oh,no,读取srcImage错误~! \n"); return false; }

	//【2】将一个三通道图像转换成三个单通道图像
	split(srcImage,channels);//分离色彩通道

	//【3】将原图的红色通道引用返回给imageBlueChannel,注意是引用,相当于两者等价,修改其中一个另一个跟着变
	imageRedChannel= channels.at(2);
	//【4】将原图的红色通道的(500,250)坐标处右下方的一块区域和logo图进行加权操作,将得到的混合结果存到imageRedChannel中
	addWeighted(imageRedChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,logoImage,0.5,0.,imageRedChannel(Rect(500,250,logoImage.cols,logoImage.rows)));

	//【5】将三个独立的单通道重新合并成一个三通道
	merge(channels,srcImage);

	//【6】显示效果图
	namedWindow("<3>游戏原画+logo红色通道 ");
	imshow("<3>游戏原画+logo红色通道 ",srcImage);

	return true;
}

测试一下

int main(   )
{
	system("color 9F");
	if(MultiChannelBlending( ))
	{
		cout<<endl<<"\n运行成功,得出了需要的图像~! ";
	}
	waitKey(0);
	return 0;
}

效果图如下:

这里写图片描述

这里写图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值