yuv存儲格式
㈠ YUV格式圖像基礎
yuv是一種類似rgb的顏色模型,起源於黑白和彩電的過渡時期。其中Y代表亮度,uv組合起來可以表示色度。yuv信息只有y的信息就足以顯示黑白的圖片,yuv和YCbCr表示相同的東西,且Cb嚴格對應U,Cr嚴格對應V,yuv和rgb可以通過固定公式進行轉換。
yuv轉rgb:
rgb轉yuv:
yuv主流的采樣方式有yuv4:4:4、yuv4:2:2、yuv4:2:0。下圖中以黑點表示采樣該像素點的Y分量,以空心圓圈表示採用該像素點的UV分量,可以看到這些采樣方式是影響uv的采樣的,對y都是全部采樣。
可以看到,yuv格式圖像信息可以比rgb格式佔用的位元組碼更少,所以可以用yuv來傳輸色彩數據,接收到yuv數據後再轉換為rgb來顯示圖像,從而減少了傳輸圖像佔用的帶寬。
yuv衍生出了很多格式,主要是由於其存儲方式決定的。
packed存儲的yuv的存儲先後不同,細分為了yuv、yvu、yvyu、uyvy等等。
planar存儲的yuv依據數組數量分成了yuv分別三個數組表示的完全平面的,以及y一個數組而uv一個數組的半平面(Semi planar)的兩類,而半平面的又可以細分為uv和vu兩個存儲順序。
I420: YYYYYYYY UU VV =>YUV420P
YV12: YYYYYYYY VV UU =>YUV420P
NV12: YYYYYYYY UVUV =>YUV420SP
NV21: YYYYYYYY VUVU =>YUV420SP //安卓Camera默認格式
涉及到攝像頭幀圖像處理的應用經常需要操作Yuv數據幀,例如鏡像、加濾鏡等。
操作yuv圖像可以直接使用google開源的libyuv庫,提供了對yuv圖像的格式轉換、縮放、裁剪、旋轉、鏡像等操作: 谷歌git libyuv ,github上有人用其做了簡單的安卓版本的demo: 安卓libyuvDemo ,包含了基礎的yuv庫的使用邏輯,但是該項目沒有同步谷歌libyuv更新。
參考鏈接:
https://www.cnblogs.com/azraelly/archive/2013/01/01/2841269.html
http://www.360doc.com/content/16/0517/16/496343_559909505.shtml
谷歌git libyuv
[安卓libyuvDemo
㈡ 視頻數據存儲方式YUV
在視頻中的數據保存和傳輸都是YUV數據格式。主要是為了降低數據大小,如果argb格式數據,1px可能需要4個位元組,而YUV可能就只需要1.5個位元組。
簡單的講YUV是一種圖像和視頻的編碼方式,RGB通過三種顏色來表達現實世界中的各種顏色,YUV通過 亮度 與 色度飽和度 來表示顏色。
RGB很好理解,它更直觀。從學生開始就認識繪畫的顏料是用三種顏色調配來的,汽車的油漆顏色也是RGB三種顏色調配而來的。
YUV的出現有它的歷史意義但也是一種必然。它基於人眼對亮度的敏感度比色彩的敏感度更高的特點。Y表示亮度也可以理解在灰度值,最低的亮度就是黑色最高的亮度就是白色,中間的可呈現出灰色。
在黑白電視機向彩色電視機過渡的年代,黑白電視機只需要YUV中的一個分量Y就可以呈現出黑白畫面。UV分量用在彩色電視機上即可呈現出彩色了。YUV可以帶來更高的幀內壓縮比,由於人眼對黑白更敏感,YUV可以弱化不敏感的信息,減少UV分量的采樣。RGB24的每個像素需要3*8個位元組,YUV呢?不同的YUV采樣方式壓縮比有所不同。
電視信息使用的是YUV而數字信息使用的是 YCrCb 命令,以下統稱YUV。
YUV簡介
與RGB類似,YUV也是一種顏色編碼方法,主要用於視頻領域,它將亮度信息(Y)與色彩信息(UV)分離,沒有UV信息一樣可以顯示完整的圖像,只不過是黑白的,這樣設計解決了彩色電視機與黑白電視的兼容問題。
YUV,分為三個分量,「Y"表示明亮度(Luminance或Luma),也就是灰度;而」U"和「V」表示是色度(Chrominance或Chroma),作用於指定像素的顏色。
UV即CbCr(C代表顏色color,b代表藍色blue,r代表紅色red)
分類
YUV格式的兩大類:平面(plannr)和緊湊(packed)。
對於planar的YUV格式,先連續存儲所有像素點的Y,緊接著存儲所有像素點的U,隨是存儲所有像素點的V,或者是先v後u
對於packed的YUV格式,每個像素點的Y,U,V是連續交替存儲的。比如YUV420P 其中P表示緊湊,YUV420SP其中的SP表示「半緊湊」。
采樣
主流的采樣方式有三種,YUV4:4:4,YUV4:2:2 ,YVU4:2:0
YUV4:4:4采樣,每一個Y對應一組UV分量,一個YUV佔8+8+8=24bits 3個位元組。
YUV4:2:2采樣,每兩個Y共用一組UV分量,一個YUV佔8+4+4=16bits 2個位元組。
YUV4:2:0采樣,每四個Y共用一組UV分量,一個YUV佔8+2+2 = 12bits 1.5個位元組。
最覺的YUV420P和YUV420SP都是基於4:2:0采樣的,所以如果圖片的寬為width,高為height,在內存中占的空間width*height*3/2,其中前width*height的空間存放Y分量,接著width*height/4存放U分量,最後width*height/4存放V分量。
YUV格式
常見的YUV格式有YUY2、YUYV、YVYU、UYUV、AYUV、Y41P、Y411、Y211、Y211、IF09、IYUV、YV12、YVU9、YUV411、YUV420等,Android中比較常見是YUV420分兩種:YUV420P和YUV420SP。以下為YUV420P和YUV420SP。
YUV420P
YUV420P是平面模式,Y、U、V分別在不同平面,也就是有三個平面。它是YUV標准格式4:2:0,為了更方便的看如下表示 :
為了說明存儲方式,每一組用不同顏色表示。每一種顏色都是一組,每四個Y共用一組UV分量。
比如:
Y1、Y2、Y7、Y8共用U1,V1;
Y3、Y4、Y9、Y10共用U2,V2;
Y5、Y6、Y11、Y12共用U3,V3;
Y13,Y14,Y19,Y20共用U4,V4
Y17,Y18,Y23,Y24共用U6,V6
那麼真實的在位元組流中就是按照行從左到右一行一行的拼起來的:
YUV420分為:YU12和YV12
YUV格式
在Android中也叫作I420格式,首先是所有Y值 ,然後是所有U值,最後是所有V值。比如6*6的圖片,內存大小就是6*6*3/2 = 54個位元組。為了更清晰的查看,我們換行看,真實的是一行byte[]數據流。
1 YYYYYY
2 YYYYYY
3 YYYYYY
4 YYYYYY
5 UUUUUU
6 VVVVVV
YV12格式
YV12格式與YU12格式,首先是所有Y值,然後是所有V值,最後是所有U值。比如6*6圖片,內存大小就是6*6*3/2=54位元組
1 YYYYYY
2 YYYYYY
3 YYYYYY
4 YYYYYY
5 VVVVVV
6 UUUUUU
YUV420SP
YUV420SP也是平面模式。分為NV21和NV12兩種格式。Y是一個平面,UV是一個平面, UV/VU為交替存儲,而不是分為三個平面。
在Android Camera中文檔強烈推薦使用NV21和YU12,因為這兩種格式支持所有的相機設備。
Camera默認輸出YUV的數據格式為NV21。但是在Camera2中推薦使用格式則是YUV_420_888。
NV21格式
在Android Carmra中手機從攝像頭採集的預覽數據默認值是NV21。
NV21存儲順序是先存Y值,再VU交替存儲:YYYVUVUVU,比如6*6的圖片,內存大小就是6*6*3/2=54個位元組。
1 YYYYYY
2 YYYYYY
3 YYYYYY
4 YYYYYY
5 VUVUVU
6 VUVUVU
NV12格式
NV12存儲順序是先存Y值,再UV交替存儲:YYYUVUVUV,比如6*6的圖片,內存大小就是6*6*3/2=54位元組。
1 YYYYYY
2 YYYYYY
3 YYYYYY
4 YYYYYY
5 UVUVUV
6 UVUVUV
這里先熟悉下Android中常見的YUV420P和YUV420SP。一般我們在使用yuv數據的時候,會對yuv數據進行變換,比如:攝像頭數據旋轉,從一種格式轉為另一種數據等。