多通道(Multichannel)單通道(singlechannel)圖像概念梳理————OpenCV筆記(六)

          在做機器視覺時,常常要將一個多通道圖像分離成幾個單通道圖像或者將幾個單通道圖像合成一個多通道圖像,以方便圖像處理,但是。寫這篇博客,是爲加深對這兩個概念的理解,下面會給出部分OpenCV對單通道與多通道圖像間相互轉化的程序代碼,並對運行結果進行觀察分析。

          OpenCV中常用IplImage或CvMat存儲圖像矩陣,而對這兩個對象的初始化函數cvCreateImage(CvSize size, int depth, int channels )cvCreateMat( int rows, int cols, int type );的最後一個參數channels(通道數可以是1、2、3、4)和type都包含了選擇通道數,一般來說常用的是RGB顏色空間,而R、G、B則表示三個通道,是三通道圖像。此外,depth代表深度,type裏包含對深度的選擇,深度即選擇存儲圖像矩陣的元素數據類型(長度),當然是數據長度(比如8bit,16bit,32bit)越長,能存儲的範圍越大,相應的,像素也越大,圖像就越清晰。

          圖像通道在RGB色彩模式下就是指下就是指那單獨的紅色R、綠色G、藍色B部分。也就是說,一幅完整的圖像,是由紅色綠色藍色三個通道組成的。他們共同作用產生了完整的圖像。同樣在HSV色系中指的是色調H,飽和度S,亮度V三個通道。除了這兩個三通道圖像模式,以下列舉了還列舉一些圖像模式(來自百度百科圖像模式)

    圖像模式:          

1、位圖模式
位圖模式是1位深度的圖像。它只是黑和白兩種顏色。它可以由掃描或置入黑色的矢量線條圖像生成,也能由灰度模式或雙色調模式轉換而成。其他圖像模式不能直接轉換爲位圖模式。
2、灰度模式
灰度模式是8位深度的圖像模式。也就是28,28=256,在全黑和全白之間插有254個灰度等級的顏色來描繪灰度模式的圖像。
所有模式的圖像都能換成灰度模式,甚至位圖也可轉換爲灰度模式。Photoshop幾乎所有的功能都支持灰度模式。
3、雙色調模式
雙色調模式不是單個的圖像模式,而是一個分類。它僅僅是單色調、雙色調、三色調和四色調的一個統稱。雙色調模式只有一個通道。雙色調模式和位圖模式一樣,也只有灰度模式才能轉換。
4、RGB模式
RGB模式是數碼圖像中最重要的一個模式,Photoshop的全部功能都支持它,因爲Photoshop就是以它爲基礎來開發的。顯示屏上顯示的顏色是RGB模式,電視屏幕也是RGB模式,所不同的它不是用數碼而是用電平來描述的。掃描儀和數碼相機都是捕捉RGB圖像信息的。
RGB模式是相加的模式,當R、G、B的值都達到最大值時,三色合成便成白色。
RGB模式是24位顏色深度。它共有三個通道,每個通道都有8位深度。三個通道合成一起可生成1677萬種顏色,我們也稱之謂“真彩色”。
5、CMYK模式
CMYK模式是用來打印或印刷的模式,它是相減的模式,當C、M、Y三值達到最大值時,在理論上應爲黑色,但實際上因顏料的關係,呈顯的不是黑色,而是深褐色。爲彌補這個問題,所以加進了黑色K。
由於加了黑色,CMYK共有四個通道,正因爲如此,對於同一個圖像文件來說,CMYK模式比RGB模式的信息量要大四分之一。
但RGB模式的色域範圍比CMYK模式大。因爲印刷顏料在印刷過程中不能重現RGB色彩。
CMY和RGB爲互補色。
C-青色:由G-綠色和B-藍色合成,其中沒有R-紅色成份;
M-洋紅:由R-紅色和B-藍色合成,其中沒有G-綠色成份;
Y-黃色:由R-綠色和G-紅色合成,其中沒有B-藍色成份;
CMYK模式不能轉換爲索引模式。
Photoshop的大部分功能不支持CMYK模式
6、Lab模式
Lab模式是24位顏色深度的圖像模式,有三個通道。L通道是亮度通道(Lightness),a和b兩個爲色彩通道。它的特點在於:
(1)他的色域範圍最廣,它和RGB與CMYK模式的關係如下:
就色域範圍而言Lab>RGB>CMYK
(2)此模式下的圖像是獨立於設備外的,它的顏色不會因不同的印刷設備,顯示器和操作平臺而改變。由於它有以上的有點,當Photoshop把RGB模式和CMYK模式互相轉換時,它成爲中間模式,顏色信息就不會因以上兩模式的色域範圍不同而丟失。
a分量是由綠色向紅色過度。
B分量是由藍色向黃色過渡。
Lab模式不能轉換爲索引模式。
Photoshop的大部分功能不支持Lab模式。
7、索引顏色模式
索引顏色模式是8位顏色深度模式,它最多隻能擁有256種顏色。
(1)每一副圖像都各自擁有一張顏色表,而隨圖像不同,顏色表也不同。這一點是至關重要的。
(2)它的信息量小,又可制動畫,所以它的圖像和動畫被廣泛地用於網頁製作上。
(3)它可製成透明圖像,在網頁使用。
在轉換時,只有灰度和RGB兩種模式,不能轉換成索引顏色模式。
轉換時只有兩個選擇是實用的:
(隨樣性 )當圖像顏色數大於256時,使用該選項,Photoshop會定做顏色表。實際當圖像顏色小於256時,使用該選項,就用實際的顏色製作顏色表。
Photoshop完全不支持索引顏色模式。
8、多通道模式
多通道模式是把含有通道的圖像分割成單個的通道。
CMYK模式轉爲多通道模式時,生成的通道爲青色、洋紅、黃色和黑色四個通道。
Lab模式轉爲多通道模式時,生成三個Alpha通道。
9、8位/通道和16位/通道
在灰度、RGB和CMYK模式下可以用每個通道16位深度來取代8位深度。那麼,每個通道的顏色數從256色劇增到65536色,可生成更好的顏色細節。
目前,由於設備的不支持,16位/通道的圖像不能被打印或印刷。

除了這些,還有HSV色系也比較重要,我在另一篇博客上簡單的探究了HSV色系,有興趣可以參考學習。點擊

圖像模式的轉換與分離
  在OpenCV中,常用cvCvtColor( const CvArr* src, CvArr* dst, int code );函數將一種模式的圖像轉換爲另一種模式的圖像。其中,這個函數的第三個參數code選擇要轉換的目標圖像模式,
OpenCVchm文檔中介紹該函數所有可能的色彩空間相互變換有:
RGB<=>XYZ (CV_BGR2XYZ, CV_RGB2XYZ, CV_XYZ2BGR, CV_XYZ2RGB)
RGB<=>YCrCb (CV_BGR2YCrCb, CV_RGB2YCrCb, CV_YCrCb2BGR, CV_YCrCb2RGB)
RGB=>HSV (CV_BGR2HSV,CV_RGB2HSV) 
RGB=>Lab (CV_BGR2Lab, CV_RGB2Lab)
上面的轉換公式可以參考 http://www.cica.indiana.edu/cica/faq/color_spaces/color.spaces.html
Bayer=>RGB (CV_BayerBG2BGR, CV_BayerGB2BGR, CV_BayerRG2BGR, CV_BayerGR2BGR, CV_BayerBG2RGB, CV_BayerRG2BGR, CV_BayerGB2RGB, CV_BayerGR2BGR, CV_BayerRG2RGB, CV_BayerBG2BGR, CV_BayerGR2RGB, CV_BayerGB2BGR)
下面列舉了OpenCV庫中的宏定義部分源碼,全部可以參考http://artu819.i.sohu.com/blog/view/89684052.htm:(有60多個呢)
/* Constants for color conversion */
#define  CV_BGR2BGRA    0
#define  CV_RGB2RGBA    CV_BGR2BGRA
#define  CV_BGRA2BGR    1
//...大部分省略
#define  CV_Luv2RGB     59
#define  CV_HLS2BGR     60
#define  CV_HLS2RGB     61      
#define  CV_COLORCVT_MAX  100




cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1,Arr* dst2, CvArr* dst3 );函數對某個顏色空間的多個通道進行分離。用cvMerge( const CvArr* src0, const CvArr* src1,const CvArr* src2, const CvArr* src3, CvArr* dst );函數將幾個單通道圖像合併爲一個多通道圖像。

程序演示
下面簡單演示使用這兩個函數轉換顏色空間(RGB->HSV),然後分離爲單通道圖像,在將兩個單通道圖像合成一個雙通道圖像,可以觀察缺少了某個通道後圖像的變化。用圖像表現,可以更深刻的理解通道和圖像模式
代碼:
#include"cv.h"
#include"cxcore.h"
#include"highgui.h"
using namespace std;
int main(int argc,char **argv)
{
	if(argc>=2)
	{
		IplImage *image,*change,*H,*S,*V,*R,*B,*G,*two,*Zero;
		//創建圖像顯示窗口
		cvNamedWindow("image",CV_WINDOW_AUTOSIZE);
		cvNamedWindow("R",CV_WINDOW_AUTOSIZE);
		cvNamedWindow("G",CV_WINDOW_AUTOSIZE);
		cvNamedWindow("B",CV_WINDOW_AUTOSIZE);
		cvNamedWindow("HS",CV_WINDOW_AUTOSIZE);
		cvNamedWindow("HV",CV_WINDOW_AUTOSIZE);
		cvNamedWindow("VS",CV_WINDOW_AUTOSIZE);
		cvNamedWindow("RG",CV_WINDOW_AUTOSIZE);
		cvNamedWindow("RB",CV_WINDOW_AUTOSIZE);
		cvNamedWindow("BG",CV_WINDOW_AUTOSIZE);
		cvNamedWindow("Zero",CV_WINDOW_AUTOSIZE);

		image=cvLoadImage(argv[1]);//載入圖像

		//分配圖像空間
		change=cvCreateImage(cvSize(image->width,image->height),IPL_DEPTH_8U,3);
		R=cvCreateImage(cvSize(image->width,image->height),IPL_DEPTH_8U,1);
		G=cvCreateImage(cvSize(image->width,image->height),IPL_DEPTH_8U,1);
		B=cvCreateImage(cvSize(image->width,image->height),IPL_DEPTH_8U,1);
		H=cvCreateImage(cvSize(image->width,image->height),IPL_DEPTH_8U,1);
		S=cvCreateImage(cvSize(image->width,image->height),IPL_DEPTH_8U,1);
		V=cvCreateImage(cvSize(image->width,image->height),IPL_DEPTH_8U,1);
		two=cvCreateImage(cvSize(image->width,image->height),IPL_DEPTH_8U,3);
		Zero=cvCreateImage(cvSize(image->width,image->height),IPL_DEPTH_8U,1);

		cvZero(Zero);//在將兩個通道合併是,不能沒有第三個通道,而是將該通道設爲空白,即全0

		cout<<"IPL_DEPTH_8U = "<<IPL_DEPTH_8U<<endl;
		cout<<"CV_RGB2HSV = "<<CV_RGB2HSV<<endl;
		cout<<"CV_HSV2RGB = "<<CV_HSV2RGB<<endl;

		cvCvtColor(image,change,CV_RGB2HSV);  //將RGB色系轉換爲HSV色系
		
		cvSplit(image,R,G,B,0);//分離多通道
		cvSplit(change,H,S,V,0);//分離多通道

		//顯示RGB圖單通道圖
		cvShowImage("image",image);
		cvShowImage("Zero",Zero);
		cvShowImage("R",R);
		cvShowImage("G",G);
		cvShowImage("B",B);


		cvMerge(R,G,Zero,0,two);   //合併兩個圖像空間
		cvShowImage("RG",two);//顯示B通道爲空白時的圖像

		cvMerge(Zero,G,B,0,two);
		cvShowImage("BG",two);
	
		cvMerge(R,Zero,B,0,two);
		cvShowImage("RB",two);

		cvMerge(H,S,Zero,0,two);
		cvCvtColor(two,change,CV_HSV2RGB);//cvShowImage是按照RGB色彩方式顯示圖像的,故要通過RGB色系展示對HSV色系的更改效果
		cvShowImage("HS",change);

		cvMerge(Zero,S,V,0,two);
		cvCvtColor(two,change,CV_HSV2RGB);//cvShowImage是按照RGB色彩方式顯示圖像的,故要通過RGB色系展示對HSV色系的更改效果
		cvShowImage("VS",change);

		cvMerge(H,Zero,V,0,two);
		cvCvtColor(two,change,CV_HSV2RGB);//cvShowImage是按照RGB色彩方式顯示圖像的,故要通過RGB色系展示對HSV色系的更改效果
		cvShowImage("HV",change);

		cvWaitKey(0);

		cvDestroyAllWindows();
		cvReleaseImage(&image);
		cvReleaseImage(&change);
	}
	system("pause");
	return 1;
}

(注意:cvShowImage展示圖像是通過RGB的方式展示的,所以要展示HSV色系的圖像,要先將其變化爲RGB色系再進行展示。一個三通道的圖像,如RGB空間的圖像,"缺少"某個通道,不能是某個通道的沒有爲NULL,而是該通道的元素值都爲0,這裏增加了Zero單通道圖像空間,並用cvZero清空。)

運行效果:
原圖:

1>單通道

可以觀察到,三幅圖像都是黑白的,看上去沒什麼區別(實際上,仔細看,有很多地方不一樣的)

2>RGB某一個通道空白

這個有點奇特,藍色通道空白的圖像偏藍,綠色通道空白的圖像偏紅,紅色通道空白的圖像偏黃,
3>HSV某通道空白

很顯然V亮度爲空,圖像肯定是黑色的了。
                       http://blog.sina.com.cn/s/blog_520a9c1d0100b8hr.html

發佈了26 篇原創文章 · 獲贊 59 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章