YUV格式分析详解
1. YUV簡介
YUV定義:分為三個分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的則是色度(Chrominance或Chroma),作用是描述影像色彩及飽和度,用于指定像素的顏色。
YUV格式:有兩大類:planar和packed。
對于planar的YUV格式,先連續存儲所有像素點的Y,緊接著存儲所有像素點的U,隨后是所有像素點的V。
對于packed的YUV格式,每個像素點的Y,U,V是連續交*存儲的。
YUV存儲:格式其實與其采樣的方式密切相關,主流的采樣方式有三種,YUV4:4:4,YUV4:2:2,YUV4:2:0,關于其詳細原理,可以通過網 上其它文章了解,這里我想強調的是如何根據其采樣格式來從碼流中還原每個像素點的YUV值,因為只有正確地還原了每個像素點的YUV值,才能通過YUV與 RGB的轉換公式提取出每個像素點的RGB值,然后顯示出來。?
YUV特點:也是一種顏色編碼方法,它將亮度信息(Y)與色彩信息(UV)分離,沒有UV信息一樣 可以顯示完整的圖像,只不過是黑白的,這樣的設計很好地解決了彩色電視機與黑白電視的兼容問題。并且,YUV不像RGB那樣要求三個獨立的視頻信號同時傳 輸,所以用YUV方式傳送占用極少的頻寬。
?圖:用三個圖來直觀地表示采集的方式吧,以黑點表示采樣該像素點的Y分量,以空心圓圈表示采用該像素點的UV分量。
2.? 存儲方式
??? 下面我用圖的形式給出常見的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分量: ???? (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<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的卻是不同的,在存儲空間上面有些區別。如下:
經過第一次數據壓縮后RGB24->YUV(I420)。數據量將減少一半, RGB24->YUV(YV12)有很大損失。經過X264編碼后,數據量將大大減少。將編碼后的數據打包,通過RTP實時傳送。到達目的地后,將數據取出,進行解碼。完成解碼后,數據仍然是YUV格式的,需要一次轉換,這樣windows的驅動才可以處理,就是YUV2RGB24。
YV12 : 亮度(行×列) + U(行×列/4) + V(行×列/4)
I420 : 亮度(行×列) + V(行×列/4) + U(行×列/4)
YUY2? 是 4:2:2? [Y0 U0 Y1 V0]
yuv420p:yyyyyyyy uuuuuuuu vvvvv
yuv420: yuv yuv yuv
?
YUV420P,Y,U,V三個分量都是平面格式,分為I420和YV12。在I420格式(即: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
總結
- 上一篇: hdu 6127---Hard cha
- 下一篇: 将M进制的数转换为N进制的数(java)