zoukankan      html  css  js  c++  java
  • 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======================
    

      

  • 相关阅读:
    POJ 1659 Frogs' Neighborhood
    zoj 2913 Bus Pass(BFS)
    ZOJ 1008 Gnome Tetravex(DFS)
    POJ 1562 Oil Deposits (DFS)
    zoj 2165 Red and Black (DFs)poj 1979
    hdu 3954 Level up
    sgu 249 Matrix
    hdu 4417 Super Mario
    SPOJ (BNUOJ) LCM Sum
    hdu 2665 Kth number 划分树
  • 原文地址:https://www.cnblogs.com/kekeoutlook/p/11114892.html
Copyright © 2011-2022 走看看