通過Photoshop的拾色器,我們知道表征顏色的模型的不止一種,本文將系統並且詳細討論這四種模型(HSV、LAB、RGB和CMYK)之間的聯系以及應用。
本文部分章節整合了多位優秀博主的博客(鏈接見本文末尾),並對其表示感謝。文章中模型轉換使用的是C式偽代碼而不是數學公式,這樣更便於編程人士理解。

圖1.Photoshop cc的拾色器
數字圖像處理中,最常用的使用也是最容易理解的是RGB模型,常用於顏色顯示和圖像處理,是三維坐標的模型形式。
下面先介紹RGB模型(圖1),該模型可以使用vec3(r, g, b)表示,相當於三維直角坐標系,x、y、z軸相當於紅、綠、藍三通道,原點vec3(0.0, 0.0, 0.0)代表黑色,頂點vec3(1.0, 1.0, 1.0)代表白色,原點到頂點的中軸線x = y = z代表灰度線。
圖2.RGB模型
用RGB模型表征色彩、深淺、明暗變化的方法是:
-
色彩變化:三個軸RGB的最大分量頂點與黃紫青(YMC)色頂點的連線;
-
深淺變化:RGB頂點與CMY頂點到中軸線(原點和頂點的連線)的距離;
-
明暗變化:中軸線上的點的位置。離遠點近偏暗,反之偏亮。
自然界中7色光都是單色光,都有自己獨特的光譜特征。之所以使用RGB能混合成其他顏色的光,是因為人類的感官系統導致的,與人類的生理系統有關。可以說:將RGB以不同的比例混合后,人的眼睛可以形成與其他各種頻率的可見光等效的色覺,所以才采用RGB作為三原色。
通過對RGB模型的講解,我們了解到雖然RGB用來表示顏色方便,但相近的兩個顏色其值相差可能較大。可以說RGB模型適用於計算機表示,而接下來講解的HSV模型(Hue色相、Saturation飽和度、Value/Brightness亮度,也叫HSB)模型更適合人類習慣。
HSV模型可以使用倒錐形模型表示(圖2)。模型中H表示色彩信息,即光譜顏色所在的位置,該參數用角度來表示,紅、綠、藍分別相隔120°,互補色(CMY)分別相差180°。純度S是一個比例值,范圍[0, 1],表示所選顏色的純度和該顏色最大的純度之間的比率,當S = 0時,代表灰度。V表示色彩的明亮程度,范圍[0, 1],與光強度無直接關系。
圖4.HSV模型
圖5.HSV模型解析
HSV對人類來說是一種最直觀的顏色模型,我們指定彩色角H,並使V = S = 1.0,然后通過添加黑色或者白色得到目標顏色。增加黑色可以減小V而S不變,這樣減小了該顏色亮度;同樣增加白色可以減小S而V不變,這樣增加了顏色亮度。例如深藍色(240°, 1.0, 0.4),淺藍色(240°, 0.4, 1.0)[百度百科]。
一般的,人的眼睛最大能區分128種色彩,130種飽和度和23種明暗度。若僅使用16bits表示HSV值的話,可用7位存放H,4位存放S,5位存放V,即H7S4V5或者H6S5V5就能滿足需求。
HSV可用於顏色分割:用H和S表示顏色距離。Androutsos等人同過實驗,對HSV顏色空間模型進行大致划分,V > 75% && S > 20%為亮彩色區域,V < 25%為黑色區域,V > 75% && S < 20%為白色區域,其他為彩色區域。對於不同的彩色區域,混合H與S變量,根據划定的閾值就可以進行簡單的顏色分割。
《Improving shadow suppression in moving object detection with HSV color information》(基於HSV的去陰影算法)
HSV模型不適合在使用光照的模型中,大部分光線混合運算、光強度運算都無法直接使用HSV模型來實現。
RGB與HSV模型互轉(偽代碼表示)
取值范圍:
R, G, B: [0.0, 1.0] // RGB 0 - 255
H: [0, 2π] // H: [0, 360]
S, V: [0.0, 1.0] // S、V: [0, 100]%
1.RGB to HSV:
float maxValue = max(R, G, B); float minValue = min(R, G, B); V = maxValue; S = (V != 0) ? 1.0 - minValue / maxValue : 0.0; if (maxValue == minValue) // undefined, throw error or return valid value. if (R == maxValue && G >= B) H = π/3 * (G - B) / (maxValue - minValue) + 0; // H = 60 * (G - B) / (maxValue - minValue) + 0; if (R == maxValue && G < B) H = π/3 * (G - B) / (maxValue - minValue) + 2π; // H = 60 * (G - B) / (maxValue - minValue) + 360; if (G == maxValue) H = π/3 * (B - R) / (maxValue - minValue) + 2π/3; // H = 60 * (G - B) / (maxValue - minValue) + 120; if (B == maxValue) H = π/3 * (R - G) / (maxValue - minValue) + 4π/3; // H = 60 * (G - B) / (maxValue - minValue) + 240;
2. HSV to RGB
hi = mod(floor(H / (π/3)), 6); // hi = floor( H / 60° ) mod 6 f = H / (π/3) - hi; // H = 60 * (G - B) / (maxValue - minValue) + 0; p = V * (1 - S); q = V * (1 - f * S); t = V * (1 - (1 - f) * S); switch (hi) case 0: R = V; G = t; B = p; break; // (R, G, B) = (V, t, p) case 1: R = q; G = V; B = p; break; // (R, G, B) = (q, V, p) case 2: R = p; G = V; B = t; break; // (R, G, B) = (p, V, t) case 3: R = p; G = q; B = V; break; // (R, G, B) = (p, q, V) case 4: R = t; G = p; B = V; break; // (R, G, B) = (t, p, V) case 5: R = V; G = p; B = q; break; // (R, G, B) = (V, p, q)
第三個我們要介紹的是Lab模型,該模型是基於人對顏色的感覺,描述的是顏色的顯示方式,而非顯示設備生成顏色所需要的特定色料的數量,故Lab也被視為設備無關的顏色模型。
Lab色彩模型是由亮度(L,Luminosity)和有關色彩的a、b三個要素組成。a表示從洋紅色到綠色的范圍,b表示由黃色到藍色的范圍。L取值[0, 100],當L = 50時,相當於50%的黑。a、b的值域都是[-128, 127]。當x = -128時,a是綠色,b是藍色;當x漸漸過渡到127時,a漸漸變成了洋紅色,b漸漸變成了黃色。所有的顏色可以由這3個值交互變化組成。例如,當Lab取值為(100, 30, 0)時,色彩表現為粉紅色。
Lab模式中,a軸和b軸與RGB模型相比,洋紅色更加偏紅,綠色更加偏青,黃色略帶紅色,藍色略偏青色。
圖6.Lab顏色模型
Lab模型具有不依賴設備的優點,除此之外,它還具有寬闊的色域優勢。色域范圍內不僅包含了RGB、CMYK的所有色域,還能表示他們不能表現的色彩。人類能感知的色彩,都能通過Lab模型表現出來。另外,Lab色彩模型彌補了RGB色彩模型中分布不均勻的不足,在RGB模型中藍色到綠色之間過度的色彩多,而綠色到紅色之間缺少黃色和其他色彩。所以,如果想在數字圖像處理中保留寬闊的色域和豐富的色彩,最好選擇Lab模型。
1.RGB模型到Lab色彩空間的轉換
RGB無法直接轉成Lab,需要先轉換成XYZ再轉成Lab,因此轉換需要兩個步驟:
R、G、B: [0.0, 1.0] // 0 - 255
L: [0, 100]
a、b: [-128, 127]
(1)RGB轉成XYZ
R = gamma(R);
G = gamma(G);
B = gamma(B);
float gamma(float x) { if (x > 0.04045) { return pow((x + 0.055) / 1.055, 2.4); } else { return x / 12.92; } }
mat3x1(X, Y, Z) = mat3(M) * mat3x1(R, G, B);
其中 0.436052025 0.385081593 0.143087414
[M] = [ 0.222491598 0.716886060 0.060621486 ]
0.013929122 0.097097002 0.714185470
gamma函數是用來對圖像進行非線性色調調整的,目的是提高圖像的對比度。該函數並不唯一,本文給出的值被廣泛應用於大多數。
(2)XYZ轉Lab
L = 116 * f(Y / Yn) - 16;
a = 500 * (f(X/ Xn) - f(Y / Yn));
b = 200 * (f(Y / Yn) - f(Z / Zn));
float f(float t) { if (t > pow(6.0 / 29.0, 3)) { return pow(t, 1.0 / 3.0); } else { return 1.0 / 3.0 * pow(29.0 / 6.0, 2.0) * t + 4.0 / 29.0; } }
其中Xn、Yn、Zn一般默認為1。
最后,本文介紹CMYK色彩模式,該模式是以打印油墨在紙張上的光線吸收特性為基礎,圖像中每個像素都是由靛青(C)、品紅(M)、黃(Y)和黑(K)按照不同比例組成。每個像素的每種印刷油墨會被分配一個百分比例,最亮的顏色分配較低的印刷油墨顏色百分比,較暗的顏色分配較高的百分比。例如,明亮的紅色可能會是(0.02, 0.93, 0.9, 0)。(0, 0, 0, 0)會產生純白色。
R、G、B: [0.0, 1.0] // 0 - 255
C、M、Y、K: [0.0, 1.0] // 0% - 100%
由CMYK轉換成RGB的公式:
R = (1.0 - C) * (1.0 - K)
G = (1.0 - M) * (1.0 - K)
B = (1.0 - Y) * (1.0 - K)
參考鏈接:
http://baike.baidu.com/view/1139658.htm (顏色模式)
http://baike.baidu.com/view/974298.htm (色彩空間)
http://zhuanlan.zhihu.com/lianghai/19652492
http://blog.csdn.net/viewcode/article/details/8203728
http://blog.csdn.net/xoyojank/article/details/2686980
http://blog.sina.com.cn/s/blog_48a45b950100i196.html
http://blog.csdn.net/bagboy_taobao_com/article/details/5535245
http://www.cnblogs.com/hrlnw/p/4126017.html(RGB轉LAB色彩空間)
http://dqzx.neuq.edu.cn/bbs/forum.php?mod=viewthread&tid=11967&page=1
http://www.cnblogs.com/skyseraph/archive/2011/05/03/2035643.html





