OpenCV 的cvtColor()函數--------彩色空間轉換


opencv 提供了cvtColor()函數,用於在圖像中不同的色彩空間進行轉換,用於后續處理。在使用cvtColor之前首先需要了解下基本的圖像色彩模式,色彩模式決定了打印或顯示的圖片顏色。

圖像色彩模式

  位圖模式

  位圖模式是圖像中最基本的格式,圖像只有黑色和白色像素,是色彩模式中占有空間最小的,同樣也叫做黑白圖,它包含的信息量最少,無法包含圖像中的細節,相當於只有0或者1

一副彩色圖如果要轉換成黑白模式,則一般不能直接轉換,需要首先將圖像轉換成灰度模式

  灰度模式


  灰度模式即使用單一色調來表示圖像,與位圖模式不同,不像位圖只有0和1,使用256級的灰度來表示圖像,一個像素相當於占用8為一個字節,每個像素值使用0到255的亮度值代表,其中0為黑色,255為白色,相當於從黑->灰->白的過度,通常我們所說的黑白照片就是這種模式,與位圖模式相比,能表現出一定的細節,占用空間也比位圖模式較大

  RGB模式


  RGB模式為我們經常見到的,被稱為真色彩。RGB模式的圖像有3個顏色通道,分布為紅(Red),綠(Green)和藍(Bule),每個都占用8位一個字節來表示顏色信息,這樣每個顏色的取值范圍為0~255,那么就三種顏色就可以有多種組合,

當三種基色的值相等是,表現出為灰色,三種顏色都為255即為白色,三種顏色都為0,即為黑色

 

  RGB模式的圖像占用空間要比位圖,灰度圖都要大,但表現出的細節更加明顯

  CMYK模式


  CMYK模式被稱為印刷色彩模式,主要是來源於印刷行業,以打印油墨在紙張上的光線吸收特性為基礎,與RGB類似,也是使用三種顏色,分別為青色(Cyan),品紅色(Magenta),黃色(Yellow),以及黑色(Black)

與RGB不同的是:RGB模式依靠的是自身發光的色彩模式,而CMYK是一種依靠反光的色彩模式。

 

  HSB模式


  是根據日常生活中人眼的視覺對色彩的觀察得而制定的一套色彩模式,最接近與人類對色彩的辨認的思考方式,所有的顏色都是用色彩三屬性來描述

    H:(色相):是指從物體反射或透過物體傳播的顏色

    S:(飽和度):是指顏色的強度或純度,表示色相中灰色成分所占的比例

    B:(亮度):是指顏色對相對明暗程度,通常 100%定義為白色;0%為黑色

  除了上述以上之外,還有索引模式,多通道模式等等不再介紹

YUV格式
  除了上述圖像模式之外,由於歷史原因大部分攝像頭輸入的圖片格式都是YUV格式,開始主要用於電視系統以及模擬視頻領域。YUV,分為三個分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的則是色度(Chrominance或Chroma),作用是描述影像色彩及飽和度,用於指定像素的顏色。如果沒用UV信息,只有Y信息,也可以進行成像不過只是黑白的,這樣就能很好解決彩色電視與黑白電視的兼容問題,與RGB相比,YUV占用帶寬較少,目前攝像頭輸出格式普遍采用YUV格式。

  而在圖像的處理過程中,其實很少使用YUV格式,一般都需要轉成RGB格式或者灰度圖格式進行轉換,而opencv的cvtColor()函數支持這種轉換

cvtColor


opencv的C++代碼如下:

int main(int argc,char** argc){ 
  Mat img = imread("D:/Learn/OpenCVStudy/1c.jpg");   if (img.empty())   {   cout << "加載失敗" << endl;   return -1;   }   Mat rgb, hsv; cvtColor(src, rgb, CV_RGB2BGRA); cvtColor(src, hsv, CV_RGB2HSV); imshow("Pic1", rgb); imshow("Pic2", hsv);   imshow("Pic", img);   waitKey(0);//程序停頓一下,0表示一直停滯,1表示1ms   cvDestroyAllWindows();//銷毀以上所有程序
  return 0;
}

 

讀取到的彩色圖

 

 

 

轉換成的灰度圖:

 

 

 轉換成的CV_RGB2HSV圖:

 

 

注意使用cvtColor RGB轉成其他格式時,需要注意RGB圖像的三個通道的順序,是RGB還是BGR.大部分情況下opencv為RGB,但實際上是BGR,這一點需要注意。

需要注意各個值的范圍:

CV_8U圖像 其通道值范圍為0到255

CV_16U時其值通道值范圍為0到65535

CV_32F時,其通道值范圍為0到1

在線性轉換時,其范圍沒有較大關系,但是如果是非線性轉換,RGB圖像需要做正確的歸一化,以擴展到響應的范圍。例如TGB->L*U*V轉換,如果32位的浮點圖像之間是由8位的圖像轉換而來,那么將0到255的范圍轉換成0,1,那么轉換之前首先需要需要所需其圖像

img *= 1./255;
cvtColor(img, img, COLOR_BGR2Luv);
如果之間使用cvtColor進行轉換,將會丟掉一些信息

cvtColor Code
opencv cvtcolor支持的空間轉發code,如下,基本能夠滿足日常需要

  1 enum cv::ColorConversionCodes {
  2 cv::COLOR_BGR2BGRA = 0,
  3 cv::COLOR_RGB2RGBA = COLOR_BGR2BGRA,
  4 cv::COLOR_BGRA2BGR = 1,
  5 cv::COLOR_RGBA2RGB = COLOR_BGRA2BGR,
  6 cv::COLOR_BGR2RGBA = 2,
  7 cv::COLOR_RGB2BGRA = COLOR_BGR2RGBA,
  8 cv::COLOR_RGBA2BGR = 3,
  9 cv::COLOR_BGRA2RGB = COLOR_RGBA2BGR,
 10 cv::COLOR_BGR2RGB = 4,
 11 cv::COLOR_RGB2BGR = COLOR_BGR2RGB,
 12 cv::COLOR_BGRA2RGBA = 5,
 13 cv::COLOR_RGBA2BGRA = COLOR_BGRA2RGBA,
 14 cv::COLOR_BGR2GRAY = 6,
 15 cv::COLOR_RGB2GRAY = 7,
 16 cv::COLOR_GRAY2BGR = 8,
 17 cv::COLOR_GRAY2RGB = COLOR_GRAY2BGR,
 18 cv::COLOR_GRAY2BGRA = 9,
 19 cv::COLOR_GRAY2RGBA = COLOR_GRAY2BGRA,
 20 cv::COLOR_BGRA2GRAY = 10,
 21 cv::COLOR_RGBA2GRAY = 11,
 22 cv::COLOR_BGR2BGR565 = 12,
 23 cv::COLOR_RGB2BGR565 = 13,
 24 cv::COLOR_BGR5652BGR = 14,
 25 cv::COLOR_BGR5652RGB = 15,
 26 cv::COLOR_BGRA2BGR565 = 16,
 27 cv::COLOR_RGBA2BGR565 = 17,
 28 cv::COLOR_BGR5652BGRA = 18,
 29 cv::COLOR_BGR5652RGBA = 19,
 30 cv::COLOR_GRAY2BGR565 = 20,
 31 cv::COLOR_BGR5652GRAY = 21,
 32 cv::COLOR_BGR2BGR555 = 22,
 33 cv::COLOR_RGB2BGR555 = 23,
 34 cv::COLOR_BGR5552BGR = 24,
 35 cv::COLOR_BGR5552RGB = 25,
 36 cv::COLOR_BGRA2BGR555 = 26,
 37 cv::COLOR_RGBA2BGR555 = 27,
 38 cv::COLOR_BGR5552BGRA = 28,
 39 cv::COLOR_BGR5552RGBA = 29,
 40 cv::COLOR_GRAY2BGR555 = 30,
 41 cv::COLOR_BGR5552GRAY = 31,
 42 cv::COLOR_BGR2XYZ = 32,
 43 cv::COLOR_RGB2XYZ = 33,
 44 cv::COLOR_XYZ2BGR = 34,
 45 cv::COLOR_XYZ2RGB = 35,
 46 cv::COLOR_BGR2YCrCb = 36,
 47 cv::COLOR_RGB2YCrCb = 37,
 48 cv::COLOR_YCrCb2BGR = 38,
 49 cv::COLOR_YCrCb2RGB = 39,
 50 cv::COLOR_BGR2HSV = 40,
 51 cv::COLOR_RGB2HSV = 41,
 52 cv::COLOR_BGR2Lab = 44,
 53 cv::COLOR_RGB2Lab = 45,
 54 cv::COLOR_BGR2Luv = 50,
 55 cv::COLOR_RGB2Luv = 51,
 56 cv::COLOR_BGR2HLS = 52,
 57 cv::COLOR_RGB2HLS = 53,
 58 cv::COLOR_HSV2BGR = 54,
 59 cv::COLOR_HSV2RGB = 55,
 60 cv::COLOR_Lab2BGR = 56,
 61 cv::COLOR_Lab2RGB = 57,
 62 cv::COLOR_Luv2BGR = 58,
 63 cv::COLOR_Luv2RGB = 59,
 64 cv::COLOR_HLS2BGR = 60,
 65 cv::COLOR_HLS2RGB = 61,
 66 cv::COLOR_BGR2HSV_FULL = 66,
 67 cv::COLOR_RGB2HSV_FULL = 67,
 68 cv::COLOR_BGR2HLS_FULL = 68,
 69 cv::COLOR_RGB2HLS_FULL = 69,
 70 cv::COLOR_HSV2BGR_FULL = 70,
 71 cv::COLOR_HSV2RGB_FULL = 71,
 72 cv::COLOR_HLS2BGR_FULL = 72,
 73 cv::COLOR_HLS2RGB_FULL = 73,
 74 cv::COLOR_LBGR2Lab = 74,
 75 cv::COLOR_LRGB2Lab = 75,
 76 cv::COLOR_LBGR2Luv = 76,
 77 cv::COLOR_LRGB2Luv = 77,
 78 cv::COLOR_Lab2LBGR = 78,
 79 cv::COLOR_Lab2LRGB = 79,
 80 cv::COLOR_Luv2LBGR = 80,
 81 cv::COLOR_Luv2LRGB = 81,
 82 cv::COLOR_BGR2YUV = 82,
 83 cv::COLOR_RGB2YUV = 83,
 84 cv::COLOR_YUV2BGR = 84,
 85 cv::COLOR_YUV2RGB = 85,
 86 cv::COLOR_YUV2RGB_NV12 = 90,
 87 cv::COLOR_YUV2BGR_NV12 = 91,
 88 cv::COLOR_YUV2RGB_NV21 = 92,
 89 cv::COLOR_YUV2BGR_NV21 = 93,
 90 cv::COLOR_YUV420sp2RGB = COLOR_YUV2RGB_NV21,
 91 cv::COLOR_YUV420sp2BGR = COLOR_YUV2BGR_NV21,
 92 cv::COLOR_YUV2RGBA_NV12 = 94,
 93 cv::COLOR_YUV2BGRA_NV12 = 95,
 94 cv::COLOR_YUV2RGBA_NV21 = 96,
 95 cv::COLOR_YUV2BGRA_NV21 = 97,
 96 cv::COLOR_YUV420sp2RGBA = COLOR_YUV2RGBA_NV21,
 97 cv::COLOR_YUV420sp2BGRA = COLOR_YUV2BGRA_NV21,
 98 cv::COLOR_YUV2RGB_YV12 = 98,
 99 cv::COLOR_YUV2BGR_YV12 = 99,
100 cv::COLOR_YUV2RGB_IYUV = 100,
101 cv::COLOR_YUV2BGR_IYUV = 101,
102 cv::COLOR_YUV2RGB_I420 = COLOR_YUV2RGB_IYUV,
103 cv::COLOR_YUV2BGR_I420 = COLOR_YUV2BGR_IYUV,
104 cv::COLOR_YUV420p2RGB = COLOR_YUV2RGB_YV12,
105 cv::COLOR_YUV420p2BGR = COLOR_YUV2BGR_YV12,
106 cv::COLOR_YUV2RGBA_YV12 = 102,
107 cv::COLOR_YUV2BGRA_YV12 = 103,
108 cv::COLOR_YUV2RGBA_IYUV = 104,
109 cv::COLOR_YUV2BGRA_IYUV = 105,
110 cv::COLOR_YUV2RGBA_I420 = COLOR_YUV2RGBA_IYUV,
111 cv::COLOR_YUV2BGRA_I420 = COLOR_YUV2BGRA_IYUV,
112 cv::COLOR_YUV420p2RGBA = COLOR_YUV2RGBA_YV12,
113 cv::COLOR_YUV420p2BGRA = COLOR_YUV2BGRA_YV12,
114 cv::COLOR_YUV2GRAY_420 = 106,
115 cv::COLOR_YUV2GRAY_NV21 = COLOR_YUV2GRAY_420,
116 cv::COLOR_YUV2GRAY_NV12 = COLOR_YUV2GRAY_420,
117 cv::COLOR_YUV2GRAY_YV12 = COLOR_YUV2GRAY_420,
118 cv::COLOR_YUV2GRAY_IYUV = COLOR_YUV2GRAY_420,
119 cv::COLOR_YUV2GRAY_I420 = COLOR_YUV2GRAY_420,
120 cv::COLOR_YUV420sp2GRAY = COLOR_YUV2GRAY_420,
121 cv::COLOR_YUV420p2GRAY = COLOR_YUV2GRAY_420,
122 cv::COLOR_YUV2RGB_UYVY = 107,
123 cv::COLOR_YUV2BGR_UYVY = 108,
124 cv::COLOR_YUV2RGB_Y422 = COLOR_YUV2RGB_UYVY,
125 cv::COLOR_YUV2BGR_Y422 = COLOR_YUV2BGR_UYVY,
126 cv::COLOR_YUV2RGB_UYNV = COLOR_YUV2RGB_UYVY,
127 cv::COLOR_YUV2BGR_UYNV = COLOR_YUV2BGR_UYVY,
128 cv::COLOR_YUV2RGBA_UYVY = 111,
129 cv::COLOR_YUV2BGRA_UYVY = 112,
130 cv::COLOR_YUV2RGBA_Y422 = COLOR_YUV2RGBA_UYVY,
131 cv::COLOR_YUV2BGRA_Y422 = COLOR_YUV2BGRA_UYVY,
132 cv::COLOR_YUV2RGBA_UYNV = COLOR_YUV2RGBA_UYVY,
133 cv::COLOR_YUV2BGRA_UYNV = COLOR_YUV2BGRA_UYVY,
134 cv::COLOR_YUV2RGB_YUY2 = 115,
135 cv::COLOR_YUV2BGR_YUY2 = 116,
136 cv::COLOR_YUV2RGB_YVYU = 117,
137 cv::COLOR_YUV2BGR_YVYU = 118,
138 cv::COLOR_YUV2RGB_YUYV = COLOR_YUV2RGB_YUY2,
139 cv::COLOR_YUV2BGR_YUYV = COLOR_YUV2BGR_YUY2,
140 cv::COLOR_YUV2RGB_YUNV = COLOR_YUV2RGB_YUY2,
141 cv::COLOR_YUV2BGR_YUNV = COLOR_YUV2BGR_YUY2,
142 cv::COLOR_YUV2RGBA_YUY2 = 119,
143 cv::COLOR_YUV2BGRA_YUY2 = 120,
144 cv::COLOR_YUV2RGBA_YVYU = 121,
145 cv::COLOR_YUV2BGRA_YVYU = 122,
146 cv::COLOR_YUV2RGBA_YUYV = COLOR_YUV2RGBA_YUY2,
147 cv::COLOR_YUV2BGRA_YUYV = COLOR_YUV2BGRA_YUY2,
148 cv::COLOR_YUV2RGBA_YUNV = COLOR_YUV2RGBA_YUY2,
149 cv::COLOR_YUV2BGRA_YUNV = COLOR_YUV2BGRA_YUY2,
150 cv::COLOR_YUV2GRAY_UYVY = 123,
151 cv::COLOR_YUV2GRAY_YUY2 = 124,
152 cv::COLOR_YUV2GRAY_Y422 = COLOR_YUV2GRAY_UYVY,
153 cv::COLOR_YUV2GRAY_UYNV = COLOR_YUV2GRAY_UYVY,
154 cv::COLOR_YUV2GRAY_YVYU = COLOR_YUV2GRAY_YUY2,
155 cv::COLOR_YUV2GRAY_YUYV = COLOR_YUV2GRAY_YUY2,
156 cv::COLOR_YUV2GRAY_YUNV = COLOR_YUV2GRAY_YUY2,
157 cv::COLOR_RGBA2mRGBA = 125,
158 cv::COLOR_mRGBA2RGBA = 126,
159 cv::COLOR_RGB2YUV_I420 = 127,
160 cv::COLOR_BGR2YUV_I420 = 128,
161 cv::COLOR_RGB2YUV_IYUV = COLOR_RGB2YUV_I420,
162 cv::COLOR_BGR2YUV_IYUV = COLOR_BGR2YUV_I420,
163 cv::COLOR_RGBA2YUV_I420 = 129,
164 cv::COLOR_BGRA2YUV_I420 = 130,
165 cv::COLOR_RGBA2YUV_IYUV = COLOR_RGBA2YUV_I420,
166 cv::COLOR_BGRA2YUV_IYUV = COLOR_BGRA2YUV_I420,
167 cv::COLOR_RGB2YUV_YV12 = 131,
168 cv::COLOR_BGR2YUV_YV12 = 132,
169 cv::COLOR_RGBA2YUV_YV12 = 133,
170 cv::COLOR_BGRA2YUV_YV12 = 134,
171 cv::COLOR_BayerBG2BGR = 46,
172 cv::COLOR_BayerGB2BGR = 47,
173 cv::COLOR_BayerRG2BGR = 48,
174 cv::COLOR_BayerGR2BGR = 49,
175 cv::COLOR_BayerBG2RGB = COLOR_BayerRG2BGR,
176 cv::COLOR_BayerGB2RGB = COLOR_BayerGR2BGR,
177 cv::COLOR_BayerRG2RGB = COLOR_BayerBG2BGR,
178 cv::COLOR_BayerGR2RGB = COLOR_BayerGB2BGR,
179 cv::COLOR_BayerBG2GRAY = 86,
180 cv::COLOR_BayerGB2GRAY = 87,
181 cv::COLOR_BayerRG2GRAY = 88,
182 cv::COLOR_BayerGR2GRAY = 89,
183 cv::COLOR_BayerBG2BGR_VNG = 62,
184 cv::COLOR_BayerGB2BGR_VNG = 63,
185 cv::COLOR_BayerRG2BGR_VNG = 64,
186 cv::COLOR_BayerGR2BGR_VNG = 65,
187 cv::COLOR_BayerBG2RGB_VNG = COLOR_BayerRG2BGR_VNG,
188 cv::COLOR_BayerGB2RGB_VNG = COLOR_BayerGR2BGR_VNG,
189 cv::COLOR_BayerRG2RGB_VNG = COLOR_BayerBG2BGR_VNG,
190 cv::COLOR_BayerGR2RGB_VNG = COLOR_BayerGB2BGR_VNG,
191 cv::COLOR_BayerBG2BGR_EA = 135,
192 cv::COLOR_BayerGB2BGR_EA = 136,
193 cv::COLOR_BayerRG2BGR_EA = 137,
194 cv::COLOR_BayerGR2BGR_EA = 138,
195 cv::COLOR_BayerBG2RGB_EA = COLOR_BayerRG2BGR_EA,
196 cv::COLOR_BayerGB2RGB_EA = COLOR_BayerGR2BGR_EA,
197 cv::COLOR_BayerRG2RGB_EA = COLOR_BayerBG2BGR_EA,
198 cv::COLOR_BayerGR2RGB_EA = COLOR_BayerGB2BGR_EA,
199 cv::COLOR_BayerBG2BGRA = 139,
200 cv::COLOR_BayerGB2BGRA = 140,
201 cv::COLOR_BayerRG2BGRA = 141,
202 cv::COLOR_BayerGR2BGRA = 142,
203 cv::COLOR_BayerBG2RGBA = COLOR_BayerRG2BGRA,
204 cv::COLOR_BayerGB2RGBA = COLOR_BayerGR2BGRA,
205 cv::COLOR_BayerRG2RGBA = COLOR_BayerBG2BGRA,
206 cv::COLOR_BayerGR2RGBA = COLOR_BayerGB2BGRA,
207 cv::COLOR_COLORCVT_MAX = 143
208 }

顏色模型CV_BGR2HSV

opencv函數cvCvtColor(rgb_im,hsv_im,CV_BGR2HSV)中使用的RGB顏色空間轉到HSV算法:

      max=max(R,G,B)

  min=min(R,G,B)

  if R = max, H = (G-B)/(max-min)

  if G = max, H = 2 + (B-R)/(max-min)

  if B = max, H = 4 + (R-G)/(max-min)

  H = H * 60

  if H < 0, H = H + 360

   V=max(R,G,B)

  S=(V-min)/V,ifV=0,S=0,(對於8bit雖然幫助文檔上如是寫S=(V-min)*255/V,但實測S:0~1)

  因此,對於8bit圖像可直接輸入,根據該算法所得結果中:范圍H:0~360,S:0~1,V:0~255,

圖像精度轉換cvConvertScale()

  通常我們獲取的圖像深的為IPL_DEPTH_8U,而上述hsv_im已超出該范圍。因此我們定義hsv_im的深度為IPL_DEPTH_32F,而源圖像為IPL_DEPTH_8U,如果直接調用函數cvCvtColor會出項輸入不匹配的錯處,因此要將源圖像轉換到IPL_DEPTH_32F深度,並歸一化像素值。這一步使用cvConvertScale(hsv_im,hsv_im_float,1/255),然后調用cvCvtColor(hsv_im_float,hsv_im,CV_BGR2HSV)即可得到正確的HSV值,但HSV值與matlab有一定誤差,原因不明。
 
    cvtColor(temp,tempGray,CV_BGR2GRAY);  


免責聲明!

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



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