在做機器視覺時,常常要將一個多通道圖像分離成幾個單通道圖像或者將幾個單通道圖像合成一個多通道圖像,以方便圖像處理,但是。寫這篇博客,是爲加深對這兩個概念的理解,下面會給出部分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三個通道。除了這兩個三通道圖像模式,以下列舉了還列舉一些圖像模式(來自百度百科圖像模式)
圖像模式:
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)
/* 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 );函數將幾個單通道圖像合併爲一個多通道圖像。
#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清空。)