1. 程式人生 > >RGB顏色空間與Lab顏色空間區別與聯絡(附轉換程式碼)

RGB顏色空間與Lab顏色空間區別與聯絡(附轉換程式碼)

RGB顏色空間

RGB顏色是紅色(Red)、綠色(Green)和藍色(Blue)三基色的字母縮寫。RGB色彩模式是通過三種基本顏色的不同程度的迭加來產生各種各樣的不同顏色。這個標準能夠涵蓋人類視力所能感知的所有顏色,是目前運用廣泛的顏色系統之一。

RGB(red,green,blue)顏色空間最常用的用途就是顯示器系統,彩色陰極射線管,彩色光柵圖形的顯示器 都使用R、G、B數值來驅動R、G、B 電子槍發射電子,並分別激發熒光屏上的R、G、B三種顏色的熒光粉 發出不同亮度的光線,並通過相加混合產生各種顏色;掃描器也是通過吸收原稿經反射或透射而傳送來 的光線中的R、G、B成分,並用它來表示原稿的顏色。

RGB色彩空間稱為與裝置相關的色彩空間,因為不同 的掃描器掃描同一幅影象,會得到不同色彩的影象資料;不同型號的顯示器顯示同一幅影象,也會有不同 的色彩顯示結果。顯示器和掃描器使用的RGB空間與CIE 1931 RGB真實三原色表色系統空間是不同的,後者 是與裝置無關的顏色空間。btw:Photoshop的色彩選取器(Color Picker)。可以顯示HSB、RGB、LAB和CMYK 色彩空間的每一種顏色的色彩值。

                                                                                          


RBG顏色的表示語法是(Red, Green, Blue), 因此各種顏色的標識值可以由公式計算得:65536*Blue+256*Green+Red。各個分量的數值越小,亮度越低;數值越大,亮度越高。(0,0,0)為黑色;(255,255,255)為白色。

RGB的格式有RGB565,RGB555,RGB24和RGB32等等。

Lab 顏色空間

  同RGB顏色空間相比,Lab是一種不常用的色彩空間。它是在1931年國際照明委員會(CIE)制定的顏色度量國際標準的基礎上建立起來的。1976年,經修改後被正式命名為CIELab它是一種裝置無關的顏色系統也是一種基於生理特徵的顏色系統。這也就意味著,

它是用數字化的方法來描述人的視覺感應Lab顏色空間中的L分量用於表示畫素的亮度,取值範圍是[0,100],表示從純黑到純白;a表示從紅色到綠色的範圍,取值範圍是[127,-128]b表示從黃色到藍色的範圍,取值範圍是[127,-128]。下圖所示為Lab顏色空間的圖示;

                          

    需要提醒的是,Lab顏色空間比計算機顯示器、印表機甚至比人類視覺的色域都要大,表示為 Lab 的點陣圖比 RGB 或 CMYK 點陣圖獲得同樣的精度要求更多的每畫素資料。雖然我們在生活中使用RGB顏色空間更多一些,但也並非Lab顏色空間真的一無所有。例如,在 Adobe Photoshop影象處理軟體中,TIFF格式檔案中,PDF文件中,都可以見到Lab顏色空間的身影。而在計算機視覺中,尤其是顏色識別相關的演算法設計中,rgb,hsv,lab顏色空間混用更是常用的方法。

兩者的區別:

    RGB的是由紅色通道(R)、綠色通道(G)、藍色通道(B)組成的,最亮的紅色+最亮的綠色+最亮的藍色=白色;最暗的紅色+最暗的綠色+最暗的藍色=黑色;而在最亮和最暗之間,相同明暗度的紅色+相同明暗度的綠色+相同明暗度的藍色=灰色。在RGB的任意一個通道內,白和黑表示這個顏色的明暗度。所以,有白色或者灰白色的地方,R、G、B三個通道都不可能是黑色的,因為必須要有R、G、B三個通道來構成這些顏色。
    而LAB不一樣,LAB中的明度通道(L)專門負責整張圖的明暗度,簡單的說就是整幅圖的黑白版。a通道和b通道只負責顏色的多少。a通道表示從洋紅色(通道里的白色)至深綠色(通道里的黑色)的範圍;b表示從焦黃色(通道里的白色)至嫋藍色(通道里的黑色)的範圍;a、b通道里的50%中性灰色表示沒有顏色,所以越接近灰色說明顏色越少,而且a通道和b通道的顏色沒有亮度。這就說明了為什麼在a、b通道中紅色T恤的輪廓是那麼的清晰!因為紅色是洋紅色+焦黃色組成的。
    總的來說:
      1、適合RGB通道摳的圖大部分LAB模式能完成,反之不成立。
      2、任何單一色調背景下,用通道摳有明顯顏色區別的部分,用LAB模式很快能完成
      3、LAB模式下對明度(L)通道做任何操作(如銳化、模糊等)不會影響到色相。

1.原理

RGB無法直接轉換成LAB,需要先轉換成XYZ再轉換成LAB,即:RGB——XYZ——LAB

因此轉換公式分兩部分:

(1)RGB轉XYZ

假設r,g,b為畫素三個通道,取值範圍均為[0,255],轉換公式如下:

    (1)      

    (2)

    (3)

M=

0.4124,0.3576,0.1805

0.2126,0.7152,0.0722

0.0193,0.1192,0.9505

等同於如下公式:

X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805
Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722
Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505

上面的gamma函式,是用來對圖象進行非線性色調編輯的,目的是提高影象對比度。

這個函式不是唯一的,但是我在網上查到的基本都使用上式。

(2)XYZ轉LAB

    (5)

    (6)

上面兩個公式中,L*,a*,b*是最終的LAB色彩空間三個通道的值。X,Y,Z是

RGB轉XYZ後計算出來的值,Xn,Yn,Zn一般預設是95.047,100.0,108.883。

2.程式碼實現

 (1)完全按照演算法無優化實現

[cpp] view plain copy print?
  1. <span style="font-size:14px;">inlinefloat gamma(float x)  
  2. {return x>0.04045?pow((x+0.055f)/1.055f,2.4f):x/12.92;};  
  3. void RGBToLab(unsigned char*rgbImg,float*labImg)  
  4. {  
[cpp] view plain copy print?
  1. float R=gamma(rgbImg[2]/255.0f);  
  2. float X=0.412453*R+0.357580*G+0.180423*B;  
  3. float Y=0.212671*R+0.715160*G+0.072169*B;  
  4. float Z=0.019334*R+0.119193*G+0.950227*B;  
  5. float X/=95.047;  
  6. float Y/=1000.0;  
  7. float Z/=108.883;  
  8. float FX = X > 0.008856f ? pow(X,1.0f/3.0f) : (7.787f * X +0.137931f);  
  9. float FY = Y > 0.008856f ? pow(Y,1.0f/3.0f) : (7.787f * Y +0.137931f);  
  10. float FZ = Z > 0.008856f ? pow(Z,1.0f/3.0f) : (7.787f * Z +0.137931f);  
  11. labImg[0] = Y > 0.008856f ? (116.0f * FY - 16.0f) : (903.3f * Y);  
  12. labImg[1] = 500.f * (FX - FY);  

    上面是完全按照轉換演算法做的無優化的實現,裡面涉及了大量的浮點運算,在PC上可能沒什麼問題,但是如果是在Android作業系統的移動端上,即使利用JNI,把轉換演算法寫成C++版本進行加速,速度也不理想,因為這個操作時逐畫素的,每個畫素做幾十次浮點運算,耗時還是十分巨大的
點選開啟連結