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 << "讀取圖像有誤,請重新輸入正確路徑!\n";
		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======================

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM