1. 程式人生 > >顏色空間RGB與HSV(HSL)的轉換

顏色空間RGB與HSV(HSL)的轉換

一般的3D程式設計只需要使用RGB顏色空間就好了,但其實美術人員更多的是使用HSV(HSL),因為可以方便的調整飽和度和亮度。

有時候美術需要程式幫助調整飽和度來達到特定風格的渲染效果,這時候就需要轉換顏色空間了。

HSLHSV(也叫做 HSB)是對RGB 色彩空間中點的兩種有關係的表示,它們嘗試描述比 RGB 更準確的感知顏色聯絡,並仍保持在計算上簡單。HSL 表示 hue(色相)、saturation(飽和度)、lightness(亮度),HSV 表示 hue、saturation、value(色調) 而 HSB 表示 hue、saturation、brightness(明度

)。

HSL 和 HSV 二者都把顏色描述在圓柱體內的點,這個圓柱的中心軸取值為自底部的黑色到頂部的白色而在它們中間是的灰色,繞這個軸的角度對應於“色相”,到這個軸的距離對應於“飽和度”,而沿著這個軸的距離對應於“亮度”,“色調”或“明度”。

這兩種表示在用目的上類似,但在方法上有區別。二者在數學上都是圓柱,但 HSV(色相,飽和度,明度)在概念上可以被認為是顏色的倒圓錐體(黑點在下頂點,白色在上底面圓心),HSL 在概念上表示了一個雙圓錐體和圓球體(白色在上頂點,黑色在下頂點,最大橫切面的圓心是半程灰色)。注意儘管在 HSL 和 HSV 中“色相”指稱相同的性質,它們的“飽和度”的定義是明顯不同的。

因為 HSL 和 HSV 是裝置依賴的 RGB 的簡單變換,(h, s, l) 或 (h, s, v) 三元組定義的顏色依賴於所使用的特定紅色綠色藍色加法原色”。每個獨特的 RGB 裝置都伴隨著一個獨特的 HSL 和 HSV 空間。但是 (h, s, l) 或 (h, s, v) 三元組在被約束於特定 RGB 空間比如 sRGB 的時候就變成明確的了。

HSV 模型在 1978 年由埃爾維·雷·史密斯創立。

動機

藝術家有時偏好使用 HSV 顏色模型而不選擇 RGB CMYK 模型,因為它類似於人類感覺顏色的方式。RGB 和 CMYK 分別是加法原色減法原色模型,以原色組合的方式定義顏色,而 HSV 以人類更熟悉的方式封裝了關於顏色的資訊:“這是什麼顏色?深淺如何?明暗如何?”。HSL 顏色空間類似於 HSV,在某些方面甚至比它還好。

[編輯]用途

HSV 色輪允許使用者快速的選擇眾多顏色。 HSV 模型的圓錐表示適合於在一個單一物體中展示整個 HSV 色彩空間。

HSV 模型通常用於計算機圖形應用中。在使用者必須選擇一個顏色應用於特定圖形元素各種應用環境中,經常使用 HSV 色輪。在其中,色相表示為圓環;可以使用一個獨立的三角形來表示飽和度和明度。典型的,這個三角形的垂直軸指示飽和度,而水平軸表示明度。在這種方式下,選擇顏色可以首先在圓環中選擇色相,在從三角形中選擇想要的飽和度和明度。

HSV 模型的另一種可視方法是圓錐體。在這種表示中,色相被表示為繞圓錐中心軸的角度,飽和度被表示為從圓錐的橫截面的圓心到這個點的距離,明度被表示為從圓錐的橫截面的圓心到頂點的距離。某些表示使用了六稜錐體。這種方法更適合在一個單一物體中展示這個 HSV 色彩空間;但是由於它的三維本質,它不適合在二維計算機介面中選擇顏色。

HSV 色彩空間還可以表示為類似於上述圓錐體的圓柱體,色相沿著圓柱體的外圓周變化,飽和度沿著從橫截面的圓心的距離變化,明度沿著橫截面到底面和頂面的距離而變化。這種表示可能被認為是 HSV 色彩空間的更精確的數學模型;但是在實際中可區分出的飽和度和色相的級別數目隨著明度接近黑色而減少。此外計算機典型的用有限精度範圍來儲存 RGB 值;這約束了精度,再加上人類顏色感知的限制,使圓錐體表示在多數情況下更實用。

[編輯]HSL 與 HSV 的比較

HSL 和 HSV 色彩空間比較。

HSL 類似於 HSV。對於一些人,HSL 更好的反映了“飽和度”和“亮度”作為兩個獨立引數的直覺觀念,但是對於另一些人,它的飽和度定義是錯誤的,因為非常柔和的幾乎白色的顏色在 HSL 可以被定義為是完全飽和的。對於 HSV 還是 HSL 更適合於人類使用者介面是有爭議的。

W3C CSS3 規定聲稱“HSL 的優點是它對稱於亮與暗(HSV 就不是這樣)…”,這意味著:

  • 在 HSL 中,飽和度分量總是從完全飽和色變化到等價的灰色(在 HSV 中,在極大值 V 的時候,飽和度從全飽和色變化到白色,這可以被認為是反直覺的)。
  • 在 HSL 中,亮度跨越從黑色過選擇的色相到白色的完整範圍(在 HSV 中,V 分量只走一半行程,從黑到選擇的色相)。

在軟體中,通常以一個線性或圓形色相選擇器和在其中為選定的色相選取飽和度和明度/亮度的一個二維區域(通常為方形或三角形)形式提供給使用者基於色相的顏色模型(HSV 或 HSL)。通過這種表示,在 HSV 和 HSL 之間的區別就無關緊要了。但是很多程式還允許你通過線性滑塊或數值錄入框來選擇顏色的明度/亮度,而對於這些控制元件通常使用要麼 HSL 要麼 HSV(而非二者)。HSV 傳統上更常用。下面是一些例子:

GIMP 支援在 HSV 色彩空間內的選取顏色的多種方法,包括帶有色相滑塊的色輪和色方。
  • 使用 HSV 和 HSL 二者的應用:

[編輯]與其他顏色模型的比較

HSV 顏色空間在技術上不支援到輻射測定中測量的物理能量譜密度的一一對映。所以一般不建議做在 HSV 座標和物理光性質如波長振幅之間的直接比較。

[編輯]形式定義

HSL 和 HSV 在數學上定義為在 RGB 空間中的顏色的 R, GB 的座標的變換。

[編輯]從 RGB 到 HSL 或 HSV 的轉換

設 (r, g, b) 分別是一個顏色的紅、綠和藍座標,它們的值是在 0 到 1 之間的實數。設 max 等價於 r, gb 中的最大者。設 min 等於這些值中的最小者。要找到在 HSL 空間中的 (h, s, l) 值,這裡的 h ∈ [0, 360)是角度的色相角,而 s, l ∈ [0,1] 是飽和度和亮度,計算為:

h =\begin{cases}0^\circ & \mbox{if } max = min \\60^\circ \times \frac{g - b}{max - min} + 0^\circ,   & \mbox{if } max = r \mbox{ and } g \ge b \\60^\circ \times \frac{g - b}{max - min} + 360^\circ,   & \mbox{if } max = r \mbox{ and } g < b \\60^\circ \times \frac{b - r}{max - min} + 120^\circ, & \mbox{if } max = g \\60^\circ \times \frac{r - g}{max - min} + 240^\circ, & \mbox{if } max = b\end{cases}
l = \begin{matrix} \frac{1}{2} \end{matrix} (max + min)
s = \begin{cases}0 & \mbox{if } l = 0 \mbox{ or } max = min \\\frac{max-min}{max+min} = \frac{max-min}{2l}, & \mbox{if } 0  \frac{1}{2}\end{cases}


h 的值通常規範化到位於 0 到 360°之間。而 h = 0 用於 max = min 的(就是灰色)時候而不是留下 h 未定義。

HSL 和 HSV 有同樣的色相定義,但是其他分量不同。HSV 顏色的 sv 的值定義如下:

s = \begin{cases}0, & \mbox{if } max = 0 \\\frac{max - min}{max} = 1 - \frac{min}{max}, & \mbox{otherwise}\end{cases}
v = max \,

[編輯]從 HSL 到 RGB 的轉換

給定 HSL 空間中的 (h, s, l) 值定義的一個顏色,帶有 h 在指示色相角度的值域 [0, 360)中,分別表示飽和度和亮度的sl 在值域 [0, 1] 中,相應在 RGB 空間中的 (r, g, b) 三原色,帶有分別對應於紅色、綠色和藍色的 r, gb 也在值域 [0, 1] 中,它們可計算為:

首先,如果 s = 0,則結果的顏色是非彩色的、或灰色的。在這個特殊情況,r, gb 都等於 l。注意 h 的值在這種情況下是未定義的。

s ≠ 0 的時候,可以使用下列過程:[1]

q=\begin{cases}l \times (1+s), & \mbox{if } l < \frac{1}{2} \\l+s-(l \times s), & \mbox{if } l \ge \frac{1}{2}\end{cases}
p = 2 \times l - q \,
h_k = {h \over 360} \,h 規範化到值域 [0,1)內)
t_R = h_k+\frac{1}{3} \,
t_G = h_k \,
t_B = h_k-\frac{1}{3} \,
\mbox{if } t_C < 0 \rightarrow t_C = t_C + 1.0 \quad \mbox{for each}\,C \in \{R,G,B\}
\mbox{if } t_C > 1 \rightarrow t_C = t_C - 1.0 \quad \mbox{for each}\,C \in \{R,G,B\}


對於每個顏色向量 Color = (ColorR, ColorG, ColorB) = (r, g, b),

{Color}_C =\begin{cases}p+ \left((q-p) \times 6 \times t_C\right), & \mbox{if } t_C < \frac{1}{6}  \\q, & \mbox{if } \frac{1}{6} \le t_C < \frac{1}{2}  \\p+\left((q-p) \times 6 \times (\frac{2}{3} - t_C) \right), & \mbox{if } \frac{1}{2} \le t_C < \frac{2}{3} \\p, & \mbox{otherwise }\end{cases}
\mbox{for each}\,C \in \{R,G,B\}

[編輯]從 HSV 到 RGB 的轉換

類似的,給定在 HSV 中 (h, s, v) 值定義的一個顏色,帶有如上的 h,和分別表示飽和度和明度的 sv 變化於 0 到 1 之間,在 RGB 空間中對應的 (r, g, b) 三原色可以計算為:

h_i \equiv \left\lfloor \frac{h}{60} \right\rfloor \pmod{6}
f = \frac{h}{60} - h_i
p = v \times (1 - s) \,
q = v \times (1 - f \times s) \,
t = v \times (1 - (1 - f) \times s) \,


對於每個顏色向量 (r, g, b),

(r, g, b) = \begin{cases}(v, t, p), & \mbox{if } h_i = 0  \\(q, v, p), & \mbox{if } h_i = 1  \\(p, v, t), & \mbox{if } h_i = 2  \\(p, q, v), & \mbox{if } h_i = 3  \\(t, p, v), & \mbox{if } h_i = 4  \\(v, p, q), & \mbox{if } h_i = 5  \\\end{cases}

[編輯]例子

展示的 RGB 值的範圍是 0.0 到 1.0。

RGB

HSL

HSV

結果

(1, 0, 0)

(0°, 1, 0.5)

(0°, 1, 1)

(0.5, 1, 0.5)

(120°, 1, 0.75)

(120°, 0.5, 1)

(0, 0, 0.5)

(240°, 1, 0.25)

(240°, 1, 0.5)

HSV顏色空間
HSV(hue,saturation,value)顏色空間的模型對應於圓柱座標系中的一個圓錐形子集,圓錐的頂面對應於V=1。它包含RGB模型中的R=1,G=1,B=1三個面,所代表的顏色較亮。色彩H由繞V軸的旋轉角給定。紅色對應於角度0°,綠色對應於角度120°,藍色對應於角度240°。在HSV顏色模型中,每一種顏色和它的補色相差180°。飽和度S取值從0到1,所以圓錐頂面的半徑為1。HSV顏色模型所代表的顏色域是CIE色度圖的一個子集,這個模型中飽和度為百分之百的顏色,其純度一般小於百分之百。在圓錐的頂點(即原點)處,V=0,H和S無定義,代表黑色。圓錐的頂面中心處S=0,V=1,H無定義,代表白色。從該點到原點代表亮度漸暗的灰色,即具有不同灰度的灰色。對於這些點,S=0,H的值無定義。可以說,HSV模型中的V軸對應於RGB顏色空間中的主對角線。在圓錐頂面的圓周上的顏色,V=1,S=1,這種顏色是純色。HSV模型對應於畫家配色的方法。畫家用改變色濃和色深的方法從某種純色獲得不同色調的顏色,在一種純色中加入白色以改變色濃,加入黑色以改變色深,同時加入不同比例的白色,黑色即可獲得各種不同的色調。

HSV顏色空間可以用一個圓錐空間模型來描述

RGB和HSV顏色空間

從 RGB 到HSV 的轉換

設 (r, g, b) 分別是一個顏色的紅、綠和藍座標,它們的值是在 0 到 1 之間的實數。設 max 等價於 r, gb 中的最大者。設 min 等於這些值中的最小者。要找到在 HSV 空間中的 (h, s, v) 值,這裡的 h ∈ [0, 360)是角度的色相角,而 s, v ∈ [0,1] 是飽和度和亮度,計算為:

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=(max-min)/max

h 的值通常規範化到位於 0 到 360°之間。而 h = 0 用於 max = min 的(就是灰色)時候而不是留下 h 未定義。

以下為相應的VC程式碼:

void Rgb2Hsv(float R, float G, float B, float& H, float& S, float&V)
{
// r,g,b values are from 0 to 1
// h = [0,360], s = [0,1], v = [0,1]
// if s == 0, then h = -1 (undefined)

float min, max, delta,tmp;
tmp = min(R, G);
min = min( tmp, B );
tmp = max( R, G);
max = max(tmp, B );
V = max; // v

delta = max - min;

if( max != 0 )
S = delta / max; // s
else
{
// r = g = b = 0 // s = 0, v is undefined
S = 0;
H = UNDEFINEDCOLOR;
return;
}
if( R == max )
H = ( G - B ) / delta; // between yellow & magenta
else if( G == max )
H = 2 + ( B - R ) / delta; // between cyan & yellow
else
H = 4 + ( R - G ) / delta; // between magenta & cyan

H *= 60; // degrees
if( H < 0 )
H += 360;
}

YUV顏色空間

YUV(亦稱YCrCb)是被歐洲電視系統所採用的一種顏色編碼方法(屬於PAL)。在現代彩色電視系統中,通常採用三管彩色攝影機或彩色CCD攝影機進行取像,然後把取得的彩色影象訊號經分色、分別放大校正後得到RGB,再經過矩陣變換電路得到亮度訊號Y和兩個色差訊號R-Y(即U)、B-Y(即V),最後傳送端將亮度和色差三個訊號分別進行編碼,用同一通道傳送出去。這種色彩的表示方法就是所謂的YUV色彩空間表示。採用YUV色彩空間的重要性是它的亮度訊號Y和色度訊號U、V是分離的。如果只有 Y訊號分量而沒有U、V訊號分量,那麼這樣表示的影象就是黑白灰度影象。彩色電視採用YUV空間正是為了用亮度訊號Y解決彩色電視機與黑白電視機的相容問題,使黑白電視機也能接收彩色電視訊號。

優點作用

  YUV主要用於優化彩色視訊訊號的傳輸,使其向後相容老式黑白電視。與RGB視訊訊號傳輸相比,它最大的優點在於只需佔用極少的頻寬(RGB要求三個獨立的視訊訊號同時傳輸)。其中“Y”表示明亮度(Luminance或Luma),也就是灰階值;而“U”和“V” 表示的則是色度(Chrominance或Chroma),作用是描述影像色彩及飽和度,用於指定畫素的顏色。“亮度”是透過RGB輸入訊號來建立的,方法是將RGB訊號的特定部分疊加到一起。“色度”則定義了顏色的兩個方面─色調與飽和度,分別用Cr和CB來表示。其中,Cr反映了GB輸入訊號紅色部分與RGB訊號亮度值之間的差異。而CB反映的是RGB輸入訊號藍色部分與RGB訊號亮度值之同的差異。

  採用YUV色彩空間的重要性是它的亮度訊號Y和色度訊號U、V是分離的。如果只有Y訊號分量而沒有U、V分量,那麼這樣表示的影象就是黑白灰度影象。彩色電視採用YUV空間正是為了用亮度訊號Y解決彩色電視機與黑白電視機的相容問題,使黑白電視機也能接收彩色電視訊號。

  YUV與RGB相互轉換的公式如下(RGB取值範圍均為0-255)︰
  Y = 0.299R + 0.587G + 0.114B
  U = -0.147R - 0.289G + 0.436B
  V = 0.615R - 0.515G - 0.100B
  R = Y + 1.14V
  G = Y - 0.39U - 0.58V
  B = Y + 2.03U