RGB YUV的来历及相互转换
在視頻等相關的應用中, YUV 是一個經常出現的格式。本文主要以圖解的資料的形式詳細描述 YUV 和 RGB 格式的來由,相互關系以及轉換方式,并對 C 語言實現的 YUV 轉為 RGB 程序進行介紹。
???????? 人類眼睛的色覺,具有特殊的特性,早在上世紀初, Young ( 1809 )和 Helmholtz ( 1824 )就提出了視覺的三原色學說,即:視網膜存在三種視錐細胞,分別含有對紅、綠、藍三種光線敏感的視色素,當一定波長的光線作用于視網膜時,以一定的比例使三種視錐細胞分別產生不同程度的興奮,這樣的信息傳至中樞,就產生某一種顏色的感覺。
?????? 70年代以來,由于實驗技術的進步,關于視網膜中有三種對不同波長光線特別敏感的視錐細胞的假說,已經被許多出色的實驗所證實 。 例如:①有人用不超過單個視錐直徑的細小單色光束,逐個檢查并繪制在體(最初實驗是在金魚和蠑螈等動物進行,以后是人)視錐細胞的光譜吸收曲線 ,發現所有繪制出來的曲線不外三種類型,分別代表了三類光譜吸收特性不同的視錐細胞,一類的吸收峰值在 420nm處,一類在 534nm處,一類在 564nm處,差不多正好相當于藍、綠、紅三色光的波長。與上述視覺三原色學說的假設相符。②用微電極記錄單個視錐細胞感受器電位的方法,也得到了類似的結果,即不同單色光所引起的不同視錐細胞的超極化型感受器電位的大小也不同,峰值出現的情況符合于三原色學說。
??? 于是,在彩色顯示器 還沒有發明的時候,人類已經懂得使用三原色光調配出所有顏色的光。并不是說三原色混合后產生了新的頻率的光,而是給人眼睛的感覺是這樣。
?
?????????
??????????????????? 在顯示器發明之后,從黑白顯示器發展到彩色顯示器,人們開始使用發出不同顏色的光的熒光粉( CRT ,等離子體顯示器),或者不同顏色的濾色片( LCD ),或者不同顏色的半導體發光器件( OLED 和 LED 大型全彩顯示牌)來形成色彩,無一例外的選擇了 Red,Green,Blue 這 3 種顏色的發光體作為基本的發光單元。通過控制他們發光強度,組合出了人眼睛能夠感受到的大多數的自然色彩。
???????? 計算機顯示彩色圖像的時候也不例外,最終顯示的時候,要控制一個像素中 Red,Green,Blue 的值,來確定這個像素的顏色。計算機中無法模擬連續的存儲從最暗到最亮的量值,而只能以數字的方式表示。于是,結合人眼睛的敏感程度,使用 3 個字節( 3*8 位)來分別表示一個像素里面的 Red,Green 和 Blue 的發光強度數值,這就是常見的 RGB 格式。我們可以打開畫圖板,在自定義顏色工具框中,輸入 r,g,b 值,得到不同的顏色。
?
????????
???????? 但是對于視頻捕獲和編解碼等應用來講,這樣的表示方式數據量太大了。需要想辦法在不太影響感覺的情況下,對原始數據的表示方法進行更改,減少數據量。
?????? ?? 無論中間處理過程怎樣,最終都是為了展示給人觀看,這樣的更改,也是從人眼睛的特性出發,和發明 RGB 三原色表示方法的出發點是一樣的。
???????? 于是我們使用 Y,Cb,Cr 模型來表示顏色。 Iain 的書中寫道: The human visual system (HVS) is less sensitive to colour than to luminance (brightness). 人類視覺系統(其實就是人的眼睛)對亮度的感覺比對顏色更加敏感。
???????? 在 RGB 色彩空間中,三個顏色的重要程度相同,所以需要使用相同的分辨率進行存儲,最多使用 RGB565 這樣的形式減少量化的精度,但是 3 個顏色需要按照相同的分辨率進行存儲,數據量還是很大的。所以,利用人眼睛對亮度比對顏色更加敏感,將圖像的亮度信息和顏色信息分離,并使用不同的分辨率進行存儲,這樣可以在對主觀感覺影響很小的前提下,更加有效的存儲圖像數據。
??????? YCbCr 色彩空間和它的變形(有時被稱為 YUV )是最常用的有效的表示彩色圖像的方法。 Y 是圖像的亮度( luminance/luma )分量,使用以下公式計算,為 R,G,B 分量的加權平均值:
??????? Y = kr R + kgG + kbB
??????? 其中 k 是權重因數。
??????? 上面的公式計算出了亮度信息,還有顏色信息,使用色差( color difference/chrominance 或 chroma )來表示,其中每個色差分量為 R,G,B 值和亮度 Y 的差值:
Cb = B - Y
Cr = R - Y
Cg = G - Y
其中, Cb+Cr+Cg 是一個常數(其實是一個關于 Y 的表達式),所以,只需要其中兩個數值結合 Y 值就能夠計算出原來的 RGB 值。所以,我們僅保存亮度和藍色、紅色的色差值,這就是 (Y,Cb,Cr) 。
相比 RGB 色彩空間, YCbCr 色彩空間有一個顯著的優點。 Y 的存儲可以采用和原來畫面一樣的分辨率,但是 Cb,Cr 的存儲可以使用更低的分辨率。這樣可以占用更少的數據量,并且在圖像質量上沒有明顯的下降。所以,將色彩信息以低于量度信息的分辨率來保存是一個簡單有效的圖像壓縮方法。
在 COLOUR SPACES .17 ITU-R recommendation BT.601 中,建議在計算 Y 時,權重選擇為 kr=0.299,kg=0.587,kb=0.114 。于是常用的轉換公式如下:
Y = 0.299R + 0.587G + 0.114B
Cb = 0.564(B - Y )
Cr = 0.713(R - Y )
R = Y + 1.402Cr
G = Y - 0.344Cb - 0.714Cr
B = Y + 1.772Cb
有了這個公式,我們就能夠將一幅 RGB 畫面轉換成為 YUV 畫面了,反過來也可以。下面將畫面數據究竟是以什么形式存儲起來的。
在 RGB24 格式中,對于寬度為 w, 高度為 h 的畫面,需要 w*h*3 個字節來存儲其每個像素的 rgb 信息,畫面的像素數據是連續排列的。按照 r(0,0),g(0,0),b(0,0);r(0,1),g(0,1),b(0,1);…;r(w-1,0),g(w-1,0),b(w-1,0);…;r(w-1,h-1),g(w-1,h-1),b(w-1,h-1) 這樣的順序存放起來。
在 YUV 格式中,以 YUV420 格式為例。寬度為 w 高度為 h 的畫面,其亮度 Y 數據需要 w*h 個字節來表示(每個像素點一個亮度)。而 Cb 和 Cr 數據則是畫面中 4 個像素共享一個 Cb,Cr 值。這樣 Cb 用 w*h/4 個字節, Cr 用 w*h/4 個字節。
YUV 文件中,把多個幀的畫面連續存放。就是 YUV YUV YUV….. 這樣的不斷連續的形式,而其中每個 YUV ,就是一幅畫面。
在這單個 YUV 中,前 w*h 個字節是 Y 數據,接著的 w*h/4 個字節是 Cb 數據,再接著的 w*h/4 個字節為 Cr 數據。
在由這樣降低了分辨率的數據還原出 RGB 數據的時候,就要依據像素的位置找到它對應的 Y,Cb,Cr 值,其中 Y 值最好找到,像素位置為 x,y 的話, Y 數據中第 y*width+x 個數值就是它的 Y 值。 Cb 和 Cr 由于是每 2x2 像素的畫面塊擁有一個,這樣 Cb 和 Cr 數據相當于兩個分辨率為 w/2 * h/2 的畫面,那么原來畫面中的位置為 x,y 的像素,在這樣的低分辨率畫面中的位置是 x/2,y/2 ,屬于它的 Cb,Cr 值就在這個地方: (y/2)*(width/2)+(x/2) 。
為了直觀起見,再下面的圖中,分別將 Y 畫面 (Cb,Cr=0) 和 Cb,Cr 畫面 (Y=128) 顯示出來,可見 Cb,Cr 畫面的分辨率是 Y 畫面的 1/4 。但是合成一個畫面之后,我們的眼睛絲毫感覺不到 4 個像素是共用一個 Cb,Cr 的。
?
??????? Y 畫面
?
??????? Cb,Cr 畫面
將 Cb,Cr 畫面放大觀察,里面顏色相同的塊都是 2x2 大小的。
附件為 Windows Mobile 上使用公式進行 YUV 到 RGB 轉換的程序。其中需要注意的是 Cb,Cr 在計算過程中是會出現負數的,但是從 -128 到 127 這些數值都用一個字節表示,讀取的時候就映射 0 到 255 這個區間,成為了無符號的值,所以要減去 128 ,才能參與公式計算。這樣的運算有浮點運算,效率是比較低的,所以要提高效率的話,一般在實用程序中使用整數計算或者查表法來代替。還有,運算后的 r,g,b 可能會超過 0-255 的區間,作一個判斷進行調整就可以了。
?
來自: http://hi.baidu.com/ykdsea/blog/item/c0245aa1c86cab8e471064c3.html
總結
以上是生活随笔為你收集整理的RGB YUV的来历及相互转换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 完美打造安全的系统。
- 下一篇: 源码推荐-380套大型商业源码