YUV

**YUV**，是一種顏色編碼方法。常使用在各個影像處理元件中。
YUV 在對相片或影片編碼時，考慮到人類的感知能力，允許降低色度的頻寬。

YUV 是編譯 true-color 顏色空間（color space）的種類，Y'UV, YUV, YCbCr，YPbPr 等專有名詞都可以稱為 YUV，彼此有重疊。「Y」表示**明亮度**（Luminance、Luma），「U」和「V」則是**色度**、**濃度**（Chrominance、Chroma），

Y′UV, YUV, YCbCr, YPbPr 所指涉的範圍，常有混淆或重疊的情況。從歷史的演變來說，其中 YUV 和 Y'UV 通常用來編碼電視的類比訊號，而 YCbCr 則是用來描述數位的影像訊號，適合影片與圖片壓縮以及傳輸，例如 MPEG、JPEG。
但在現今，YUV 通常已經在電腦系統上廣泛使用。

Y' 代表明亮度 (luma; brightness) 而 U 與 V 儲存色度 (色訊；chrominance; color) 部分；亮度 (luminance) 記作 Y，而 Y' 的 prime 符號記作伽瑪校正。

YUV Formats 分成兩個格式：

* 緊縮格式（packed formats）：將 Y、U、V 值儲存成 Macro Pixels 陣列，和 RGB 的存放方式類似。
* 平面格式（planar formats）：將 Y、U、V 的三個分量分別存放在不同的矩陣中。

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

## 歷史

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

因為 UV 分別代表不同顏色訊號，所以直接使用 R 與 B 訊號表示色度的 UV。
也就是說 UV 訊號告訴了電視要偏移某象素的的顏色，而不改變其亮度。
或者 UV 訊號告訴了顯示器使得某個顏色亮度依某個基準偏移。
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 等。

### YUY2 及常見表示方法

**YUY2**（和 **YUYV**）格式為像素保留 Y，而 UV 在水平空間上相隔二個像素採樣一次（Y0 U0 Y1 V0），（Y2 U2 Y3 V2）… 其中，（Y0 U0 Y1 V0）就是一個 macro-pixel（宏像素），它表示了 2 個像素，（Y2 U2 Y3 V2）是另外的 2 個像素。
以此類推，再如：Y41P（和 Y411）格式為每個像素保留 Y 分量，而 UV 分量在水平方向上每 4 個像素採樣一次。一個宏像素為 12 個位元組，實際表示 8 個像素。圖像資料中 YUV 分量排列順序如下：（U0 Y0 V0 Y1 U4 Y2 V4 Y3 Y4 Y5 Y6 Y7）…

### YVYU UYVY

**YVYU**, **UYVY** 格式跟 YUY2 類似，只是排列順序有所不同。**Y211** 格式是 Y 每 2 個像素採樣一次，而 UV 每 4 個像素採樣一次。**AYUV** 格式則有一 Alpha 通道。

### YV12

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

排列舉例：**2\*2 圖像** YYYYVU；
**4＊4 圖像** YYYYYYYYYYYYYYYYVVVVUUUU

## 轉換

YUV 與 RGB 的轉換公式：

U 和 V 元件可以被表示成原始的 R，G，和 B（R，G，B 為 γ 預校正後的）:

$$
{\begin{array}{rll}Y&=0.299*R+0.587*G+0.114*B\\U&=-0.169*R-0.331*G+0.5*B+128\\V&=0.5*R-0.419*G-0.081*B+128\end{array}}
$$

如一般順序，轉移元件的範圍可得到：

$$
{\begin{array}{rll}Y&\in \left[0,255\right]\\U&\in \left[0,255\right]\\V&\in \left[0,255\right]\end{array}}
$$

在逆轉關係上，從 YUV 到 RGB，可得

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

取而代之，以矩陣表示法（matrix representation），可得到公式：

$$
{\begin{bmatrix}Y\\U\\V\end{bmatrix}}={\begin{bmatrix}0.299&0.587&0.114\\-0.169&-0.331&0.5\\0.5&-0.419&-0.081\end{bmatrix}}{\begin{bmatrix}R\\G\\B\end{bmatrix}}+{\begin{bmatrix}0\\128\\128\end{bmatrix}}
$$

$$
{\begin{bmatrix}R\\G\\B\end{bmatrix}}={\begin{bmatrix}1&-0.00093&1.401687\\1&-0.3437&-0.71417\\1&1.77216&0.00099\end{bmatrix}}{\begin{bmatrix}Y\\U-128\\V-128\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.

### 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（x264，XviD，DivX），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);
```

## 註釋

## 參見

* 色度抽樣

## 外部連結

* RGB/YUV Pixel Conversion （頁面存檔備份，存於網際網路檔案館）
* Explanation of many different formats in the YUV family （頁面存檔備份，存於網際網路檔案館）
* Charles Poynton - Video engineering （頁面存檔備份，存於網際網路檔案館）
* YUV422 to RGB using SSE/Assembly （頁面存檔備份，存於網際網路檔案館）