14.多通道分离与合并
在图像颜色模型中不同的分量存放在不同的通道中,如果我们只需要颜色模型的某一个分量,例如只需要处理RGB图像中的红色通道,可以将红色通道从三通道的数据中分离出来再进行处理,这种方式可以减少数据所占据的内存,加快程序的运行速度。同时,当我们分别处理完多个通道后,需要将所有通道合并在一起重新生成RGB图像。针对图像多通道的分离与混合,OpenCV 4中提供了split()函数和merge()函数用于解决这些需求。
1、多通道分离函数split()
代码清单3-4 split()函数原型 1. void cv::split(const Mat & src, 2. Mat * mvbegin 3. ) 4. 5. void cv::split(InputArray m, 6. OutputArrayOfArrays mv 7. )
-
src:待分离的多通道图像。
-
mvbegin:分离后的单通道图像,为数组形式,数组大小需要与图像的通道数相同
-
m:待分离的多通道图像
-
mv:分离后的单通道图像,为向量vector形式
该函数主要是用于将多通道的图像分离成若干单通道的图像,两个函数原型中不同之处在于前者第二个参数输入的是Mat类型的数组,其数组的长度需要与多通道图像的通道数相等并且提前定义;第二种函数原型的第二个参数输入的是一个vector<Mat>容器,不需要知道多通道图像的通道数。两个函数原型虽然输入参数的类型不同,但是通道分离的原理是相同的,公式:mv(c)[I] = src(I)c
2、多通道合并函数merge()
OpenCV 4中针对多通道合并函数merge ()也有两种重载原型,在代码清单3-5中给出了两种原型。
代码清单3-5 merge()函数原型 1. void cv::merge(const Mat * mv, 2. size_t count, 3. OutputArray dst 4. ) 5. 6. void cv::merge(InputArrayOfArrays mv, 7. OutputArray dst 8. )
-
mv:需要合并的图像数组,其中每个图像必须拥有相同的尺寸和数据类型。
-
count:输入的图像数组的长度,其数值必须大于0.
-
mv:需要合并的图像向量vector,其中每个图像必须拥有相同的尺寸和数据类型。
-
dst:合并后输出的图像,与mv[0]具有相同的尺寸和数据类型,通道数等于所有输入图像的通道数总和。
该函数主要是用于将多个图像合并成一个多通道图像,该函数也具有两种不同的函数原型,每一种函数原型都是与split()函数像对应,两种原型分别输入数组形式的图像数据和向量vector形式的图像数据,在输入数组形式数据的原型中,还需要输入数组的长度。合并函数的输出结果是一个多通道的图像,其通道数目是所有输入图像通道数目的总和。这里需要说明的是,用于合并的图像并非都是单通道的,也可以是多个通道数目不相同的图像合并成一个通道更多的图像,虽然这些图像的通道数目可以不相同,但是需要所有图像具有相同的尺寸和数据类型。
3、图像多通道分离与合并例程
为了使读者更加熟悉图像多通道分离与合并的操作,同时加深对图像不同通道作用的理解,在代码清单3-6中实现了图像的多通道分离与合并的功能。程序中用两种函数原型分别分离了RGB图像和HSV图像,为了验证merge ()函数可以合并多个通道不相同的图像,程序中分别用两种函数原型合并了多个不同通道的图像,合并后图像的通道数为5,不能通过imshow()函数显示,我们用Image Watch插件查看了合并的结果。由于RGB三个通道分离结果显示时都是灰色且相差不大,因此图3-5没有给出其分离后的结果,只给出合并后显示为绿色的合并图像,同时给出HSV分离结果,其他结果读者可以自行运行程序查看。
代码清单3-6 mySplitAndMerge.cpp实现图像分离与合并 1. #include <opencv2\opencv.hpp> 2. #include <iostream> 3. #include <vector> 4. 5. using namespace std; 6. using namespace cv; 7. 8. int main() 9. { 10. Mat img = imread("lena.png"); 11. if (img.empty()) 12. { 13. cout << "请确认图像文件名称是否正确" << endl; 14. return -1; 15. } 16. Mat HSV; 17. cvtColor(img, HSV, COLOR_RGB2HSV); 18. Mat imgs0, imgs1, imgs2; //用于存放数组类型的结果 19. Mat imgv0, imgv1, imgv2; //用于存放vector类型的结果 20. Mat result0, result1, result2; //多通道合并的结果 21. 22. //输入数组参数的多通道分离与合并 23. Mat imgs[3]; 24. split(img, imgs); 25. imgs0 = imgs[0]; 26. imgs1 = imgs[1]; 27. imgs2 = imgs[2]; 28. imshow("RGB-R通道", imgs0); //显示分离后R通道的像素值 29. imshow("RGB-G通道", imgs1); //显示分离后G通道的像素值 30. imshow("RGB-B通道", imgs2); //显示分离后B通道的像素值 31. imgs[2] = img; //将数组中的图像通道数变成不统一 32. merge(imgs, 3, result0); //合并图像 33. //imshow("result0", result0); //imshow最多显示4个通道,因此结果在Image Watch中查看 34. Mat zero = cv::Mat::zeros(img.rows, img.cols, CV_8UC1); 35. imgs[0] = zero; 36. imgs[2] = zero; 37. merge(imgs, 3, result1); //用于还原G通道的真实情况,合并结果为绿色 38. imshow("result1", result1); //显示合并结果 39. 40. //输入vector参数的多通道分离与合并 41. vector<Mat> imgv; 42. split(HSV, imgv); 43. imgv0 = imgv.at(0); 44. imgv1 = imgv.at(1); 45. imgv2 = imgv.at(2); 46. imshow("HSV-H通道", imgv0); //显示分离后H通道的像素值 47. imshow("HSV-S通道", imgv1); //显示分离后S通道的像素值 48. imshow("HSV-V通道", imgv2); //显示分离后V通道的像素值 49. imgv.push_back(HSV); //将vector中的图像通道数变成不统一 50. merge(imgv, result2); //合并图像 51. //imshow("result2", result2); /imshow最多显示4个通道,因此结果在Image Watch中查看 52. waitKey(0); 53. return 0; 54. }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具