最近在準備作Android Camera2相關應用,恰好也碰上了YUV格式相關的問題,因此仍是寫一篇博客理解YUV格式數據。html
YUV是一種顏色空間,基於YUV的顏色編碼是流媒體的經常使用編碼方式。android
YUV是編譯true-color顏色空間(color space)的種類,Y'UV, YUV, YCbCr,YPbPr等專有名詞均可以稱爲YUV,彼此有重疊。「Y」表示明亮度(Luminance、Luma),「U」和「V」則是色度、濃度(Chrominance、Chroma),Y′UV, YUV, YCbCr, YPbPr所指涉的範圍,常有混淆或重疊的狀況。編碼
YUV格式有兩大類:planar和packed。spa
平面格式(planar formats) :對於planar的YUV格式,先連續存儲全部像素點的Y,緊接着存儲全部像素點的U,隨後是全部像素點的V,如 YYYY YYYY UU VV。.net
緊縮格式(packed formats):對於packed的YUV格式,每一個像素點的Y,U,V是連續交替存儲的,如YUV YUV YUV YUV,這種排列方式跟 RGB 很相似。翻譯
Y'UV的發明是因爲彩色電視與黑白電視的過渡時期。黑白視頻只有Y(Luma,Luminance)視頻,也就是灰階值。到了彩色電視規格的制定,是以YUV/YIQ的格式來處理彩色電視圖像,把UV視做表示彩度的C(Chrominance或Chroma),若是忽略C信號,那麼剩下的Y(Luma)信號就跟以前的黑白電視頻號相同,這樣一來便解決彩色電視機與黑白電視機的兼容問題。Y'UV最大的優勢在於只需佔用極少的帶寬。設計
由於UV分別表明不一樣顏色信號,因此直接使用R與B信號表示色度的UV。 也就是說UV信號告訴了電視要偏移某象素的的顏色,而不改變其亮度。 或者UV信號告訴了顯示器使得某個顏色亮度依某個基準偏移。 UV的值越高,表明該像素會有更飽和的顏色。3d
彩色圖像記錄的格式,常見的有RGB、YUV、CMYK等。彩色電視最先的構想是使用RGB三原色來同時傳輸。這種設計方式是原來黑白帶寬的3倍,在當時並非很好的設計。RGB訴求於人眼對色彩的感應,YUV則着重於視覺對於亮度的敏感程度,Y表明的是亮度,UV表明的是彩度(所以黑白電影可省略UV,相近於RGB),分別用Cr和Cb來表示,所以YUV的記錄一般以Y:UV的格式呈現。code
將一張圖片的Y、U、V數據單獨顯示就會以下圖所示:orm
YUV的存儲格式其實與其採樣的方式密切相關,主流的採樣方式有三種,YUV4:4:4,YUV4:2:2,YUV4:2:0。
以黑點表示採樣該像素點的Y份量,以空心圓圈表示採用該像素點的UV份量
複製代碼
4:4:4表示徹底取樣,每一個像素點都採樣單獨的 YUV 份量信息,包含了最全面的 YUV 信息。
在 YUV444 編碼的基礎上採用 2 * 1 的矩陣進行二次取樣,也就是在水平方向上隔一列採樣一次 UV 信息,在垂直方向上進行徹底取樣,每兩個Y共用一組UV份量。
YUYV格式
字節排列 : YUYV YUYV YUYV YUYV
UYVY 格式
字節排列 : UYVY UYVY UYVY UYVY
YUV422P格式
字節排列 :YYYY YYYY UUUU VVVV
解決 YUV444 佔用空間過大問題,也是最經常使用的採樣格式。在 YUV444 格式的基礎上使用 2 * 2 矩陣對像素點進行二次取樣,4 個像素點具備單獨 Y 份量且共享同一個 UV 信息,總 6 字節。一幀圖像佔用總空間 (W * H + W * H / 2) bytes,比 YUV444 少一半空間。
I420格式 字節排列 YYYY YYYY UU VV,所有都是平面型排列
NV21格式 字節排列 YYYY YYYY UV UV,Y 平面和 UV 平面, UV 內部是緊湊型
YV12格式 字節排列 YYYY YYYY VV UU,平面型,V 在 U 前面
更多YUV格式參看:V4L2文檔翻譯(十)
最簡單的方式:
YUV4:2:2 ---> YUV4:2:0 Y不變,將U和V信號值在行(垂直方向)在進行一次隔行抽樣
YUV4:2:0 ---> YUV4:2:2 Y不變,將U和V信號值的每一行分別拷貝一份造成連續兩行數據
YUV_420_888是在Android Camera2直播開發中遇到的一個Android內部的YUV格式,當時也是在這個格式上面糾結很久,直播的視頻流想用YUV420P格式的數據,但卻不清楚這個YUV_420_888到底對應的究竟是個什麼樣的格式,網上對這個格式的講解也比較少。在搜索一番以後終於搞定,在這裏記錄一下。
下面這兩篇博客介紹了YUV_420_888以及如何解析,講的很清晰,這裏仍是不本身去寫了。