今天呢,我们一起来学习彩色图像的颜色通道分离与多通道图像混合,一般情况下,我们大多数看到的图像都是基于RGB颜色通道的图像,因此要实现颜色通道的分离,即要将R、G、B三个通道分离,而多通道图像混合,即将R、G、B三个通道的图像进行混合起来,重新组成一幅彩色图像。
实现的话,我们可以通过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容器。
split函数分割多通道数组转换成独立的单通道数组,按公式来看就是这样:
分离彩色图像的实例:
#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
Mat srcImage = imread("lena.png",
IMREAD_COLOR);
if (srcImage.empty())
{
printf("image error!\n");
return 0;
}
std::vector<Mat> channels;
Mat aChannels[3];
//利用数组分离
split(srcImage, aChannels);
//利用vector对象分离
split(srcImage, channels);
// 显示原图
namedWindow("src");
imshow("src", srcImage);
namedWindow("B");
namedWindow("G");
namedWindow("R");
imshow("B", aChannels[0]);
imshow("G", aChannels[1]);
imshow("R", aChannels[2]);
waitKey(0);
return 0;
}
原图
分离通道的三个图
2、merge()函数
功能:merge()函数的功能是split()函数的逆向操作,将多个数组组合合并成一个多通道的数组。
函数原型:
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]拥有一样的尺寸和深度,并且通道的数量是矩阵阵列中的通道的总数。
图像通道的分离与合并的实例:
#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
// 图像通道的分离与合并
///@srcImage const Mat 原始图像
///@logoImage const Mat 融合图像
///@outputImage Mat 输出图像
///@splitChannel int 图像的某个通道(0--2)
void SplitMerge(const Mat &srcImage,
const Mat &logoImage,
Mat &outputImage,
int splitChannel)
{
vector<Mat>channels;
//把一个3通道图像转换成3个单通道图像
//分离色彩通道
split(srcImage, channels);
// 得到其中一个通道的图像
Mat ChannelImage =
channels.at(splitChannel);
//将原图的蓝色通道的(50,50)坐标处
// 右下方的一块区域和logo图进行加权操作,
// 将得到的混合结果存到imageBlueChannel中
addWeighted(ChannelImage(
Rect(50, 50, logoImage.cols,
logoImage.rows)), 1.0,logoImage,
0.9, 0, ChannelImage(Rect(50, 50,
logoImage.cols, logoImage.rows)));
// 将三个单通道重新合并成一个三通道
merge(channels, outputImage);
}
int main()
{
//【0】定义相关变量
Mat srcImage;
Mat logoImage;
//读入图片
logoImage = imread("2.png", 0);
srcImage = imread("lena.png");
if (!logoImage.data)
{
printf("image error!\n");
return false;
}
if (!srcImage.data)
{
printf("image error!\n");
return false;
}
Mat outputImage1,
outputImage2,
outputImage3;
SplitMerge(srcImage, logoImage,
outputImage1, 0);
// 显示效果图
namedWindow("B");
imshow("B", outputImage1);
SplitMerge(srcImage, logoImage,
outputImage2, 1);
// 显示效果图
namedWindow("G");
imshow("G", outputImage2);
SplitMerge(srcImage, logoImage,
outputImage3, 2);
// 显示效果图
namedWindow("R");
imshow("R", outputImage3);
waitKey(0);
return 0;
}
运行结果:
图像通道的分离与合并