分离颜色通道、多通道图像混合
通道分离:split()函数
split()函数用于将一个多通道数组分离成几个单通道数组。
C++原型:
- C++:void split(const Mat& src,Mat*mvbegin);
- C++:void split(InputArray m,OutputArrayOfArrays mv);
变量介绍如下:
- 第一个参数,InputArray类型的m或者const Mat&类型的src,填我们需要进行分离的多通道数组
- 第二个参数,OutputArrayOfArrays类型的mv,填函数的输出数组或者输出的vector容器
split函数分割多通道数组转换成独立的单通道数组,公式如下:
mvc = src(I)c
示例:
vector<Mat> channels;
Mat imageBlueChannel;
Mat imageGreenChannel;
Mat imageRedChannel;
srcImage4 = imread("dota.jpg");
//把一个3通道图像转换成3个单通道图像
split(srcImage4,channels);//分离色彩通道
imageBlueChannel = channels.at(0);
imageGreenChannel = channels.at(1);
imageRedChannel = channels.at(2);
根据OpenCV的BGR色彩空间(Blue、Green、Red,蓝、绿、红),其中channels.at(0)就表示引用取出channels中的蓝色分量,channels.at(1)就表示引用取出channels中的绿色分量,channels.at(2)就表示引用取出channels中的红色分量
通道合并:merge()函数
merge()函数是split()函数的逆向操作——将多个数组合并成一个多通道的数组。
示例:
Mat srcImage = imread("1.jpg");
Mat imageBlueChannel,imageGreenChannel,imageRedChannel,mergeImage;
//定义Mat向量容器保存拆分后的数据
vector<Mat> channels;
//通道的拆分
split(srcImage,channels);
//提取三色的通道的数据
imageBlueChannel = channels.at(0);
imageGreenChannel = channels.at(1);
imageRedChannel = channels.at(2);
//对拆分的通道数据合并
merge(channels,mergeImage);
imshow("mergeImage",mergeImage);
复杂的通道组合,可以使用mixChannels()函数
示例程序:多通道混合
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
bool MultiChannelBlending();
int main( )
{
system("color 9F");
ShowHelpText( );
if(MultiChannelBlending( ))
{
cout<<endl<<"\n运行成功,得出了需要的图像~! ";
}
waitKey(0);
return 0;
}
//-----------------------------【MultiChannelBlending( )函数】--------------------------------
// 描述:多通道混合的实现函数
//-----------------------------------------------------------------------------------------------
bool MultiChannelBlending()
{
//【0】定义相关变量
Mat srcImage;
Mat logoImage;
vector<Mat> channels;
Mat imageBlueChannel;
//=================【蓝色通道部分】=================
// 描述:多通道混合-蓝色分量部分
//============================================
// 【1】读入图片
logoImage= imread("dota_logo.jpg",0);
srcImage= imread("dota_jugg.jpg");
if( !logoImage.data ) { printf("Oh,no,读取logoImage错误~! \n"); return false; }
if( !srcImage.data ) { printf("Oh,no,读取srcImage错误~! \n"); return false; }
//【2】把一个3通道图像转换成3个单通道图像
split(srcImage,channels);//分离色彩通道
//【3】将原图的蓝色通道引用返回给imageBlueChannel,注意是引用,相当于两者等价,修改其中一个另一个跟着变
imageBlueChannel= channels.at(0);
//【4】将原图的蓝色通道的(500,250)坐标处右下方的一块区域和logo图进行加权操作,将得到的混合结果存到imageBlueChannel中
addWeighted(imageBlueChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,
logoImage,0.5,0,imageBlueChannel(Rect(500,250,logoImage.cols,logoImage.rows)));
//【5】将三个单通道重新合并成一个三通道
merge(channels,srcImage);
//【6】显示效果图
namedWindow(" <1>游戏原画+logo蓝色通道");
imshow(" <1>游戏原画+logo蓝色通道",srcImage);
//=================【绿色通道部分】=================
// 描述:多通道混合-绿色分量部分
//============================================
//【0】定义相关变量
Mat imageGreenChannel;
//【1】重新读入图片
logoImage= imread("dota_logo.jpg",0);
srcImage= imread("dota_jugg.jpg");
if( !logoImage.data ) { printf("读取logoImage错误~! \n"); return false; }
if( !srcImage.data ) { printf("读取srcImage错误~! \n"); return false; }
//【2】将一个三通道图像转换成三个单通道图像
split(srcImage,channels);//分离色彩通道
//【3】将原图的绿色通道的引用返回给imageBlueChannel,注意是引用,相当于两者等价,修改其中一个另一个跟着变
imageGreenChannel= channels.at(1);
//【4】将原图的绿色通道的(500,250)坐标处右下方的一块区域和logo图进行加权操作,将得到的混合结果存到imageGreenChannel中
addWeighted(imageGreenChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,
logoImage,0.5,0.,imageGreenChannel(Rect(500,250,logoImage.cols,logoImage.rows)));
//【5】将三个独立的单通道重新合并成一个三通道
merge(channels,srcImage);
//【6】显示效果图
namedWindow("<2>游戏原画+logo绿色通道");
imshow("<2>游戏原画+logo绿色通道",srcImage);
//=================【红色通道部分】=================
// 描述:多通道混合-红色分量部分
//============================================
//【0】定义相关变量
Mat imageRedChannel;
//【1】重新读入图片
logoImage= imread("dota_logo.jpg",0);
srcImage= imread("dota_jugg.jpg");
if( !logoImage.data ) { printf("Oh,no,读取logoImage错误~! \n"); return false; }
if( !srcImage.data ) { printf("Oh,no,读取srcImage错误~! \n"); return false; }
//【2】将一个三通道图像转换成三个单通道图像
split(srcImage,channels);//分离色彩通道
//【3】将原图的红色通道引用返回给imageBlueChannel,注意是引用,相当于两者等价,修改其中一个另一个跟着变
imageRedChannel= channels.at(2);
//【4】将原图的红色通道的(500,250)坐标处右下方的一块区域和logo图进行加权操作,将得到的混合结果存到imageRedChannel中
addWeighted(imageRedChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,
logoImage,0.5,0.,imageRedChannel(Rect(500,250,logoImage.cols,logoImage.rows)));
//【5】将三个独立的单通道重新合并成一个三通道
merge(channels,srcImage);
//【6】显示效果图
namedWindow("<3>游戏原画+logo红色通道 ");
imshow("<3>游戏原画+logo红色通道 ",srcImage);
return true;
}
运行截图: