学习@浅墨_毛星云【OpenCV入门教程之五】 分离颜色通道&多通道图像混合

本文参考@浅墨_毛星云【OpenCV入门教程之五】 分离颜色通道&多通道图像混合,

上篇文章中我们讲到了使用addWeighted函数进行图像混合操作,以及将ROI和addWeighted函数结合起来使用,对指定区域进行图像混合操作。

而为了更好的观察一些图像材料的特征,有时需要对RGB三个颜色通道的分量进行分别显示和调整。通过OpenCV的split和merge方法可以很方便的达到目的。

<1>split函数,将一个多通道数组分离成几个单通道数组。

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

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

它通过组合一些给定的单通道数组,将这些孤立的单通道数组合并成一个多通道的数组,从而创建出一个由多个单通道阵列组成的多通道阵列。它有两个基于C++的函数原型:
void merge(const Mat* mv, size_tcount, OutputArray dst)  
void merge(InputArrayOfArrays mv,OutputArray dst)
第一个参数,mv,填需要被合并的输入矩阵或vector容器的阵列,这个mv参数中所有的矩阵必须有着一样的尺寸和深度。
    第二个参数,count,当mv为一个空白的C数组时,代表输入矩阵的个数,这个参数显然必须大于1.
    第三个参数,dst,即输出矩阵,和mv[0]拥有一样的尺寸和深度,并且通道的数量是矩阵阵列中的通道的总数。

 
函数解析:

merge函数的功能是将一些数组合并成一个多通道的数组。关于组合的细节,输出矩阵中的每个元素都将是输出数组的串接,其中,第i个输入数组的元素被视为mv[i]。 c一般用其中的Mat::at()方法对某个通道进行存取,也就是这样用channels.at(0)。

PS: Mat::at()方法,返回一个引用到指定的数组元素。注意是引用,修改其中一个另一个跟着变。

根据OpenCV的BGR色彩空间(bule,Green,Red,蓝绿红),其中channels.at(0)就表示引用取出channels中的蓝色分量,channels.at(1)就表示引用取出channels中的绿色色分量,channels.at(2)就表示引用取出channels中的红色分量。

下面是多通道图像混合示例程序:

#include
#include
#include


using namespace cv;
using namespace std;


//首先是进行蓝色通道分离
void Test1_blue()
{
	Mat srcimg,imgROI,logoimg;
	vector channels;
	srcimg=imread("img/3.jpg");
	logoimg=imread("img/logo.png",0);
	//把一个三通道图像转换成三个单通道图像
	split(srcimg,channels);
	//将原图的蓝色通道.at(0)引用返回给imgROI,注意是引用,若修改其中一个另一个跟着变
	imgROI=channels.at(0);
	imgROI=imgROI(Rect(100,100,logoimg.cols,logoimg.rows));
	//将原图的蓝色通道.at(0)的(100,100)坐标处右下方的一块区域和logo图进行加权操作,将得到的混合结果存到imgROI
	addWeighted(imgROI,1.0,logoimg,0.5,0.0,imgROI);
	//将三个通道重新合并成一个通道
	merge(channels,srcimg);
	namedWindow("将原图的.at(0)通道混合到原图");
	imshow("将原图的.at(0)通道混合到原图",srcimg);
	
}
//其次是进行绿色通道分离

void Test1_green()
{
	Mat srcimg,imgROI,logoimg;
	vector channels;
	srcimg=imread("img/3.jpg");
	logoimg=imread("img/logo.png",0);
	//把一个三通道图像转换成三个单通道图像
	split(srcimg,channels);
	//将原图的绿色通道.at(1)引用返回给imgROI,注意是引用,若修改其中一个另一个跟着变
	imgROI=channels.at(1);
	imgROI=imgROI(Rect(100,100,logoimg.cols,logoimg.rows));
	//将原图的绿色通道.at(1)的(100,100)坐标处右下方的一块区域和logo图进行加权操作,将得到的混合结果存到imgROI
	addWeighted(imgROI,1.0,logoimg,0.5,0.0,imgROI);
	//将三个通道重新合并成一个通道
	merge(channels,srcimg);
	namedWindow("将原图的.at(1)通道混合到原图");
	imshow("将原图的.at(1)通道混合到原图",srcimg);
	
}

//再次是进行红色通道分离

void Test1_red()
{
	Mat srcimg,imgROI,logoimg;
	vector channels;
	srcimg=imread("img/3.jpg");
	logoimg=imread("img/logo.png",0);
	//把一个三通道图像转换成三个单通道图像
	split(srcimg,channels);
	//将原图的红色通道.at(2)引用返回给imgROI,注意是引用,若修改其中一个另一个跟着变
	imgROI=channels.at(2);
	imgROI=imgROI(Rect(100,100,logoimg.cols,logoimg.rows));
	//将原图的红色通道.at(2)的(100,100)坐标处右下方的一块区域和logo图进行加权操作,将得到的混合结果存到imgROI
	addWeighted(imgROI,1.0,logoimg,0.5,0.0,imgROI);
	//将三个通道重新合并成一个通道
	merge(channels,srcimg);
	namedWindow("将原图的.at(2)通道混合到原图");
	imshow("将原图的.at(2)通道混合到原图",srcimg);
	
}

int main()
{
	 Test1_blue();
	 Test1_green();
	 Test1_red();
	 waitKey();
	 return 0;
}

三个通道分别分离后的效果图如下:

学习@浅墨_毛星云【OpenCV入门教程之五】 分离颜色通道&多通道图像混合_第1张图片

你可能感兴趣的:(Opencv)