这篇博客我们来学习opencv的通道分离与合并(split,merge)两个函数:
OpenCV中默认imread函数加载图像文件,加载进来的是三通道彩色图像,色彩空间是RGB色彩空间、通道顺序是BGR(蓝色、绿色、红色)、对于三通道的图像OpenCV中提供了两个API函数用以实现通道分离与合并。
- split // 通道分类
- merge // 通道合并
- mixChannels //
扩展:
在很多CNN的卷积神经网络中输入的图像一般会要求[h, w, ch]其中h是高度、w是指宽度、ch是指通道数数目、OpenCV DNN模块中关于图像分类的googlenet模型输入[224,224,3]表示的就是224x224大小的三通道的彩色图像输入。
我们来看一个描绘了一个一般的RGB图像在opencv的Mat中像素数据存储结构以及通道分离/合并操作关系的图:
void split(InputArray m, OutputArrayOfArrays mv)
//split(待分离的Mat型多通道矩阵(二维),填分离后的Mat型单通道数组(三维)或一个vector对象);
//split(image, mv); //(输入图片,mat对象)
void merge(InputArrayOfArrays mv, OutputArray dst)
//merge(对象名channels,通道合并后的矩阵)
//merge(mv, dst); //(这块为mat对象,输出图片);
mixChannels(输入矩阵(可以1个,可以多个),矩阵个数,输出矩阵,矩阵个数,矩阵对应规则,fromTo的数组元素个数除以2)
//mixChannels(&image, 1, &dst, 1, from_to,3);
//输入的矩阵(或矩阵数组)的某些通道拆分复制给对应的输出矩阵(或矩阵数组)的某些通道中,
//其中的对应关系就由fromTo参数制定
void QuickDemo::channels_Demo(Mat &image)
{
std::vector<Mat>mv;
split(image, mv);
/*imshow("蓝色", mv[0]);
imshow("绿色", mv[1]);
imshow("红色", mv[2]);*/
Mat dst;
mv[0] = 0;
mv[1] = 0;
merge(mv, dst);
imshow("红色",dst);
//这里是通道交换规则:
int from_to[] = { 0,1,1,2,2,0 }; //即从0到1,1到2,2到0
mixChannels(&image, 1, &dst, 1, from_to,3);
imshow("通道混合",dst);
imwrite("C:/Users/Dell/Desktop/myself/tongdaohunhe.jpg", dst);
}
执行上述程序后。得到三张不同d灰度图:
为什么得到的是三张不同d灰度图呢?不是已经分离出R,G,B通道了吗?应该是分别是红色图,绿色图,蓝色图才对阿。
原因是:当调用 imshow(R)时,是把图像的R,G,B三个通道的值都变为R的值,所以图像的颜色三通道值为(R,R,R)
同理 imshow(G)和imshow(B)所显示d图像的颜色通道也依次为(G,G,G)和(B,B,B)。
而 当三个通道值相同时,则为灰度图。
当要合并成红色图时,即显示(0,0,R)图像,所以代码修改为
mv[0] = 0;
mv[1] = 0;
当要合并成蓝色图时,即显示(B,0,0)图像,所以代码修改为
mv[1] = 0;
mv[2] = 0;
当要合并成绿色图时,即显示(0,G,0)图像,所以代码修改为
mv[0] = 0;
mv[2] = 0;
上面代码中提到了转换规则为:
int from_to[] = { 0,1,1,2,2,0 };
int from_to[] = { 0,2,1,1,2,0 };
这个可以多加尝试,我就不再赘述。
这篇博客主要学习了三个API函数,分别为通道合并merge函数、通道分离split函数、通道混合mixChannels函数。
加油吧 阿超没有蛀牙!