• OpenCV 学习笔记(8)彩色图像RGB通道的分离、合并与显示


    https://blog.csdn.net/ZYTTAE/article/details/42234989

    由于算法的需要,需要把彩色图像的R、G、B值分离出来,OpenCV中正好有split() 和 merge() 函数可以实现。

    一、对单独彩色图片的RGB通道分离:

    #include <iostream>
    #include "cv.h"
    #include "highgui.h"
     
    using namespace std;
    using namespace cv;
     
    int main(int argc,char* argv[])
    {
    	Mat img = imread("lena.jpg"/*,CV_LOAD_IMAGE_COLOR*/);
    	Mat channel[3];
    	split(img,channel);
    	imshow("original",img);
    	imshow("B",channel[0]);
    	imshow("G",channel[1]);
    	imshow("R",channel[2]);
     
    	//set blue channel to 0
    	channel[0] = Mat::zeros(img.rows,img.cols,CV_8UC1);
    	//merge red and green channels
    	merge(channel,3,img);
    	imshow("R_G_merge",img);
     
    	waitKey(0);
    	return 1;
    }
    

      

    二、对摄像头摄入视频帧的RGB彩色通道分离

    int main(int argc,char* argv[])
    {
    	VideoCapture cap;
    	cap.open(0);
     
    	if(!cap.isOpened()) 
    	{
    		exit(0);
    	}
     
    	cap.set(CV_CAP_PROP_FRAME_WIDTH,250);
    	cap.set(CV_CAP_PROP_FRAME_HEIGHT,250);
     
    	cout << "Frame Width: " << cap.get(CV_CAP_PROP_FRAME_WIDTH) << endl;
    	cout << "Frame Height: " << cap.get(CV_CAP_PROP_FRAME_HEIGHT) << endl;
     
    	Mat frame;
    	vector<Mat> rgb;
    	cap >> frame;
     
    	//rgb.push_back( Mat(frame.rows, frame.cols, CV_8UC1));
    	//rgb.push_back( Mat(frame.rows, frame.cols, CV_8UC1));
    	//rgb.push_back( Mat(frame.rows, frame.cols, CV_8UC1));
    	//rgb.push_back( Mat(frame.rows, frame.cols, CV_8UC1));
     
    	namedWindow("original", 1);
    	namedWindow("red", 1);
    	namedWindow("green", 1);
    	namedWindow("blue", 1);
     
    	for(;;)
    	{
    		cap >> frame;
    		imshow("original", frame);
    		split(frame, rgb);
     
    		imshow("red", rgb.at(2));
    		imshow("green", rgb.at(1));
    		imshow("blue", rgb.at(0));
     
    		if(waitKey(30) >= 0) 
    			break;
    	}
     
    	waitKey(0);
    	return 1;
    }
    

      

    1.split()函数

    此函数的作用是将一个图像通道进行分离。
    首先看一下split()函数定义:

    void split(const Mat& m, vector<Mat>& mv );

    参数说明:

    第一个参数,const Mat&类型的src,填我们需要进行分离的图像;
    第二个参数,vector<Mat>类型的mv,填函数的输出数组或者输出的vector容器,即分离后的图像;

    2.merge()函数
    merge()函数的功能是split()函数的逆向操作,将多个数组合并成一个多通道的数组。
    首先看一下merge()函数定义:

    void merge(const vector<Mat>& mv, OutputArray dst );

    参数说明:

    第一个参数,const <Mat>类型的mv,填需要被合并的vector容器的阵列,这个mv参数中所有的矩阵必须有着一样的尺寸和深度;说白了就是前面被split()函数分离后的图像通道。
    第二个参数,保存为合并后的图像;

    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <iostream>
    using namespace cv;
    using namespace std;
     
    int main()
    {
    	//【0】定义相关变量
    	Mat srcImage, newImage;					//源图像、通道合并后的图像
    	Mat srcImage_B, srcImage_G, srcImage_R;	//R、G、B各个通道
    	Mat image_H, image_S, image_V;			//H、S、V各个通道
    	vector<Mat> channels_BGR;		//vector<Mat>: 可以理解为存放Mat类型的容器(数组)
    	vector<Mat> channels_HSV;
    	//【1】读取原始图像并检查图像是否读取成功  
    	srcImage = imread("D:\OutPutResult\ImageTest\adog.jpg");	//请修改为自己的图像路径
    	if (srcImage.empty())
    	{
    		cout << "读取图像有误,请重新输入正确路径!
    ";
    		return -1;
    	}
    	imshow("srcImage源图像", srcImage);		//在窗口显示源图像  
     
    	//【2】对加载的原图像进行通道分离,即把一个3通道图像转换成为3个单通道图像
    	split(srcImage, channels_BGR);
    	//0通道为B分量,1通道为G分量,2通道为R分量。因为:RGB色彩空间在opencv中默认通道顺序为BGR!!!
    	srcImage_B = channels_BGR.at(0);
    	srcImage_G = channels_BGR.at(1);
    	srcImage_R = channels_BGR.at(2);
    	imshow("srcImage_B通道", srcImage_B);	//分别显示R,G,B各个通道图像
    	imshow("srcImage_G通道", srcImage_G);
    	imshow("srcImage_R通道", srcImage_R);
     
    	//【3】将BGR颜色空间转换为HSV颜色空间
    	Mat image_hsv;
    	cvtColor(srcImage, image_hsv, CV_BGR2HSV);
    	imshow("HSV颜色空间图像", image_hsv);
     
    	//【4】对加载的HSV图像进行通道分离
    	split(image_hsv, channels_HSV);
    	//0通道为H分量,1通道为S分量,2通道为V分量
    	image_H = channels_HSV.at(0);
    	image_S = channels_HSV.at(1);
    	image_V = channels_HSV.at(2);
    	imshow("image_H通道", image_H);//分别显示H,S,V各个通道图像
    	imshow("image_S通道", image_S);
    	imshow("image_V通道", image_V);
     
    	//【5】将3个单通道重新合并成一个三通道图像
    	merge(channels_HSV, newImage);
    	imshow("将H,S,V通道合并后的图像", newImage);
     
    	//【6】保持等待状态  
    	waitKey(0);
    	return 0;
    }
    

      

    5.程序说明
    
    看到这里,可能有人会问为什么分离出的通道都是黑白灰,而不是红绿蓝?
    
    原因是分离后为单通道,相当于分离通道的同时把其他两个通道填充了相同的数值。比如红色通道,分离出红色通道的同时,绿色和蓝色被填充为和红色相同的数值,这样一来就只有黑白灰了。那么红色体现在哪呢?可以进行观察,会发现原图中颜色越接近红色的地方在红色通道越接近白色。
    
    
    
    ====================分割线===============
    
    此程序共显示9个窗口。
    
    先将RGB图像通道分离,分别显示R、G、B、单个通道;
    
    后将RGB颜色空间转为HSV空间,将HSV图像通道分离,分别显示H、S、V、单个通道;
    
    最后将H、S、V、单个通道重新合并为3通道图像;
    
    
    
    =========================END======================
    

      

  • 相关阅读:
    Java运行 Unsupported major.minor version 51.0 错误
    Spark 概述
    spring入门-整合junit和web
    通过IE私有滤镜让IE6 7 8支持背景透明,内容不透明效果。
    目标计划及执行情况
    Bugku的一道注入
    在这个年纪,打DOTA冲分有那么可笑么?
    吴裕雄--天生自然HTML学习笔记:HTML 表格
    吴裕雄--天生自然HTML学习笔记:HTML 图像
    吴裕雄--天生自然HTML学习笔记:HTML 样式- CSS
  • 原文地址:https://www.cnblogs.com/kekeoutlook/p/11114892.html
Copyright © 2020-2023  润新知