而为了更好的观察一些图像材料的特征,有时需要对RGB三个颜色通道的分量进行分别显示和调整。通过OpenCV的split()和merge()方法可以很方便的达到目的,使用addWeighted函数进行图像混合操作,以及将ROI和addWeighted函数结合起来使用,对指定区域进行图像混合操作。
本文将介绍三个函数的应用:
将一个多通道数组分离成几个单通道数组。ps:这里的array按语境译为数组或者阵列。
这个split函数的C++版本有两个原型,他们分别是:
merge()函数的功能是split()函数的逆向操作,将多个数组组合合并成一个多通道的数组。
它通过组合一些给定的单通道数组,将这些孤立的单通道数组合并成一个多通道的数组,从而创建出一个由多个单通道阵列组成的多通道阵列。它有两个基于C++的函数原型:
这个函数的作用是,计算两个数组(图像阵列)的加权和。原型如下:
如果用数学公式来表达,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;
}