天天看點

RGB與HSV等的轉換

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

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

出處:http://zh.wikipedia.org/wiki/HSL%E5%92%8CHSV%E8%89%B2%E5%BD%A9%E7%A9%BA%E9%97%B4

HSL 和 HSV(也叫做 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,在某些方面甚至比它還好。

[編輯]用途

RGB與HSV等的轉換
RGB與HSV等的轉換

HSV 色輪允許使用者快速的選擇衆多顔色。

RGB與HSV等的轉換
RGB與HSV等的轉換

HSV 模型的圓錐表示适合于在一個單一物體中展示整個 HSV 色彩空間。

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

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

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

[編輯]HSL 與 HSV 的比較

RGB與HSV等的轉換
RGB與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 傳統上更常用。下面是一些例子:

RGB與HSV等的轉換
RGB與HSV等的轉換

GIMP 支援在 HSV 色彩空間内的選取顔色的多種方法,包括帶有色相滑塊的色輪和色方。

  • 使用 HSV (HSB)的應用:
    • Apple Mac OS X 系統顔色選擇器(有一個 H/S 顔色碟和一個 V 滑塊)
    • Xara Xtreme
    • Paint.NET(有一個 H/S 顔色碟和一個 V 滑塊)
    • Adobe 圖形應用程式(Illustrator,Photoshop,等等)
    • Turbo Photo
  • 使用 HSL 的應用:
    • CSS3 規定
    • Inkscape(從版本 0.42 開始)
    • Macromedia Studio
    • Microsoft Windows 系統顔色選擇器(包括 Microsoft Paint)
    • Paint Shop Pro
    • ImageMagick
  • 使用 HSV 和 HSL 二者的應用:
    • Pixel image editor(從 Beta5 開始)
    • Pixia
    • Bryce
    • GIMP(HSV 用于顔色選擇,HSL 用于顔色調整)

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

HSV 顔色空間在技術上不支援到輻射測定中測量的實體能量譜密度的一一映射。是以一般不建議做在 HSV 坐标和實體光性質如波長和振幅之間的直接比較。

[編輯]形式定義

HSL 和 HSV 在數學上定義為在 RGB 空間中的顔色的 R, G 和 B 的坐标的變換。

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

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

RGB與HSV等的轉換
RGB與HSV等的轉換
RGB與HSV等的轉換

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

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

RGB與HSV等的轉換
RGB與HSV等的轉換

[編輯]從 HSL 到 RGB 的轉換

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

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

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

RGB與HSV等的轉換
RGB與HSV等的轉換
RGB與HSV等的轉換
( h 規範化到值域 [0,1)内)
RGB與HSV等的轉換
RGB與HSV等的轉換
RGB與HSV等的轉換
RGB與HSV等的轉換
RGB與HSV等的轉換

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

RGB與HSV等的轉換
RGB與HSV等的轉換

[編輯]從 HSV 到 RGB 的轉換

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

RGB與HSV等的轉換
RGB與HSV等的轉換
RGB與HSV等的轉換
RGB與HSV等的轉換
RGB與HSV等的轉換

對于每個顔色向量 (r, g, b),

RGB與HSV等的轉換

[編輯]例子

展示的 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, g 和 b 中的最大者。設 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