YUV格式分析詳解

YUV格式分析詳解

一,YUV含義

 YUV格式通常有兩大類:打包(packed)格式和平面(planar)格式。前者將YUV分量存放在同一個數組中,通常是幾個相鄰的像素組成一個宏像素(macro-pixel);而後者使用三個數組分開存放YUV三個分量,就像是一個三維平面一樣。

在攝像頭之類編程經常是會碰到YUV格式,而非大家比較熟悉的RGB格式. 我們可以把YUV看成是一個RGB的變種來理解.

 如果只有Y信號分量而沒有U、V分量,那麼這樣表示的圖像就是黑白灰度圖像。因此用YUV格式由彩色轉黑白信號相當簡單. 在技術文檔裏,YUV經常有另外的名字, YCbCr ,其中Y與YUV 中的Y含義一致,Cb , Cr 同樣都指色彩,,只是在表示方法上不同而已,Cb Cr 就是本來理論上的“分量/色差”的標識。C代表分量(是component的縮寫)Cr、Cb分別對應r(紅)、b(藍)分量信號,Y除了g(綠)分量信號,還疊加了亮度信號。

 YUV的原理是把亮度與色度分離,研究證明,人眼對亮度的敏感超過色度。利用這個原理,可以把色度信息減少一點,人眼也無法查覺這一點。YUV三個字母中,其中"Y"表示明亮度(Lumina nce或Luma),也就是灰階值;而"U"和"V"表示的則是色度(Chrominance或Chroma),作用是描述影像色彩及飽和度,用於指定像素的顏色。用這個三個字母好象就是通道命令。

使用YUV的優點有兩個:
1,彩色YUV圖像轉黑白YUV圖像轉換非常簡單,這一特性用在於電視信號上。
2,YUV是數據總尺寸小於RGB格式

二 幾大類YUV格式解析

• 4:4:4 表示色度頻道沒有下采樣。
• 4:2:2 表示 2:1 的水平下采樣,沒有垂直下采樣。對於每兩個 U 樣例或 V 樣例,每個掃描行都包含四個 Y 樣例。
• 4:2:0 表示 2:1 的水平下采樣,2:1 的垂直下采樣。
• 4:1:1 表示 4:1 的水平下采樣,沒有垂直下采樣。對於每個 U 樣例或 V 樣例,每個掃描行都包含四個 Y 樣例。與其他格式相比,4:1:1 採樣不太常用,本文不對其進行詳細討論。

採樣樣例:

圖片中使用的採樣網格。燈光樣例用叉來表示,色度樣例則用圈表示。

圖 1 顯示了 4:4:4 圖片中使用的採樣網格。

圖 1. YUV 4:4:4 樣例位置

4:2:2 採樣的這種主要形式在 ITU-R Recommendation BT.601 中進行了定義。圖 2 顯示了此標準定義的採樣網格。

圖 2. YUV 4:2:2 樣例位置

4:2:0 採樣有兩種常見的變化形式。其中一種形式用於 MPEG-2 視頻,另一種形式用於 MPEG-1 以及 ITU-T recommendations H.261 和 H.263。圖 3 顯示了 MPEG-1 方案中使用的採樣網格,圖 4 顯示了 MPEG-2 方案中使用的採樣網格。

圖 3. YUV 4:2:0 樣例位置(MPEG-1 方案)

圖 4. YUV 4:2:0 樣例位置(MPEG-2 方案)

首先,您應該理解下列概念,這樣才能理解接下來的內容:
• 表面原點。對於本文講述的 YUV 格式,原點 (0,0) 總是位於表面的左上角。
• 跨距。表面的跨距,有時也稱爲間距,指的是表面的寬度,以字節數表示。對於一個表面原點位於左上角的表面來說,跨距總是正數。
• 對齊。表面的對齊是根據圖形顯示驅動程序的不同而定的。表面始終應該 DWORD 對齊,就是說,表面中的各個行肯定都是從 32 位 (DWORD) 邊界開始的。對齊可以大於 32 位,但具體取決於硬件的需求。
• 打包格式與平面格式。YUV 格式可以分爲打包 格式和平面 格式。在打包格式中,Y、U 和 V 組件存儲在一個數組中。像素被組織到了一些巨像素組中,巨像素組的佈局取決於格式。在平面格式中,Y、U 和 V 組件作爲三個單獨的平面進行存儲。

YUV碼流的存儲格式其實與其採樣的方式密切相關,主流的採樣方式有三種, YUV4:4:4,YUV4:2:2 ,YUV4:2:0,關於其詳細原理,可以通過網上其它文章瞭解,這裏我想強調的是如何根據其採樣格式來從碼流中還原每個像素點的 YUV值,因爲只有正確地還原了每個像素點的 YUV值,才能通過 YUV與 RGB的轉換公式提取出每個像素點的 RGB值,然後顯示出來。

用三個圖來直觀地表示採集的方式吧, 以黑點表示採樣該像素點的 Y分量,以空心圓圈表示採用該像素點的 UV分量。

先記住下面這段話,以後提取每個像素的 YUV分量會用到。

YUV 4:4:4 採樣,每一個 Y對應一組UV分量。
YUV 4:2:2 採樣,每兩個 Y共用一組UV分量。
YUV 4:2:0 採樣,每四個 Y共用一組UV分量。

三,YUV格式與RGB格式的換算

RGB取值範圍均爲0~255,Y=0~255,U=-122~+122,V=-157~+157
以下是經過簡化的公式,運算量比上述公式要小一些。

RGB轉YUV
Y = 0.299R + 0.587G + 0.114B
U’= (BY)*0.565
V’= (RY)*0.713

YUV轉RGB
R = Y + 1.403V’
G = Y - 0.344U’ - 0.714V’
B = Y + 1.770U’

四.YUV的存儲格式—Packed(打包) / planar(平面)

RGB格式中,一個24bpp像素要佔用4字節空間。在YUV格式中,可以對於UV分量的數據壓縮,但是對圖像整體質量影響不大,這樣YUV所佔的空間就比RGB要小一些.不過RGB中 16bpp的 565格式每一個點只佔2個字節,從這一點看也沒有省多少。不過視頻應用都是清一色的YUV應用。因此YUV的處理還是一個比較重要課題。

YUV的存儲中與RGB格式最大不同在於,RGB格式每個點的數據是連繼保存在一起的。即R,G,B是前後不間隔的保存在2-4byte空間中。而YUV的數據中爲了節約空間,U,V分量空間會減小。每一個點的Y分量獨立保存,但連續幾個點的U,V分量是保存在一起的.這幾個點合起來稱爲macro-pixel, 這種存儲格式稱爲Packed(打包)格式。
另外一種存儲格式是把一幅圖像中Y,U,V分別用三個獨立的數組表示。這種模式稱爲planar(平面)模式。此模式中,YUV文件中YUV420又是怎麼存儲的呢? 在常見H264測試的YUV序列中,例如CIF圖像大小的YUV序列(352*288),在文件開始並沒有文件頭,直接就是YUV數據,先存第一幀的Y信息,長度爲352*288個byte, 然後是第一幀U信息長度是352*288/4個byte, 最後是第一幀的V信息,長度是352*288/4個byte, 因此可以算出第一幀數據總長度是352*288*1.5,即152064個byte, 如果這個序列是300幀的話, 那麼序列總長度即爲152064*300=44550KB,這也就是爲什麼常見的300幀CIF序列總是44M的原因.

YUV420 Planar :

YUV有packed format和planar format兩種。Packed format和planner format的區別在於,packed  format中的YUV是混合在一起的,因此就有了UYVY、YUYV等等,他們在碼流中排列的方式有所不同。而對於planner format每一個Y分量,U分量和V分量都是以獨立的平面組織的,也就是說所有的U分量都在Y分量之後出現,而V分量在所有的U分量之後。就像三個大色塊一樣。如下:

下面我用圖的形式給出常見的 YUV碼流的存儲方式 ,並在存儲方式後面附有取樣每個像素點的 YUV數據的方法,其中 ,Cb、 Cr的含義等同於 U、 V。
(1 ) YUVY 格式 (屬於YUV422)

YUYV爲YUV422 採樣的存儲格式中的一種,相鄰的兩個 Y共用其相鄰的兩個 Cb、 Cr,分析,對於像素點 Y’00、 Y’01 而言,其 Cb、 Cr的值均爲 Cb00、 Cr00,其他的像素點的 YUV取值依次類推。

(2) UYVY 格式 (屬於 YUV422)

UYVY格式也是YUV422 採樣的存儲格式中的一種 ,只不過與YUYV不同的是 UV的排列順序不一樣而已,還原其每個像素點的 YUV值的方法與上面一樣。

(3) YUV422P(屬於YUV422)

YUV422P也屬於YUV422 的一種,它是一種 Plane模式,即平面模式,並不是將 YUV數據交錯存儲,而是先存放所有的 Y分量,然後存儲所有的 U( Cb)分量,最後存儲所有的 V( Cr)分量,如上圖所示。其每一個像素點的 YUV值提取方法也是遵循 YUV422格式的最基本提取方法,即兩個 Y共用一個 UV。比如,對於像素點 Y’00、 Y’01 而言,其 Cb、 Cr的值均爲 Cb00、 Cr00。

(4) YV12,YU12 格式(屬於 YUV420)

YU12和 YV12屬於YUV420 格式,也是一種 Plane模式,將 Y、 U、 V分量分別打包,依次存儲。其每一個像素點的 YUV數據提取遵循 YUV420格式的提取方式,即4個 Y分量共用一組 UV。注意,上圖中, Y’00、 Y’01、 Y’10、 Y’11共用 Cr00、 Cb00,其他依次類推。

(5)NV12、NV21(屬於YUV420)

NV12和NV21屬於YUV420格式,是一種two-plane模式,即Y和UV分爲兩個Plane,但是UV(CbCr)爲交錯存儲,而不是分爲三個plane。其提取方式與上一種類似,即Y’00、Y’01、Y’10、Y’11共用Cr00、Cb00 YUV420 planar數據.

以720×488大小圖象YUV420 planar爲例,其存儲格式是: 共大小爲(720×480×3>>1)字節,分爲三個部分:Y,U和V
Y分量 :(720×480)個字節
U(Cb)分量:(720×480>>2)個字節
V(Cr)分量:(720×480>>2)個字節
三個部分內部均是行優先存儲,三個部分之間是Y,U,V 順序存儲。
即YUV數據的0-720×480字節是Y分量值, 720×480-720×480×5/4字節是U分量, 720×480×5/4-720×480×3/2字節是V分量。

4 :2: 2 和4:2:0 轉換:
最簡單的方式:
YUV4:2:2 —> YUV4:2:0 Y不變,將U和V信號值在行(垂直方向)在進行一次隔行抽樣。
YUV4:2:0 —> YUV4:2:2 Y不變,將U和V信號值的每一行分別拷貝一份形成連續兩行數據。

在YUV420中,一個像素點對應一個Y,一個4X4的小方塊對應一個U和V。對於所有YUV420圖像,它們的Y值排列是完全相同的,因爲只有Y的圖像就是灰度圖像。YUV420sp與YUV420p的數據格式它們的UV排列在原理上是完全不同的。420p它是先把U存放完後,再存放V,也就是說UV它們是連續的。而420sp它是UV、UV這樣交替存放的。(見下圖) 有了上面的理論,我就可以準確的計算出一個YUV420在內存中存放的大小。 width * hight =Y(總和) U = Y / 4 V = Y / 4

所以YUV420 數據在內存中的長度是 width * hight * 3 / 2,
假設一個分辨率爲8X4的YUV圖像,它們的格式如下圖:
YUV420sp格式如下圖

YUV420p數據格式如下圖

旋轉90度的算法:
public static void rotateYUV240SP(byte[] src,byte[] des,int width,int height)
{

int wh = width * height;
//旋轉Y
int k = 0;
for(int i=0;i

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章