上一篇中,我們了解了Android二維碼掃描開發的實作思路和原理。其中從相機裡擷取到的資料是NV21格式的,NV21屬于YUV圖像,當然有些外置攝像頭會傳回其他YUV格式的資料,那麼我們就來看一看,到底什麼是YUV圖像。
RGB圖像大家都了解,RGB圖像分為了三個顔色分量,R紅色分量,G綠色分量,B藍色分量。而YUV圖像,也是分為了三個分量,Y亮度分量,用來表示明亮度,也叫灰階值,U分量和V分量是色值分量,用來表示圖像色彩與飽和度,其中U分量也叫Cb,表示的圖像藍色偏移量,V分量也叫Cr,用來表示圖像紅色部分偏移量,是以YUV有時也寫作YCbCr。
YUV圖像把亮度和色度分開了,避免了亮度和色度的互相幹擾,可以在降低色度采樣率的情況下,保持圖像的視覺品質。
[采樣比率]
下面我們來看看YUV圖像的采樣方式,是如何改變色度采樣率的。YUV圖像有以下幾種采樣比例:
444采樣中,Y:U:V=4:4:4,每一個Y對應一個UV,水準和垂直方向都保持原資料;
422采樣中,Y:U:V=4:2:2,每兩個Y共用一個UV,水準方向采用2:1采樣,垂直方向保持原資料;
411采樣中,Y:U:V=4:1:1,每四個Y共用一個UV,水準方向采用4:1采樣,垂直方向保持原資料;
420采樣中,Y:UV=4:2或Y:U:V=4:1:1,每四個Y共用一個UV,水準方向和垂直方向都采用2:1采樣。
如果用×表示Y資料,用〇表示UV資料,那麼下面幾種采樣如下圖所示:

[存儲方式]
YUV資料的存儲方式分為打包的(packed)和平面的(planar)。
packed存儲方式是,每一組YUV作為一個連續存儲,每個組後面跟着另外一組,常見的有UYVY、YUYV等類型,以YUYV(屬于YUV422)為例,儲存方式如下圖所示:
從上圖中可以看出,兩個相鄰的Y共用一組UV,Y和UV是交錯儲存的。
planar儲存方式是,先是連續的Y,然後是連續的UV,UV可以交錯也可以不交錯。以YUV420為例,YUV420分為YUV420P和YUV420SP,差別是YUV420P中U和V是分開連續存儲的,YUV420SP中,UV是交錯存儲的。如下圖所示:
[常見YUV格式]
YUYV,YUYV屬于YUV422,根據上面的圖像也可以看出來,Y和UV是按照(YUYV)(YUYV)(YUYV)...的格式交錯存儲的。
UYVY,UYVY也是YUV422圖像,和YUYV類似,不過是Y和UV的存儲順序按照(UYVY)(UYVY)(UYVY)...的順序存儲的。
YUV422P,屬于YUV422圖像,其中Y、U、V分别連續存儲。
NV21和NV12,這兩種格式都屬于YUV420SP圖像,Y連續存儲,然後是交錯的UV,二者差別是,NV21是V在U前,NV12是U在V前。
YU12和YV12,這兩種格式屬于YUV420P圖像,Y、U、V分别連續存儲。差別是YU12是Y在前,其次是U,最後是V;而YV12是Y在前,其次是V,最後是U。
I420,即YU12圖像。
[YUV圖像處理]
①YUV422和YUV420之間的轉換
YUV422轉YUV420,需要在垂直方向上隔行采樣,隻保留奇數行或偶數行的UV資料。YUV420轉YUV422,需要在垂直方向上,将一行拷貝成兩行。
②YUV轉RGB
YUV和RGB的計算方法,用矩陣公式表示的話,如下圖所示:
如果用算數公式表示的話如下所示:
RGB轉YUV:
Y = 0.299 R + 0.587 G + 0.114 B
U = - 0.1687 R - 0.3313 G + 0.5 B + 128
V = 0.5 R - 0.4187 G - 0.0813 B + 128
YUV轉RGB:
R = Y + 1.402 (V - 128)
G = Y - 0.34414 (U - 128) - 0.71414 (V - 128)
B = Y + 1.772 (U - 128)
注意,這裡隻是單個像素點的轉換方法,圖像裡的批量轉換,還需根據YUV的儲存格式進行考慮。
YUV圖像就先講解到這裡,下一篇我将對YUV圖像和RGB圖像的亮度計算,以及zxing的使用方法進行介紹。