天天看點

Android二維碼掃描開發(二):YUV圖像格式詳解

上一篇中,我們了解了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資料,那麼下面幾種采樣如下圖所示:

Android二維碼掃描開發(二):YUV圖像格式詳解

[存儲方式]

YUV資料的存儲方式分為打包的(packed)和平面的(planar)。

packed存儲方式是,每一組YUV作為一個連續存儲,每個組後面跟着另外一組,常見的有UYVY、YUYV等類型,以YUYV(屬于YUV422)為例,儲存方式如下圖所示:

Android二維碼掃描開發(二):YUV圖像格式詳解

從上圖中可以看出,兩個相鄰的Y共用一組UV,Y和UV是交錯儲存的。

planar儲存方式是,先是連續的Y,然後是連續的UV,UV可以交錯也可以不交錯。以YUV420為例,YUV420分為YUV420P和YUV420SP,差別是YUV420P中U和V是分開連續存儲的,YUV420SP中,UV是交錯存儲的。如下圖所示:

Android二維碼掃描開發(二):YUV圖像格式詳解

[常見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的計算方法,用矩陣公式表示的話,如下圖所示:

Android二維碼掃描開發(二):YUV圖像格式詳解

如果用算數公式表示的話如下所示:

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的使用方法進行介紹。