本文参考@浅墨_毛星云【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,填我们需要进行分离的多通道数组。
void merge(const Mat* mv, size_tcount, OutputArray dst)
void merge(InputArrayOfArrays mv,OutputArray dst)
第一个参数,mv,填需要被合并的输入矩阵或vector容器的阵列,这个mv参数中所有的矩阵必须有着一样的尺寸和深度。
根据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;
}