【Codecs】圖文詳解YUV420/YUV422數據格式(很全面)


###Date:2018.5.24

===============================================================

轉載自:http://www.360doc.com/content/18/0524/09/55952130_756582907.shtml#

一.YUV格式與RGB格式的換算

關於YUV與RGB轉換


以下是標准公式
  • RGB 轉換成 YUV
Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16 
Cr = V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128 
Cb = U = -( 0.148 * R) - (0.291 * G) + (0.439 * B) + 128
  • YUV 轉換成 RGB
B = 1.164(Y - 16) + 2.018(U - 128) 
G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) 
R = 1.164(Y - 16) + 1.596(V - 128)

RGB取值范圍均為0~255,Y=0~255,U=-122~+122,V=-157~+157
以下是經過簡化的公式,運算量比上述公式要小一些。
  • RGB轉YUV
Y = 0.299R + 0.587G + 0.114B 
U'= (BY)*0.565 
V'= (RY)*0.713
  • YUV轉RGB
R = Y + 1.403V' 
G = Y - 0.344U' - 0.714V' 
B = Y + 1.770U'

RGB轉灰度整數算法

  而實際應用時,希望避免低速的浮點運算,所以需要整數算法。
  注意到系數都是3位精度的沒有,我們可以將它們縮放1000倍來實現整數運算算法:

                          Gray = (R*299 + G*587 + B*114 + 500) / 1000

  RGB一般是8位精度,現在縮放1000倍,所以上面的運算是32位整型的運算。注意后面那個除法是整數除法,所以需要加上500來實現四舍五入。
  就是由於該算法需要32位運算,所以該公式的另一個變種很流行:

                          Gray = (R*30 + G*59 + B*11 + 50) / 100

  但是,雖說上一個公式是32位整數運算,但是根據80x86體系的整數乘除指令的特點,是可以用16位整數乘除指令來運算的。而且現在32位早普及了(AMD64都出來了),所以推薦使用上一個公式。


   如果只有Y信號分量而沒有U、V分量,那么這樣表示的圖像就是黑白灰度圖像。因此用YUV格式由彩色轉黑白信號相當簡單. 
   在技術文檔里,YUV經常有另外的名字, YCbCr ,其中Y與YUV 中的Y含義一致,Cb , Cr 同樣都指色彩,,只是在表示方法上不同而已,Cb Cr 就是本來理論上的“分量/色差”的標識。C代表分量(是component的縮寫)Cr、Cb分別對應r(紅)、b(藍)分量信號,Y除了g(綠)分量信 號,還疊加了亮度信號。

   還有一種格式是YPbPr格式,它與YCbPr格式的區別在於,其中YCbCr是隔行信號,YPbPr是逐行信號。
數字信號都是YCbCr ,其應用領域很廣泛,JPEG、MPEG均采用此格式。在后文中,如無特別指明,講的YUV都是指YCbCr格式。

  而YPbPr一般是模擬信號,我引用兩段來說明兩者區別
  1.   什么是YCbCr?
  2.   YCbCr表示隔行分量端子,是屬於YUV經過縮放和偏移的翻版,常說的YUV也稱 作YCbCr。其中Y與YUV 中的Y含義一致,Cb , Cr 同樣都指色彩,,只是在表示方法上不同而已,Cb Cr 就是本來理論上的“分量/色差”的標識。C代表分量(是component的縮寫)Cr、Cb分別對應r(紅)、b(藍)分量信號,Y除了g(綠)分量信 號,還疊加了亮度信號。
  3.   其中YCbCr是隔行信號,YPbPr是逐行信號。YCbCr 是在計算機系統中應用最多的一種信號,其應用領域很廣泛,JPEG、MPEG均采用此格式。
  4.   什么是YPbPr?
  5.    Y'CbCr 在模擬分量視頻(analog component video)中也常被稱為YPbPr,YPbPr是將模擬的Y、PB、PR信號分開,使用三條線纜來獨立傳輸,保障了色彩還原的准確性,YPbPr表示逐 行掃描色差輸出.YPbPr接口可以看做是S端子的擴展,與S端子相比,要多傳輸PB、PR兩種信號,避免了兩路色差混合解碼並再次分離的過程,也保持了 色度通道的最大帶寬,只需要經過反矩陣解碼電路就可以還原為RGB三原色信號而成像,這就最大限度地縮短了視頻源到顯示器成像之間的視頻信號通道,避免了 因繁瑣的傳輸過程所帶來的圖像失真,保障了色彩還原的准確,目前幾乎所有大屏幕電視都支持色差輸入。
二.YUV的存儲格式
 
  RGB格式中,一個24bpp像素要占用4字節空間。在YUV格式中,可以對於UV分量的數據壓縮,但是對圖像整體質量影響不大,這樣YUV所占的空間就比RGB要小一些
不過RGB中 16bpp的 565格式每一個點只占2個字節,從這一點看也沒有省多少。不過視頻應用都是清一色的YUV應用。因此YUV的處理還是一個比較重要課題。

  YUV的存儲中與RGB格式最大不同在於,RGB格式每個點的數據是連繼保存在一起的。即R,G,B是前后不間隔的保存在2-4byte空間中。而YUV 的數據中為了節約空間,U,V分量空間會減小。每一個點的Y分量獨立保存,但連續幾個點的U,V分量是保存在一起的,(反正人眼一般也看不出區別).這幾 個點合起來稱為macro-pixel, 這種存儲格式稱為Packed格式。
  另外一種存儲格式是把一幅圖像中Y,U,V分別用三個獨立的數組表示。這種模式稱為planar模式。

YUV格式有兩大類:planar和packed。對於planar的YUV格式,先連續存儲所有像素點的Y,緊接着存儲所有像素點的U,隨后是所有像素點的V。
對於packed的YUV格式,每個像素點的Y,U,V是連續交*存儲的。

YUV,分為三個分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的則是色度(Chrominance或Chroma),作用是描述影像色彩及飽和度,用於指定像素的顏色。

    與我們熟知的RGB類似,YUV也是一種顏色編碼方法,主要用於電視系統以及模擬視頻領域,它將亮度信息(Y)與色彩信息(UV)分離,沒有UV信息一樣可以顯示完整的圖像,只不過是黑白的,這樣的設計很好地解決了彩色電視機與黑白電視的兼容問題。並且,YUV不像RGB那樣要求三個獨立的視頻信號同時傳輸,所以用YUV方式傳送占用極少的頻寬。

YUV碼流的存儲格式其實與其采樣的方式密切相關,主流的采樣方式有三種,YUV4:4:4,YUV4:2:2,YUV4:2:0,關於其詳細原理,可以通過網上其它文章了解,這里我想強調的是如何根據其采樣格式來從碼流中還原每個像素點的YUV值,因為只有正確地還原了每個像素點的YUV值,才能通過YUV與RGB的轉換公式提取出每個像素點的RGB值,然后顯示出來。

    用三個圖來直觀地表示采集的方式吧,以黑點表示采樣該像素點的Y分量,以空心圓圈表示采用該像素點的UV分量。

 

先記住下面這段話,以后提取每個像素的YUV分量會用到。

  1. YUV 4:4:4采樣,每一個Y對應一組UV分量。
  2. YUV 4:2:2采樣,每兩個Y共用一組UV分量。 
  3. YUV 4:2:0采樣,每四個Y共用一組UV分量。 

2.  存儲方式

    下面我用圖的形式給出常見的YUV碼流的存儲方式,並在存儲方式后面附有取樣每個像素點的YUV數據的方法,其中,Cb、Cr的含義等同於U、V。

(1) YUVY 格式 (屬於YUV422)

YUYV為YUV422采樣的存儲格式中的一種,相鄰的兩個Y共用其相鄰的兩個Cb、Cr,分析,對於像素點Y'00、Y'01 而言,其Cb、Cr的值均為 Cb00、Cr00,其他的像素點的YUV取值依次類推。 
(2) UYVY 格式 (屬於YUV422)
UYVY格式也是YUV422采樣的存儲格式中的一種,只不過與YUYV不同的是UV的排列順序不一樣而已,還原其每個像素點的YUV值的方法與上面一樣。
(3) YUV422P(屬於YUV422)
 
YUV422P也屬於YUV422的一種,它是一種Plane模式,即平面模式,並不是將YUV數據交錯存儲,而是先存放所有的Y分量,然后存儲所有的U(Cb)分量,最后存儲所有的V(Cr)分量,如上圖所示。其每一個像素點的YUV值提取方法也是遵循YUV422格式的最基本提取方法,即兩個Y共用一個UV。比如,對於像素點Y'00、Y'01 而言,其Cb、Cr的值均為 Cb00、Cr00。
(4)YV12,YU12格式(屬於YUV420)

YU12和YV12屬於YUV420格式,也是一種Plane模式,將Y、U、V分量分別打包,依次存儲。其每一個像素點的YUV數據提取遵循YUV420格式的提取方式,即4個Y分量共用一組UV。注意,上圖中,Y'00、Y'01、Y'10、Y'11共用Cr00、Cb00,其他依次類推。

(5)NV12、NV21(屬於YUV420)

NV12和NV21屬於YUV420格式,是一種two-plane模式,即Y和UV分為兩個Plane,但是UV(CbCr)為交錯存儲,而不是分為三個plane。其提取方式與上一種類似,即Y'00、Y'01、Y'10、Y'11共用Cr00、Cb00

YUV420 planar數據, 以720×488大小圖象YUV420 planar為例,

其存儲格式是: 共大小為(720×480×3>>1)字節,

分為三個部分:Y,U和V

Y分量:    (720×480)個字節  

U(Cb)分量:(720×480>>2)個字節

V(Cr)分量:(720×480>>2)個字節

三個部分內部均是行優先存儲,三個部分之間是Y,U,V 順序存儲。

即YUV數據的0--720×480字節是Y分量值,         

720×480--720×480×5/4字節是U分量    

720×480×5/4 --720×480×3/2字節是V分量。

4 :2: 2 和4:2:0 轉換:

最簡單的方式:

YUV4:2:2 ---> YUV4:2:0  Y不變,將U和V信號值在行(垂直方向)在進行一次隔行抽樣。 YUV4:2:0 ---> YUV4:2:2  Y不變,將U和V信號值的每一行分別拷貝一份形成連續兩行數據。

在YUV420中,一個像素點對應一個Y,一個4X4的小方塊對應一個U和V。對於所有YUV420圖像,它們的Y值排列是完全相同的,因為只有Y的圖像就是灰度圖像。YUV420sp與YUV420p的數據格式它們的UV排列在原理上是完全不同的。420p它是先把U存放完后,再存放V,也就是說UV它們是連續的。而420sp它是UV、UV這樣交替存放的。(見下圖) 有了上面的理論,我就可以准確的計算出一個YUV420在內存中存放的大小。 

width * hight =Y(總和) U = Y / 4   V = Y / 4

所以YUV420 數據在內存中的長度是 width * hight * 3 / 2,

假設一個分辨率為8X4的YUV圖像,它們的格式如下圖:

                      YUV420sp格式如下圖

             

                        YUV420p數據格式如下圖

           

 

旋轉90度的算法:

public static void rotateYUV240SP(byte[] src,byte[] des,int width,int height)
 {
    
  int wh = width * height;
  //旋轉Y
  int k = 0;
  for(int i=0;i<width;i++) {
   for(int j=0;j<height;j++) 
   {
               des[k] = src[width*j + i];   
         k++;
   }
  }
  
  for(int i=0;i<width;i+=2) {
   for(int j=0;j<height/2;j++) 
   { 
               des[k] = src[wh+ width*j + i]; 
               des[k+1]=src[wh + width*j + i+1];
         k+=2;
   }
  }

YV12和I420的區別        一般來說,直接采集到的視頻數據是RGB24的格式,RGB24一幀的大小size=width×heigth×3 Bit,RGB32的size=width×heigth×4,如果是I420(即YUV標准格式4:2:0)的數據量是 size=width×heigth×1.5 Bit。       在采集到RGB24數據后,需要對這個格式的數據進行第一次壓縮。即將圖像的顏色空間由RGB2YUV。因為,X264在進行編碼的時候需要標准的YUV(4:2:0)。但是這里需要注意的是,雖然YV12也是(4:2:0),但是YV12和I420的卻是不同的,在存儲空間上面有些區別。如下: YV12 : 亮度(行×列) + U(行×列/4) + V(行×列/4)

I420 : 亮度(行×列) + V(行×列/4) + U(行×列/4)

可以看出,YV12和I420基本上是一樣的,就是UV的順序不同。

繼續我們的話題,經過第一次數據壓縮后RGB24->YUV(I420)。這樣,數據量將減少一半,為什么呢?呵呵,這個就太基礎了,我就不多寫了。同樣,如果是RGB24->YUV(YV12),也是減少一半。但是,雖然都是一半,如果是YV12的話效果就有很大損失。然后,經過X264編碼后,數據量將大大減少。將編碼后的數據打包,通過RTP實時傳送。到達目的地后,將數據取出,進行解碼。完成解碼后,數據仍然是YUV格式的,所以,還需要一次轉換,這樣windows的驅動才可以處理,就是YUV2RGB24。

YUY2  是 4:2:2  [Y0 U0 Y1 V0]

yuv420p 和 YUV420的區別 在存儲格式上有區別
yuv420p:yyyyyyyy uuuuuuuu vvvvv yuv420: yuv yuv yuv

     YUV420P,Y,U,V三個分量都是平面格式,分為I420和YV12。I420格式和YV12格式的不同處在U平面和V平面的位置不同。在I420格式中,U平面緊跟在Y平面之后,然后才是V平面(即:YUV);但YV12則是相反(即:YVU)。
YUV420SP, Y分量平面格式,UV打包格式, 即NV12。 NV12與NV21類似,U 和 V 交錯排列,不同在於UV順序。
I420: YYYYYYYY UU VV    =>YUV420P
YV12: YYYYYYYY VV UU    =>YUV420P
NV12: YYYYYYYY UVUV     =>YUV420SP
NV21: YYYYYYYY VUVU     =>YUV420SP

Four CC 碼

  關於YUV444,YUV422,YUV420的名稱還有別外一種命名方式, FOURCC 碼,上文中用就是這個命令,這Four CC使用四個字母的命名,
   FourCC全稱Four-Character Codes,是由4個字符(4 bytes)組成,是一種獨立標示視頻數據流格式的四字節,在wav、avi檔案之中會有一段FourCC來描述這個AVI檔案,是利用何種codec來 編碼的。因此wav、avi大量存在等於“IDP3”的FourCC

按fourcc的命名.

YUV444 的FourCC 稱為  AYUV
YUV422 的FourcCC 按字節序分為  YUY2 和 UYVY
YUV420 的FourcCC 按字節序分為  IMC1  和 IMC2

V4L2 采用編碼
  我們一般是在V4L驅動里使用這一些編碼,而且V4L2也有一類對應的編碼.參見vedio2dev.h,在編程中要與實際排列對應上.它后面的定義值實際就是FourCC 碼.

  #define V4L2_PIX_FMT_YVU420  v4l2_fourcc('Y', 'V', '1', '2') /* 12  YVU 4:2:0     */
#define V4L2_PIX_FMT_YUYV    v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16  YUV 4:2:2     */
#define V4L2_PIX_FMT_UYVY    v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16  YUV 4:2:2     */
#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16  YVU422 planar */
#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16  YVU411 planar */
#define V4L2_PIX_FMT_Y41P    v4l2_fourcc('Y', '4', '1', 'P') /* 12  YUV 4:1:1     */
#define V4L2_PIX_FMT_YUV444  v4l2_fourcc('Y', '4', '4', '4') /* 16  xxxxyyyy uuuuvvvv */
#define V4L2_PIX_FMT_YUV555  v4l2_fourcc('Y', 'U', 'V', 'O')
比如在CMOS攝像頭里 支持
  V4L2_PIX_FMT_YVU420 ,它對應的是YV12 格式,查相應文檔,它是Plane格式,即Y,U,V分三個區排列
 
YV12 0x32315659 12 8 bit Y plane followed by 8 bit 2x2 subsampled V and U planes.

This is the format of choice for many software MPEG codecs. It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes.
  Horizontal Vertical
Y Sample Period 1 1
V Sample Period 2 2
U Sample Period 2 2

   

Positive biHeight implies top-down image (top line first)


YUV

YUV,是一種顏色編碼方法。 

YUV是編譯true-color顏色空間(color space)的種類,Y'UV, YUV, YCbCrYPbPr等專有名詞都 可以稱為YUV,彼此有重疊。“Y”表示明亮度(Luminance、Luma),“U”和“V”則是色度濃度(Chrominance、Chroma),Y'UV, YUV, YCbCr, YPbPr 常常有些混用的情況,其中 YUV 和 Y'UV 通常用來描述類比訊號,而相反的 YCbCr 與 YPbPr 則是用來描述數位的影像訊號,例如在一些壓縮格式內 MPEG、JPEG 中,但在現今,YUV 通常已經在電腦系統上廣泛使用。YUV Formats分成兩個格式:

  • 緊縮格式(packed formats):將Y、U、V值儲存成Macro Pixels陣列,和RGB的 存放方式類似。
  • 平面格式(planar formats):將Y、U、V的三個份量分別存放在不同的矩陣中。

緊縮格式(packed format)中的YUV是混合在一起的,對於YUV4:4:4格式而言,用緊縮格式很合適的,因此就有了UYVY、YUYV等。平面格式(planar formats)是指每Y份量,U份量和V份量都是以獨立的平面組織的,也就是說所有的U份量必須在Y份量后面,而V份量在所有的U份量后面,此一格式適 用於采樣(subsample)。平面格式(planar format)有I420(4:2:0)、YV12、IYUV等。

 
U-V color plane范例,Y value = 0.5,代表RGB色域(color gamut)

[歷史]

Y'UV 的發明是由於彩色電視黑白電視的過渡時期[1]。 黑白視訊只有 Y(Luma,Luminance)視訊,也就是灰階值。到了彩色電視規格的制定,是以 YUV/YIQ 的格式來處理彩色電視圖像,把 UV 視作表示彩度的 C(Chrominance或Chroma),如果忽略 C 訊號,那么剩下的 Y(Luma)訊號就跟之前的黑白電視訊號相同,這樣一來便解決彩色電視機與黑白電視機的相容問題。Y'UV 最大的優點在於只需占用極少的帶寬。

彩色圖像記錄的格式,常見的有 RGB、YUV、CMYK等。彩色電視最早的構想是使用RGB三原色來同時傳輸。這種設計方式是原來黑白帶寬的3倍,在 當時並不是很好的設計。RGB 訴求於人眼對色彩的感應,YUV則着重於視覺對於亮度的敏感程度,Y 代表的是亮度,UV 代表的是彩度(因此黑白電影可省略UV,相近於RGB),分別用Cr和CB來表示,因此YUV的記錄通常以 Y:UV 的格式呈現。

常用的YUV格式

為節省帶寬起見,大多數 YUV 格式平均使用的每像素位數都少於24位元。主要的采樣(subsample)格式有YCbCr 4:2:0、YCbCr 4:2:2、YCbCr 4:1:1和 YCbCr 4:4:4。YUV的表示法稱為 A:B:C 表示法:

  • 4:4:4 表示完全取樣。
  • 4:2:2 表示 2:1 的水平取樣,沒有垂直下采樣。
  • 4:2:0 表示 2:1 的水平取樣,2:1 的垂直下采樣。
  • 4:1:1 表示 4:1 的水平取樣,沒有垂直下采樣。

最常用Y:UV記錄的比重通常 1:1 或 2:1,DVD-Video 是以 YUV 4:2:0 的方式記錄,也就是我們俗稱的I420,YUV4:2:0 並不是說只有U(即 Cb), V(即 Cr)一定為 0,而是指U:V互相援引,時見時隱,也就是說對於每一個行,只有一個U或者V份量,如果一行是4:2:0的話,下一行就是4:0:2,再下一行是 4:2:0...以此類推。至於其他常見的YUV格式有YUY2、YUYV、YVYU、UYVY、AYUV、Y41P、Y411、Y211、IF09、 IYUV、YV12、YVU9、YUV411、YUV420等。

 

圖中的Y', U和V組成

 YUY2

YUY2(和YUYV)格式為像素保留 Y,而 UV 在水平空間上相隔二個像素采樣一次。YVYUUYVY格式跟YUY2類似,只是排列順序有所不同。Y211格式是Y每2個像素采樣一次,而UV每4個像素采樣一次。AYUV格 式則有一 Alpha通道。

 YV12

YV12格式與IYUV類似,每個像素都提取Y,在UV提取時,將圖像2 x 2的矩陣,每個元素中提取一個U和一個V。YV12格式和I420格式的不同處在V平面和U平面的位置不同。在I420格式中,U平面緊跟在Y平面之后, 然后才是V平面(即:YUV);但YV12則是相反(即:YVU)。NV12與YV12類似,效果一樣,YV12中 U 和 V 是連續排列的,而在NV12中,U 和 V 就交錯排列的。

轉換

YUV 與 RGB 的轉換公式:

\begin{array}{rll}Y &= 0.299 * R + 0.587 * G + 0.114 * B \U &= 0.436 * (B - Y) / (1 - 0.114) \V &= 0.615 * (R - Y) / (1 - 0.299)\end{array}

U 和 V 元件可以被表示成原始的 R、 G,和 B:

\begin{array}{rll}Y &= 0.299 * R + 0.587 * G + 0.114 * B \U &= -0.14713 * R - 0.28886 * G + 0.436 * B \V &= 0.615 * R - 0.51499 * G - 0.10001 * B\end{array}

如一般順序,轉移元件的范圍可得到:

\begin{array}{rll}Y & \in \left[0, 1\right] \U & \in \left[-0.436, 0.436\right] \V & \in \left[-0.615, 0.615\right]\end{array}

在逆轉關系上,從 YUV 到 RGB,可得

\begin{array}{rll}R & = Y + 1.13983 * V \G & = Y - 0.39465 * U - 0.58060 * V \B & = Y + 2.03211 * U\end{array}

取而代之,以矩陣表示法(matrix representation),可得到公式:

\begin{bmatrix} Y \\ U \\ V \end{bmatrix}=\begin{bmatrix} 0.299 & 0.587 & 0.114 \\ -0.14713 & -0.28886 & 0.436 \\ 0.615 & -0.51498 & -0.10001 \end{bmatrix}\begin{bmatrix} R \\ G \\ B \end{bmatrix}

\begin{bmatrix} R \\ G \\ B \end{bmatrix}=\begin{bmatrix} 1 & 0 & 1.13983 \\ 1 & -0.39465 & -0.58060 \\ 1 & 2.03211 & 0 \end{bmatrix}\begin{bmatrix} Y \\ U \\ V \end{bmatrix}

YUV 轉 RGB

function RGB* YUV444toRGB888(Y, U, V);將 YUV format 移轉成簡單的 RGB format 並可以用浮點運算實作:

Y'UV444

大多數 YUV 格式平均使用的每像素位數都少於24位元。YUV444是最逼真的格式,一格不刪(24 bits),即每4個Y,配上4個 U,還有4個 V;YUV422則是在UV格式上減半,即每4個Y,配2個U,2個V ;YUV420則是在UV上減1/4之格式,即每4個Y,配1個U,再配1個V。

這些公式是基於 NTSC standard;

Y' =  0.299 \times R + 0.587 \times G + 0.114 \times B
U  = -0.147 \times R - 0.289 \times G + 0.436 \times B
V  =  0.615 \times R - 0.515 \times G - 0.100 \times B

在早期的非SIMD(non-SIMD)構造中,floating point arithmetic 會比 fixed-point arithmetic 稍慢,所以有一替代公式如下:

C = Y' - 16
D = U - 128
E = V - 128

使用前面的系數並且用 clip() 注明切割的值域是 0 至 255,如下的公式是從 Y'UV 到 RGB (NTSC version):

R = clip(( 298 \times C                + 409 \times E + 128) >> 8)
G = clip(( 298 \times C - 100 \times D - 208 \times E + 128) >> 8)
B = clip(( 298 \times C + 516 \times D                + 128) >> 8)

注意:上述的公式多暗示為 YCbCr. 雖然稱為 YUV,但應該嚴格區分 YUV 和 YCbCr 這兩個專有名詞有時並非完全相同。

ITU-R 版本的公式差異:

Y  = 0.299 \times R + 0.587 \times G + 0.114 \times B + 0
Cb = -0.169 \times R - 0.331 \times G + 0.499 \times B + 128
Cr = 0.499 \times R - 0.418 \times G - 0.0813 \times B + 128
R = clip(Y + 1.402 \times (Cr - 128))
G = clip(Y - 0.344 \times (Cb - 128) - 0.714 \times (Cr - 128))
B = clip(Y + 1.772 \times (Cb - 128))

ITU-R 標准 YCbCr(每一通道8位元)至 RGB888:

Cr = Cr - 128; Cb = Cb - 128;

R = Y + Cr + Cr > > 2 + Cr > > 3 + Cr > > 5
G = Y ? (Cb > > 2 + Cb > > 4 + Cb > > 5) ? (Cr > > 1 + Cr > > 3 + Cr > > 4 + Cr > > 5)
B = Y + Cb + Cb > > 1 + Cb > > 2 + Cb > > 6

Y'UV422

Input:讀取 Y'UV 的4bytes(u, y1, v, y2 )
Output:寫入 RGB的6bytes (R, G, B, R, G, B)
u  = yuv[0];
y1 = yuv[1];
v  = yuv[2];
y2 = yuv[3];

以此一資訊可以剖析出 regular Y'UV444 格式而成為 2 RGB pixels info:

rgb1 = Y'UV444toRGB888(y1, u, v);
rgb2 = Y'UV444toRGB888(y2, u, v);

Y'UV422 可被表達成 Y'UY'2 FourCC 格式碼。意思是 2 pixels 將被定義成 each macropixel (four bytes) treated in the image. 

Yuv422 yuy2.svg

Y'UV411

// Extract YUV components
u  = yuv[0];
y1 = yuv[1];
y2 = yuv[2];
v  = yuv[3];
y3 = yuv[4];
y4 = yuv[5];
rgb1 = Y'UV444toRGB888(y1, u, v);
rgb2 = Y'UV444toRGB888(y2, u, v);
rgb3 = Y'UV444toRGB888(y3, u, v);
rgb4 = Y'UV444toRGB888(y4, u, v);

所以結果會得到 4 RGB 像素的值 (4*3 bytes) from 6 bytes. This means reducing size of transferred data to half and with quite good loss of quality.

YV12

The Y'V12 的格式相當類似 Y'UV420p,但 U 與 V 資料反轉:Y' 跟隨着 V, U 殿后。Y'UV420p 與 Y'V12 使用相同算法。許多重要的編碼器都采用YV12空間存儲視頻:MPEG-4(x264XviDDivX),DVD- Video存儲格式MPEG-2,MPEG-1以及MJPEG。

將Y'UV420p 轉換成 RGB

Height = 16;
Width  = 16;
Y'ArraySize = Height × Width;    // (256)
Y' = Array[7 × Width + 5];
U = Array[(7/2) × (Width/2) + 5/2 + Y'ArraySize];
V = Array[(7/2) × (Width/2) + 5/2 + Y'ArraySize + Y'ArraySize/4];

RGB = Y'UV444toRGB888(Y', U, V);

Yuv420.svg

參考:https://en.wikipedia.org/wiki/Talk%3AYCbCr



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM