11 通道分离与合并
11 通道分离与合并
opencv知识点:
- 通道分离 - split()
- 通道合并 - merge()
- 通道混合 - mixChannels()
本课所解决的问题:
- 如何分离RGB三通道?
- 如何合并RGB三通道?
- 如何对通道进行混合?
1.RGB三通道的解释
彩色图像,是由RGB三个通道合并起来得到的。
如果R,G,B分离,它们就分别对应一个单通道图像(因为都是单通道,所以为灰度图像)
当然,这三个单通道图像再经过合并,就会恢复成原本的彩色图像了
下图中间的R,G,B图,并不是分离,而是3通道中其他两个通道置0了 。
这时,如果再通过BGR2GRAY转换色彩空间,就可以得到对应的单通道图像。
![f3992086d11f44159ba37db3f153a10a](https://picture0717.oss-cn-beijing.aliyuncs.com/img/f3992086d11f44159ba37db3f153a10a.png)
2.通道分离
分离通道要用到split
根据文档,我们有两种分离方式
第一种方式
//函数定义
void channels_demo(Mat& image);
//函数实现—
void QuickDemo::channels_demo(Mat& image) {
Mat mvt[3];
/*
第一种方式
通过创建图像数组,存储每个单通道图像
*/
split(image, mvt);
imshow("蓝色单通道", mvt[0]);
imshow("绿色单通道", mvt[1]);
imshow("蓝色单通道", mvt[2]);
}
第二种方式
void QuickDemo::channels_demo(Mat& image) {
std::vector<Mat> mvt;
/*
第二种方式
通过创建动态数组,存储每个单通道图像
*/
split(image, mvt);
imshow("蓝色单通道", mvt[0]);
imshow("绿色单通道", mvt[1]);
imshow("红色单通道", mvt[2]);
}
分离后得到的结果
3.通道合并
合并通道要用到merge
根据文档,我们有两种合并方式
第一种方式
void QuickDemo::channels_demo(Mat& image) {
Mat mvt[3];
split(image, mvt);
imshow("蓝色单通道", mvt[0]);
imshow("绿色单通道", mvt[1]);
imshow("红色单通道", mvt[2]);
Mat dst;
merge(mvt,3,dst);
/*这里的3指,共有3个单通道图像*/
imshow("分离再合并",dst);
}
合并后得到的结果
第二种方式
void QuickDemo::channels_demo(Mat& image) {
std::vector<Mat> mvt;
split(image, mvt);
imshow("蓝色单通道", mvt[0]);
imshow("绿色单通道", mvt[1]);
imshow("红色单通道", mvt[2]);
Mat dst;
merge(mvt, dst);
imshow("分离再合并",dst);
}
合并后得到的结果:
4.通道混合
通道混合要用到mixChannels
mixChannels
混合通道
共6个参数
第1个参数 输入
第2个参数 输入的矩阵数
第3个参数 输出
第4个参数 输出的矩阵数
第5个参数 从哪个通道 变成 哪个通道
第6个参数 要变的对数
这里我们进行一个演示,实现如下通道的混合
- 0通道→2通道
- 1通道不变
- 2通道→1通道
这个混合的意思是,彩色图像本来是bgr的顺序,经过通道混合就变成了rgb。
- 0通道的单通道图像,变成了2通道的单通道图像
- 1通道不变
- 2通道的单通道图像,变成了0通道的单通道图像
void QuickDemo::channels_demo(Mat& image) {
Mat dst = Mat::zeros(image.size(), image.type());
int from_to[] = { 0,2,1,1,2,0 };
mixChannels(&image, 1, &dst, 1, from_to, 3);
imshow("通道混合",dst);
}
混合通道后的结果
本课所用API查阅
split()
char d[] = {1,2,3,4,5,6,7,8,9,10,11,12};
Mat m(2, 2, CV_8UC3, d);
Mat channels[3];
split(m, channels);
/*
channels[0] =
[ 1, 4;
7, 10]
channels[1] =
[ 2, 5;
8, 11]
channels[2] =
[ 3, 6;
9, 12]
*/
merge()
Mat m1 = (Mat_<uchar>(2,2) << 1,4,7,10);
Mat m2 = (Mat_<uchar>(2,2) << 2,5,8,11);
Mat m3 = (Mat_<uchar>(2,2) << 3,6,9,12);
Mat channels[3] = {m1, m2, m3};
Mat m;
merge(channels, 3, m);
/*
m =
[ 1, 2, 3, 4, 5, 6;
7, 8, 9, 10, 11, 12]
m.channels() = 3
*/
mixChannels()
Mat bgra( 100, 100, CV_8UC4, Scalar(255,0,0,255) );
Mat bgr( bgra.rows, bgra.cols, CV_8UC3 );
Mat alpha( bgra.rows, bgra.cols, CV_8UC1 );
// forming an array of matrices is a quite efficient operation,
// because the matrix data is not copied, only the headers
Mat out[] = { bgr, alpha };
// bgra[0] -> bgr[2], bgra[1] -> bgr[1],
// bgra[2] -> bgr[0], bgra[3] -> alpha[0]
int from_to[] = { 0,2, 1,1, 2,0, 3,3 };
mixChannels( &bgra, 1, out, 2, from_to, 4 );