若要对Opencv中(BGR)颜色通道进行单一处理,那必然会涉及到通道分离(split)与合并(merge)。那么本篇博客笔者记录了两个方法的使用方法和案例。案例来源于《Opencv3编程入门学习》。
0. 环境
系统:Windows 10
平台:VS 2013
OpenCV版本:Opencv 3.0
1. split()通道分离函数
void split(const Mat& src, Mat* mvbegin);
void split(InputArray m, OutputArrayOfArrays mv);
第一个参数:即是原图像;
第二个参数:mvbegin,是一个Mat类型的一个数组,通常这个数组都是[3]的大小,这个数组大小表示的是通道个数,mvbegin就是指的将原图像按照(BGR)通道顺序逐一进行存储的单通道数组。通常可以用vector mvbegin的方式进行定义。
2. merge()通道合并函数
void merge(const Mat* mv, size_tcount, OutputArray dst);
void merge(InputArrayOfArrays mv, OutputArray dst);
第一个参数:mv,单通道图像数组,在split函数的第二个参数有解释;
第二个参数:size_tcoutn,当mv为一个空白的C数组时,代表输入矩阵的个数,参数要大于1;
第三个参数:dst,合并后的图像。
3. 使用案例
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
//#include <opencv2\opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
bool MultiChannelBlending()
{
Mat srcImage;
Mat logoImage;
vector<Mat> channels;
Mat imageBlueChannel, imageGreenChannel, imageRedChannel;
//channels.resize(3);
//=====================蓝色通道=====================
//描述:多通道混合-蓝色分量部分
//==================================================
srcImage = imread("dota_jugg.jpg");
logoImage = imread("dota_logo.jpg", 0);
if (!srcImage.data){ printf("读取srcImage图像错误!\n"); return false; }
if (!logoImage.data){ printf("读取logoImage图像错误!\n"); return false; }
split(srcImage, channels);//分离色彩通道
imageBlueChannel = channels.at(0);
addWeighted(imageBlueChannel(Rect(500, 250, logoImage.cols, logoImage.rows)),
1.0,
logoImage,
0.5,
0,
imageBlueChannel(Rect(500, 250, logoImage.cols, logoImage.rows)));
merge(channels, srcImage);//合并色彩通道
namedWindow("【多通道混合-蓝】");
imshow("【多通道混合-蓝】", srcImage);
//=====================绿色通道=====================
//描述:多通道混合-绿色分量部分
//==================================================
srcImage = imread("dota_jugg.jpg");
logoImage = imread("dota_logo.jpg", 0);
if (!srcImage.data){ printf("读取srcImage图像错误!\n"); return false; }
if (!logoImage.data){ printf("读取logoImage图像错误!\n"); return false; }
split(srcImage, channels);//分离色彩通道
imageGreenChannel = channels.at(1);
addWeighted(imageGreenChannel(Rect(500, 250, logoImage.cols, logoImage.rows)),
1.0,
logoImage,
0.5,
0,
imageGreenChannel(Rect(500, 250, logoImage.cols, logoImage.rows)));
merge(channels, srcImage);
namedWindow("【多通道混合-绿】");
imshow("【多通道混合-绿】", srcImage);
//=====================红色通道=====================
//描述:多通道混合-红色分量部分
//==================================================
srcImage = imread("dota_jugg.jpg");
logoImage = imread("dota_logo.jpg", 0);
if (!srcImage.data){ printf("读取srcImage图像错误!\n"); return false; }
if (!logoImage.data){ printf("读取logoImage图像错误!\n"); return false; }
split(srcImage, channels);//分离色彩通道
imageRedChannel = channels.at(2);
addWeighted(imageRedChannel(Rect(500, 250, logoImage.cols, logoImage.rows)),
1.0,
logoImage,
0.5,
0,
imageRedChannel(Rect(500, 250, logoImage.cols, logoImage.rows)));
merge(channels, srcImage);
namedWindow("【多通道混合-红】");
imshow("【多通道混合-红】", srcImage);
return true;
}
void main()
{
system("color 9F");//控制台背景色设置
if (MultiChannelBlending())
{
cout << endl << "\n运行成功,得出了需要的图像!";
}
waitKey(0);
}
4. 效果
5. 注意
在使用split函数过程中,如果是Debug版本运行极有可能碰到“0xC0000005内存访问冲突问题”,若遇到可参考笔者上篇blog进行解决。