【OpenCV笔记 08】OpenCV中分离颜色通道split()和图像通道混合merge()

而为了更好的观察一些图像材料的特征,有时需要对RGB三个颜色通道的分量进行分别显示和调整。通过OpenCV的split()和merge()方法可以很方便的达到目的,使用addWeighted函数进行图像混合操作,以及将ROI和addWeighted函数结合起来使用,对指定区域进行图像混合操作。

本文将介绍三个函数的应用:

split函数详解

将一个多通道数组分离成几个单通道数组。ps:这里的array按语境译为数组或者阵列。

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

[cpp]  view plain  copy
 print ?
  1. C++: void split(const Mat& src, Mat*mvbegin);  
  2. C++: void split(InputArray m,OutputArrayOfArrays mv);  

  • 第一个参数,InputArray类型的m或者const Mat&类型的src,填我们需要进行分离的多通道数组。
  • 第二个参数,OutputArrayOfArrays类型的mv,填函数的输出数组或者输出的vector容器。

merge函数详解

merge()函数的功能是split()函数的逆向操作,将多个数组组合合并成一个多通道的数组。

它通过组合一些给定的单通道数组,将这些孤立的单通道数组合并成一个多通道的数组,从而创建出一个由多个单通道阵列组成的多通道阵列。它有两个基于C++的函数原型:

[cpp]  view plain  copy
 print ?
  1. C++: void merge(const Mat* mv, size_tcount, OutputArray dst)  
  2. C++: void merge(InputArrayOfArrays mv,OutputArray dst)  
  • 第一个参数,mv,填需要被合并的输入矩阵或vector容器的阵列,这个mv参数中所有的矩阵必须有着一样的尺寸和深度。
  • 第二个参数,count,当mv为一个空白的C数组时,代表输入矩阵的个数,这个参数显然必须大于1.
  • 第三个参数,dst,即输出矩阵,和mv[0]拥有一样的尺寸和深度,并且通道的数量是矩阵阵列中的通道的总数。

addWeighted函数

这个函数的作用是,计算两个数组(图像阵列)的加权和。原型如下:

[cpp]  view plain  copy
 print ?
  1. void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype=-1);  

  • 第一个参数,InputArray类型的src1,表示需要加权的第一个数组,常常填一个Mat。
  • 第二个参数,alpha,表示第一个数组的权重
  • 第三个参数,src2,表示第二个数组,它需要和第一个数组拥有相同的尺寸和通道数。
  • 第四个参数,beta,表示第二个数组的权重值。
  • 第五个参数,dst,输出的数组,它和输入的两个数组拥有相同的尺寸和通道数。
  • 第六个参数,gamma,一个加到权重总和上的标量值。看下面的式子自然会理解。
  • 第七个参数,dtype,输出阵列的可选深度,有默认值-1。;当两个输入数组具有相同的深度时,这个参数设置为-1(默认值),即等同于src1.depth()。

如果用数学公式来表达,addWeighted函数计算如下两个数组(src1和src2)的加权和,得到结果输出给第四个参数。即addWeighted函数的作用可以被表示为为如下的矩阵表达式为:

                                                      dst = src1[I]*alpha+ src2[I]*beta + gamma;

其中的I,是多维数组元素的索引值。而且,在遇到多通道数组的时候,每个通道都需要独立地进行处理。另外需要注意的是,当输出数组的深度为CV_32S时,这个函数就不适用了,这时候就会内存溢出或者算出的结果压根不对。


****************************************应用实例*********************************

代码如下:

//多通道图形混合, RGB颜色通道分离
#include
#include
#include
using namespace std;
using namespace cv;
//全局函数声明部分
bool MultiChannelBlending();
void ShowHelpText();
//main()函数部分
int main()
{
	system("color 9F");
	if (MultiChannelBlending())
	{
		cout << endl << "图像混合成功,如图:" << endl;
	}
	while (char(waitKey(1)) != 'q')	{ } //按下q键退出
	return 0;
}
//自定义函数部分
bool MultiChannelBlending()
{

	Mat logoWH = imread("whlogo.jpg",0);//读载入logo的灰度图
	Mat logoHZ = imread("hzlogo.jpg", 0);//读载入logoHZ的灰度图
	Mat srcImage = imread("scenery.jpg");
	vectorchannels;//vector位于std中
	Mat	imageBlueChannel;
	Mat imageGreenChannel;
	Mat imageRedChannel;
	if (!logoWH.data)
		cout << "读取logoWH错误\n";
	else if (!srcImage.data)
		cout << "读取srcImage错误\n";
	else
		cout << "图片读取成功." << endl;

	split(srcImage, channels);//将原图风景图“scenery”的颜色通道分离
	imageBlueChannel = channels.at(0);
	imageGreenChannel = channels.at(1);
	imageRedChannel = channels.at(2);//提取红色通道,并返回引用值
	/*
	imshow("[1]BlueChannel", imageBlueChannel);
	imshow("[2]GreenChannel", imageGreenChannel);
	imshow("[3]Redchannel", imageRedChannel);
	*/

	//将风景图“scenery”的红色通道和logoWH混合
	addWeighted(
		imageRedChannel(Rect(0, 0, logoWH.cols, logoWH.rows)),
		1.0,
		logoWH, 
		0.3,
		0,
		imageRedChannel(Rect(0, 0, logoWH.cols, logoWH.rows)));
	imshow("RedChannel+logoWH", imageRedChannel); 

	//将风景图“scenery”的绿色通道和logoHZ混合
	addWeighted(
		imageGreenChannel(Rect(1217,610,logoHZ.cols,logoHZ.rows)),
		1.0,
		logoHZ,
		0.3,
		0,
		imageGreenChannel(Rect(1217, 610, logoHZ.cols, logoHZ.rows)));
	imshow("GreendChannel+logoHZ", imageGreenChannel);
	
	//将分离的三个通道合并成一个三通道
	Mat	mergedImage(srcImage.rows,srcImage.cols,CV_8UC3,Scalar(0));//重新设置一个画布 , 用来显示通道分离再次混合后的图像
	merge(channels, mergedImage);//通道混合
	imshow("Channels Merged ", mergedImage);//输出

	/*本段代码是从scenery中选取logo大小的ROI区域,并在窗口显示,再次可自行去掉注释,查看显示效果
	Mat	ROI_HZ = srcImage(Rect(1217, 610, logoHZ.cols, logoHZ.rows));//选定ROI区域,类似于截取在”scenery“中截取logo大小一块
	Mat	ROI_WH = srcImage(Range(217, 217 + logoWH.rows),Range(900, 900 + logoWH.cols) );//选定ROI区域
	imshow("ROIHZ", ROI_HZ);
	imshow("ROIWH", ROI_WH);
	*/
	return true;
}

运行结果:

【OpenCV笔记 08】OpenCV中分离颜色通道split()和图像通道混合merge()_第1张图片【OpenCV笔记 08】OpenCV中分离颜色通道split()和图像通道混合merge()_第2张图片【OpenCV笔记 08】OpenCV中分离颜色通道split()和图像通道混合merge()_第3张图片

你可能感兴趣的:(C++,OpenCV,OpenCV,3.0,学习笔记)