1. 程式人生 > >YUV格式與RGB格式

YUV格式與RGB格式

YUV420介紹:

YUV420格式是指,每個畫素都保留一個Y(亮度)分量,而在水平方向上,不是每行都取U和V分量,而是一行只取U分量,則其接著一行就只取V分量,以此重複(即4:2:0, 4:0:2, 4:2:0, 4:0:2 .......),所以420不是指沒有V,而是指一行取樣只取U,另一行取樣只取V。在取U和V時,每兩個Y之間取一個U或V。但從4x4矩陣列來看,每4個矩陣點Y區域中,只有一個U和V,所以它們的比值是4:1。所以對於一個畫素,RGB需要8 * 3 = 24位,即佔3個位元組;而YUV420P,8 + 8/4 + 8/4 = 12位,即佔2個位元組,其中8指Y分量,8/4指U和V分量。

從這裡也可以看出,YUV要比RGB節省儲存空間。


這裡為什麼一個分量是8位呢?
不管是R G B還是 Y U V他們每個分量的取值都是0-255,而計算機都是用二進位制來儲存的。巧了,一個位元組(8bit)剛好可以記錄0-255的數,

yuv420又分為yuv420p和yuv420sp.

 yuv420P格式如下:

yuv420sp格式如下:

還是影象比較直觀,從上面的圖片中就能看出來yuv420sp和yuv420p的區別了。
對於所有YUV420影象,它們的Y值排列是完全相同的,因為只有Y的影象就是灰度影象。YUV420sp與YUV420p的資料格式它們的UV排列在原理上是完全不同的。420p它是先把U存放完後,再存放V,也就是說UV它們是連續的。而420sp它是UV、UV這樣交替存放的。(記得結合上圖檢視)


有了上面的理論,就可以準確的計算出一個YUV420在記憶體中存放的大小。
Y = width * hight (總和)
U = Y / 4
V = Y / 4

所以一張YUV影象他的儲存空間就是:
width * height + width * height / 4 + width * height / 4
化簡後就是 width * height *3 /2
看來數學還是有點用的

YUV420P記憶體中的儲存方式:
YUV格式通常有兩大類:打包(packed)格式和平面(planar)格式。
前者將YUV分量存放在同一個陣列中,通常是幾個相鄰的畫素組成一個巨集畫素(macro-pixel);
而後者使用三個陣列分開存放YUV三個分量

YUV420P(planar格式)在ffmpeg中儲存是在struct AVFrame的data[]陣列中
data[0]-------Y分量
data[1]------U分量
data[2]-------V分量

現在回過頭看一下,我們前面儲存yuv420影象的程式碼:

int y_size=pCodecCtx->width*pCodecCtx->height;
fwrite(pFrameYUV->data[0],1,y_size,fp_yuv); //Y
fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv); //U
fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv); //V

 

 原文 http://blog.yundiantech.com/?log=blog&id=18

參考 http://blog.yundiantech.com/?log=blog&id=19