使用Opencv分离图像通道/合并图像通道

本文介绍如何使用OpenCV库实现图像的RGB和HSV颜色空间的通道分离及合并操作,包括具体步骤与代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. 使用cvSplit将图像的中的通道拆分到单个图像中
1.所需函数:cvSplit
函数功能:将图像的中的通道拆分到单个图像中

函数原型:

void  cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1,CvArr* dst2, CvArr* dst3 );

参数介绍:

const CvArr* src:       输入的多通道图像
CvArr* dst0:		 输出的B通道图像
CvArr* dst1:		 输出的G通道图像
CvArr* dst2:		 输出的R通道图像
CvArr* dst3:            输出的A通道图像

返回值:无

 

2.cvMerge

 

函数功能:用于将通道合并到图像中

函数原型:

void  cvMerge( const CvArr* src0, const CvArr* src1,const CvArr* src2, const CvArr* src3,CvArr* dst );

参数介绍:

const CvArr* src0:    输入B通道
const CvArr* src1:    输入G通道
const CvArr* src2:    输入R通道
const CvArr* src3:    输入A通道
CvArr* dst:	       输出图像

返回值:无

 

二.开始编写代码

2.1 将测试图加载到内存

//加载图像到内存
IplImage *image = cvLoadImage("D:\\1.jpg");	//将图像加载到内存
if (image == NULL){		//判断是否加载成功
	printf("图像文件打开失败");
}

2.2 创建三幅单通道图像用来存储原图上的RGB通道

//创建存储RGB通道图像
IplImage *image_r = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
IplImage *image_g = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
IplImage *image_B = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像

2.3 创建多通道图像

注意分离后的图像是的单通道的只能显示灰度图,所以我们要创建多通道图像与用来存储RGB值

//创建多通道的RGB图像
IplImage *image_rgb_r = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
IplImage *image_rgb_g = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
IplImage *image_rgb_b = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像

 

2.4 分离通道

 

//分离通道
cvSplit(image, image_b, image_g, image_r,NULL);	//注意Opencv中默认是BGR格式不是RGB!

2.5 合并图像

注意分离后的图像是的单通道的只能显示灰度图,所以我们要将其转换成彩色图

//合并图像
cvMerge(image_b, 0, 0, NULL, image_rgb_b);	//合并图像
cvMerge(0, image_g, 0, NULL, image_rgb_g);	//合并图像
cvMerge(0, 0, image_r, NULL, image_rgb_r);	//合并图像

2.6 显示图像

//显示图像
	cvNamedWindow("image",0);
	cvNamedWindow("image_r", 0);
	cvNamedWindow("image_g", 0);
	cvNamedWindow("image_b", 0);
	cvShowImage("image", image);
	cvShowImage("image_r", image_rgb_r);
	cvShowImage("image_g", image_rgb_g);
	cvShowImage("image_b", image_rgb_b);

2.5 释放内存

//释放内存
cvReleaseImage(&image);
cvReleaseImage(&image_r);
cvReleaseImage(&image_g);
cvReleaseImage(&image_b);
cvReleaseImage(&image_rgb_r);
cvReleaseImage(&image_rgb_g);
cvReleaseImage(&image_rgb_b);

 

运行结果:

 

 

如需测试可以自行使用绘图软件进行颜色调整测试,看一下是否一致

完整代码:

//加载图像到内存
	IplImage *image = cvLoadImage("D:\\1.jpg");	//将图像加载到内存
	if (image == NULL){		//判断是否加载成功
		printf("图像文件打开失败");
	}
	//创建存储RGB通道图像
	IplImage *image_r = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
	IplImage *image_g = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
	IplImage *image_b = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
	//创建多通道的RGB图像
	IplImage *image_rgb_r = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
	IplImage *image_rgb_g = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
	IplImage *image_rgb_b = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
	//分离通道
	cvSplit(image, image_b, image_g, image_r,NULL);	//注意Opencv中默认是BGR格式不是RGB!
	//合并图像
	cvMerge(image_b, 0, 0, NULL, image_rgb_b);	//合并图像
	cvMerge(0, image_g, 0, NULL, image_rgb_g);	//合并图像
	cvMerge(0, 0, image_r, NULL, image_rgb_r);	//合并图像
	//显示图像
	cvNamedWindow("image",0);
	cvNamedWindow("image_r", 0);
	cvNamedWindow("image_g", 0);
	cvNamedWindow("image_b", 0);
	cvShowImage("image", image);
	cvShowImage("image_r", image_rgb_r);
	cvShowImage("image_g", image_rgb_g);
	cvShowImage("image_b", image_rgb_b);
	cvWaitKey(0);
	//释放内存
	cvReleaseImage(&image);
	cvReleaseImage(&image_r);
	cvReleaseImage(&image_g);
	cvReleaseImage(&image_b);
	cvReleaseImage(&image_rgb_r);
	cvReleaseImage(&image_rgb_g);
	cvReleaseImage(&image_rgb_b);

合并三通道,只需要在cvWaitKey函数前加上如下代码:

//合并图像
IplImage *image_rgb = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
cvMerge(image_b, image_g, image_r, NULL, image_rgb);	//合并图像
//显示合并后图像
cvNamedWindow("image_rgb", 0);
cvShowImage("image_rgb", image_rgb);

运行结果:

最后别忘记释放哦

cvReleaseImage(&image_rgb);

完整代码:

//加载图像到内存
	IplImage *image = cvLoadImage("D:\\1.jpg");	//将图像加载到内存
	if (image == NULL){		//判断是否加载成功
		printf("图像文件打开失败");
	}
	//创建存储RGB通道图像
	IplImage *image_r = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
	IplImage *image_g = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
	IplImage *image_b = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
	//创建多通道的RGB图像
	IplImage *image_rgb_r = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
	IplImage *image_rgb_g = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
	IplImage *image_rgb_b = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
	//分离通道
	cvSplit(image, image_b, image_g, image_r,NULL);	//注意Opencv中默认是BGR格式不是RGB!
	//合并图像
	cvMerge(image_b, 0, 0, NULL, image_rgb_b);	//合并图像
	cvMerge(0, image_g, 0, NULL, image_rgb_g);	//合并图像
	cvMerge(0, 0, image_r, NULL, image_rgb_r);	//合并图像
	//显示图像
	cvNamedWindow("image",0);
	cvNamedWindow("image_r", 0);
	cvNamedWindow("image_g", 0);
	cvNamedWindow("image_b", 0);
	cvShowImage("image", image);
	cvShowImage("image_r", image_rgb_r);
	cvShowImage("image_g", image_rgb_g);
	cvShowImage("image_b", image_rgb_b);
	//合并图像
	IplImage *image_rgb = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
	cvMerge(image_b, image_g, image_r, NULL, image_rgb);	//合并图像
	//显示合并后图像
	cvNamedWindow("image_rgb", 0);
	cvShowImage("image_rgb", image_rgb);
	cvWaitKey(0);
	//释放内存
	cvReleaseImage(&image);
	cvReleaseImage(&image_r);
	cvReleaseImage(&image_g);
	cvReleaseImage(&image_b);
	cvReleaseImage(&image_rgb_r);
	cvReleaseImage(&image_rgb_g);
	cvReleaseImage(&image_rgb_b);
	cvReleaseImage(&image_rgb);

实验图:

HSV通道:

用到cvCvtColor函数,稍微复用一下上面代码即可:

注意HSV颜色空间没有顺序问题,而RGB颜色空间Opencv使用的是BGR!

//加载图像到内存
	IplImage *image = cvLoadImage("D:\\1.jpg");	//将图像加载到内存
	if (image == NULL){		//判断是否加载成功
		printf("图像文件打开失败");
	}
	//创建存储HSV通道图像
	IplImage *image_H = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
	IplImage *image_S = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
	IplImage *image_V = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
	//创建多通道的HSV图像
	IplImage *image_HSV_H = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
	IplImage *image_HSV_S = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
	IplImage *image_HSV_V = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
	//RGB颜色空间到HSV颜色空间转换
	IplImage *image1 = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels);  //注意图像必须和输入图像的size,颜色位深度,通道一致  
	cvZero(image1); //清空image_data数据  
	cvCvtColor(image, image1, CV_BGR2HSV);//CV_BGR2HSV  
	//分离通道
	cvSplit(image1, image_H, image_S, image_V, NULL);	//注意Opencv中默认是BGR格式不是RGB!
	//合并图像
	cvMerge(image_H, 0, 0, NULL, image_HSV_H);	//合并图像
	cvMerge(0, image_S, 0, NULL, image_HSV_S);	//合并图像
	cvMerge(0, 0, image_V, NULL, image_HSV_V);	//合并图像
	//显示图像
	cvNamedWindow("image", 0);
	cvNamedWindow("image_H", 0);
	cvNamedWindow("image_S", 0);
	cvNamedWindow("image_V", 0);
	cvShowImage("image", image);
	cvShowImage("image_H", image_HSV_H);
	cvShowImage("image_S", image_HSV_S);
	cvShowImage("image_V", image_HSV_V);
	cvWaitKey(0);
	//释放内存
	cvReleaseImage(&image);
	cvReleaseImage(&image_H);
	cvReleaseImage(&image_S);
	cvReleaseImage(&image_V);
	cvReleaseImage(&image_HSV_H);
	cvReleaseImage(&image_HSV_S);
	cvReleaseImage(&image_HSV_V);


运行结果:

 

 

合成HSV也是一样,在CvWaiKey函数前面加上:

cvNamedWindow("image_HSV", 0);
	IplImage *image_HSV = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels);  //注意图像必须和输入图像的size,颜色位深度,通道一致  
	cvZero(image_HSV); //清空image_data数据  
	cvMerge(image_H, image_S, image_V, NULL, image_HSV);	//合并图像
	cvShowImage("image_HSV", image_HSV);

运行结果:

别忘记释放内存哦

cvReleaseImage(&image_HSV);

完整代码:

//加载图像到内存
	IplImage *image = cvLoadImage("D:\\1.jpg");	//将图像加载到内存
	if (image == NULL){		//判断是否加载成功
		printf("图像文件打开失败");
	}
	//创建存储HSV通道图像
	IplImage *image_H = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
	IplImage *image_S = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
	IplImage *image_V = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
	//创建多通道的HSV图像
	IplImage *image_HSV_H = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
	IplImage *image_HSV_S = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
	IplImage *image_HSV_V = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3);//注意,必须是多通道图像
	//RGB颜色空间到HSV颜色空间转换
	IplImage *image1 = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels);  //注意图像必须和输入图像的size,颜色位深度,通道一致  
	cvZero(image1); //清空image_data数据  
	cvCvtColor(image, image1, CV_BGR2HSV);//CV_BGR2HSV  
	//分离通道
	cvSplit(image1, image_H, image_S, image_V, NULL);	//注意Opencv中默认是BGR格式不是RGB!
	//合并图像
	cvMerge(image_H, 0, 0, NULL, image_HSV_H);	//合并图像
	cvMerge(0, image_S, 0, NULL, image_HSV_S);	//合并图像
	cvMerge(0, 0, image_V, NULL, image_HSV_V);	//合并图像
	//显示图像
	cvNamedWindow("image", 0);
	cvNamedWindow("image_H", 0);
	cvNamedWindow("image_S", 0);
	cvNamedWindow("image_V", 0);
	cvShowImage("image", image);
	cvShowImage("image_H", image_HSV_H);
	cvShowImage("image_S", image_HSV_S);
	cvShowImage("image_V", image_HSV_V);
	cvNamedWindow("image_HSV", 0);
	IplImage *image_HSV = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels);  //注意图像必须和输入图像的size,颜色位深度,通道一致  
	cvZero(image_HSV); //清空image_data数据  
	cvMerge(image_H, image_S, image_V, NULL, image_HSV);	//合并图像
	cvShowImage("image_HSV", image_HSV);
	cvWaitKey(0);
	//释放内存
	cvReleaseImage(&image);
	cvReleaseImage(&image_H);
	cvReleaseImage(&image_S);
	cvReleaseImage(&image_V);
	cvReleaseImage(&image_HSV_H);
	cvReleaseImage(&image_HSV_S);
	cvReleaseImage(&image_HSV_V);
	cvReleaseImage(&image_HSV);

 

注意Opencv中有一个宏定义是cvCvtPixToPlane 其实就是cvSplit的别名!

原型:

#define cvCvtPixToPlane cvSplit

相关链接:使用Opencv将RGB颜色空间转换到HSV颜色空间/灰度图

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

17岁boy想当攻城狮

感谢打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值