圖文詳解 YUV420 數據格式

YUV 格式有兩大類:planar 和 packed。
  • 對於 planar 的 YUV 格式,先連續存儲全部像素點的 Y,緊接着存儲全部像素點的 U,隨後是全部像素點的 V。
  • 對於 packed 的 YUV 格式,每一個像素點的 Y, U, V 是連續交*存儲的。

YUV,分爲三個份量,「Y」 表示明亮度(Luminance 或 Luma),也就是 灰度值;而 「U」 和 「V」 表示的則是色度(Chrominance 或 Chroma),做用是 描述影像色彩及飽和度,用於指定像素的顏色

與咱們熟知的 RGB 相似,YUV 也是一種顏色編碼方法,主要用於電視系統以及模擬視頻領域,它將亮度信息(Y)與色彩信息(UV)分離,沒有 UV 信息同樣能夠顯示完整的圖像,只不過是黑白的,這樣的設計很好地解決了彩色電視機與黑白電視的兼容問題。而且,YUV 不像 RGB 那樣要求三個獨立的視頻信號同時傳輸,因此 用 YUV 方式傳送佔用極少的頻寬

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

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

先記住下面這段話,之後提取每一個像素的 YUV 份量會用到。
windows

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

存儲方式

下面我用圖的形式給出常見的 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 值的方法與上面同樣。 spa

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'0一、Y'十、Y'11 共用 Cr00、Cb00,其餘依次類推。

code

(5)NV十二、NV21(屬於 YUV420)

NV12 和 NV21 屬於 YUV420 格式,是一種 two-planar 模式,即 Y 和 UV 分爲兩個 Plane,可是 UV(CbCr)爲交錯存儲,而不是分爲三個 plane。其提取方式與上一種相似,即 Y'00、Y'0一、Y'十、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 在內存中存放的大小: it

 width * hight = Y(總和) U = Y / 4   V = Y / 4

因此 YUV420 數據在內存中的長度是 width * hight * 3 / 2,

假設一個分辨率爲 8X4 的 YUV 圖像,它們的格式以下圖:

YUV420sp 格式以下圖           
       class

 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 < width; i++) {
   for(int j = 0; j < height; j++) 
   {
      des[k] = src[width*j + i];   
      k++;
   }
  }
  
  for(int i = 0; i < width; i+ = 2) {
   for(int j = 0; j < height/2; j++) 
   { 
      des[k] = src[wh+ width*j + i]; 
      des[k+1]=src[wh + width*j + i+1];
      k+ = 2;
   }
  }
  
 }




YV12和I420的區別        

通常來講,直接採集到的視頻數據是 RGB24 的格式,RGB24 一幀的大小 size=width×heigth×3 Bit,RGB32 的 size=width×heigth×4,若是是 I420(即 YUV 標準格式 4:2:0)的數據量是 size=width×heigth×1.5 Bit。       

在採集到 RGB24 數據後,須要對這個格式的數據進行第一次壓縮。即將圖像的顏色空間由 RGB2YUV。由於,X264在進行編碼的時候須要標準的 YUV(4:2:0)。可是這裏須要注意的是,雖然 YV12 也是(4:2:0),可是 YV12 和 I420 的倒是不一樣的,在存儲空間上面有些區別。以下: 

YV12 : 亮度(行×列) + U(行×列/4) + V(行×列/4)
I420 : 亮度(行×列) + V(行×列/4) + U(行×列/4)

能夠看出,YV12 和 I420 基本上是同樣的,就是 UV 的順序不一樣。

繼續咱們的話題,通過第一次數據壓縮後 RGB24->YUV(I420)。這樣,數據量將減小一半,爲何呢?呵呵,這個就太基礎了,我就很少寫了。一樣,若是是 RGB24->YUV(YV12),也是減小一半。可是,雖然都是一半,若是是 YV12 的話效果就有很大損失。而後,通過 X264 編碼後,數據量將大大減小。將編碼後的數據打包,經過 RTP 實時傳送。到達目的地後,將數據取出,進行解碼。完成解碼後,數據仍然是 YUV 格式的,因此,還須要一次轉換,這樣 windows 的驅動才能夠處理,就是 YUV2RGB24。

YUY2  是 4:2:2  [Y0 U0 Y1 V0]

yuv420p 和 YUV420的區別 

在存儲格式上有區別

yuv420p: yyyyyyyy uuuuuuuu vvvvv 

yuv420: yuv yuv yuv

YUV420P,Y,U,V 三個份量都是平面格式,分爲 I420 和 YV12。I420 格式和 YV12 格式的不一樣處在 U 平面和V 平面的位置不一樣。在 I420 格式中,U 平面緊跟在 Y 平面以後,而後纔是 V 平面(即:YUV);但 YV12 則是相反(即:YVU)。
YUV420SP, Y 份量平面格式,UV 打包格式, 即 NV12。 NV12 與 NV21 相似,U 和 V 交錯排列,不一樣在於 UV 順序。

I420: YYYYYYYY UU VV    =>YUV420P
YV12: YYYYYYYY VV UU    =>YUV420P
NV12: YYYYYYYY UVUV     =>YUV420SP
NV21: YYYYYYYY VUVU     =>YUV420SP

相關文章
相關標籤/搜索