From Wikipedia, the free encyclopedia
Jump to: navigation, search
Example of U-V color plane, Y' value = 0.5, represented within RGB color gamut
An image along with its Y', U, and V components respectively.

YUV is a color space typically used as part of a color image pipeline. It encodes a color image or video taking human perception into account, allowing reduced bandwidth for chrominance components, thereby typically enabling transmission errors or compression artifacts to be more efficiently masked by the human perception than using a "direct" RGB-representation. Other color spaces have similar properties, and the main reason to implement or investigate properties of Y'UV would be for interfacing with analog or digital television or photographic equipment that conforms to certain Y'UV standards.

The scope of the terms Y'UV, YUV, YCbCr, YPbPr, etc., is sometimes ambiguous and overlapping. Historically, the terms YUV and Y'UV were used for a specific analog encoding of color information in television systems, while YCbCr was used for digital encoding of color information suited for video and still-image compression and transmission such as MPEG and JPEG. Today, the term YUV is commonly used in the computer industry to describe file-formats that are encoded using YCbCr.

The Y'UV model defines a color space in terms of one luma (Y') and two chrominance (UV) components. The Y'UV color model is used in the PAL and SECAM composite color video standards. Previous black-and-white systems used only luma (Y') information. Color information (U and V) was added separately via a sub-carrier so that a black-and-white receiver would still be able to receive and display a color picture transmission in the receiver's native black-and-white format.

Y' stands for the luma component (the brightness) and U and V are the chrominance (color) components; luminance is denoted by Y and luma by Y' – the prime symbols (') denote gamma compression,[1] with "luminance" meaning perceptual (color science) brightness, while "luma" is electronic (voltage of display) brightness.

The YPbPr color model used in analog component video and its digital version YCbCr used in digital video are more or less derived from it, and are sometimes called Y'UV. (CB/PB and CR/PR are deviations from grey on blue–yellow and red–cyan axes, whereas U and V are blue–luminance and red–luminance differences.) The Y'IQ color space used in the analog NTSC television broadcasting system is related to it, although in a more complex way.

As for etymology, Y, Y', U, and V are not abbreviations. The use of the letter Y for luminance can be traced back to the choice of X Y Z primaries. This lends itself naturally to the usage of the same letter in luma (Y'), which approximates a perceptually uniform correlate of luminance. Likewise, U and V were chosen to differentiate the U and V axes from those in other spaces, such as the x and y chromaticity space. See the equations below or compare the historical development of the math.[2][3][4]



The UV representation of chrominance was chosen over straight R and B signals because U and V are color difference signals. This meant that in a black and white scene the U and V signals would be zero and only the Y' signal would need to be transmitted. If R and B were to have been used, these would have non-zero values even in a B&W scene, requiring all three data-carrying signals. This was important in the early days of color television, because holding the U and V signals to zero while connecting the black and white signal to Y' allowed color TV sets to display B&W TV without the additional expense and complexity of special B&W circuitry. In addition, black and white receivers could take the Y' signal and ignore the color signals, making Y'UV backward-compatible with all existing black-and-white equipment, input and output. It was necessary to assign a narrower bandwidth to the chrominance channel because there was no additional bandwidth available. If some of the luminance information arrived via the chrominance channel (as it would have if RB signals were used instead of differential UV signals), B&W resolution would have been compromised.[6]

Conversion to/from RGB[edit]

Y'UV signals are typically created from RGB (red, green and blue) source. Weighted values of R, G, and B are summed to produce Y', a measure of overall brightness or luminance. U and V are computed as scaled differences between Y' and the B and R values.

Defining the following constants:

W_R &= 0.299 \\
W_G &= 1 - W_R - W_B = 0.587 \\
W_B &= 0.114 \\
U_{Max} &= 0.436 \\
V_{Max} &= 0.615

Y'UV is computed from RGB as follows:

Y' &= W_R R + W_G G + W_B B \\
U &= U_{Max} \frac{B - Y'}{1 - W_B} \approx 0.492(B - Y') \\
V &= V_{Max} \frac{R - Y'}{1 - W_R} \approx 0.877(R - Y')

The resulting ranges of Y', U, and V respectively are [0, 1], [-UMax, UMax], and [-VMax, VMax].

Inverting the above transformation converts Y'UV to RGB:

R &= Y' + V \frac{1 - W_R}{V_{Max}} = Y' +  \frac{V}{0.877}\\
G &= Y' - U \frac{W_B (1 - W_B)}{U_{Max} W_G} - V \frac{W_R (1 - W_R)}{V_{Max} W_G} \\ &= Y' - \frac{0.232 U}{0.587} -  \frac{0.341 V}{0.587} = Y' - 0.395 U - 0.581 V\\
B &= Y' + U \frac{1 - W_B}{U_{Max}} =Y' +  \frac{U}{0.492}

Equivalently, substituting values for the constants and expressing them as matrices gives:

\begin{bmatrix} Y' \\ U \\ V \end{bmatrix}
  0.299   &  0.587   &  0.114 \\
 -0.14713 & -0.28886 &  0.436 \\
  0.615   & -0.51499 & -0.10001

 1 &  0       &  1.13983 \\
 1 & -0.39465 & -0.58060 \\
 1 &  2.03211 &  0


The weights used to compute Y' (top row of matrix) are identical to those used in the Y'IQ color space.



BT.709 and BT.601[edit]

When standardising high-definition video, the ATSC chose a different formula for the YCbCr than that used for standard-definition video. This means that when converting between SDTV and HDTV, the color information has to be altered, in addition to image scaling the video.

The formulae above reference Rec. 601. For HDTV, a slightly different matrix is used, where WR and WB in the above formula is replaced by Rec. 709:

W_R &= 0.2126 \\
W_B &= 0.0722 \\

This gives the matrices :

  0.2126  &  0.7152  &  0.0722 \\
 -0.09991 & -0.33609 &  0.436 \\
  0.615   & -0.55861 & -0.05639

 1 &  0       &  1.28033 \\
 1 & -0.21482 & -0.38059 \\
 1 &  2.12798 &  0

Numerical approximations[edit]

Prior to the development of fast SIMD floating-point processors, most digital implementations of RGB->Y'UV used integer math, in particular fixed-point approximations. In the following examples, the operator "a \gg b" denotes a right-shift of a by b bits.

Traditional 8 bit representation of Y'UV with unsigned integers uses the following

1. Basic transform

  66 & 129 & 25  \\
 -38 & -74 & 112 \\
 112 & -94 & -18

2. Scale down to 8 bits with rounding

Y' &=& (Y' + 128) \gg 8\\
U  &=& (U  + 128) \gg 8\\
V  &=& (V  + 128) \gg 8

3. Shift values

Y' &=& Y' + 16\\
U  &=& U + 128\\
V  &=& V + 128

Y' values are conventionally shifted and scaled to the range [16, 235] (referred to as studio swing or "TV levels") rather than using the full range of [0, 255] (referred to as full swing or "PC levels"). This confusing practice derives from the MPEG standards and explains why 16 is added to Y' and why the Y' coefficients in the basic transform sum to 220 instead of 255.[7] U and V values, which may be positive or negative, are summed with 128 to make them always positive, giving a studio range of 16-240 for U and V. These ranges are important in video editing and production, since using the wrong range will result either in an image with "clipped" blacks and whites, or a low-contrast image.

Luminance/chrominance systems in general[edit]

The primary advantage of luma/chroma systems such as Y'UV, and its relatives Y'IQ and YDbDr, is that they remain compatible with black and white analog television (largely due to the work of Georges Valensi). The Y' channel saves all the data recorded by black and white cameras, so it produces a signal suitable for reception on old monochrome displays. In this case, the U and V are simply discarded. If displaying color, all three channels are used, and the original RGB information can be decoded.





Instead of Y'UV, Y'CbCr was used as the standard format for (digital) common video compression algorithms such as MPEG-2. Digital television and DVDs preserve their compressed video streams in the MPEG-2 format, which uses a full Y'CbCr color space, although retaining the established process of chroma subsampling. The professional CCIR 601 digital video format also uses Y'CbCr at the common chroma subsampling rate of 4:2:2, primarily for compatibility with previous analog video standards. This stream can be easily mixed into any output format needed.

Y'UV is not an absolute color space. It is a way of encoding RGB information, and the actual color displayed depends on the actual RGB colorants used to display the signal. Therefore a value expressed as Y'UV is only predictable if standard RGB colorants are used (i.e. a fixed set of primary chromaticities, or particular set of red, green, and blue).

Furthermore, the range of colors and brightnesses (known as the color gamut) of RGB (whether it be BT.601 or Rec.709) is far smaller than the range of colors and brightnesses allowed by Y'UV. This can be very important when converting from Y'UV (or Y'CbCr) to RGB, since the formulas above can produce "invalid" RGB values – i.e., values below 0% or very far above 100% of the range (e.g. outwith the standard 16-235 luma range (and 16-240 chroma range) for TVs and HD content, or outwith 0-255 for standard definition on PCs). Unless these values are dealt with they will usually be "clipped" (i.e., limited) to the valid range of the channel affected. This changes the hue of the color, so it is therefore often considered better to desaturate the offending colors such that they fall within the RGB gamut.[8] Likewise, when RGB at a given bit depth is converted to YUV at the same bit depth, several RGB colors can become the same Y'UV color, resulting in information loss.

Confusion with Y'CbCr[edit]

Y'UV is often used as the term for YCbCr. However, they are different formats. Y'UV is an analog system with scale factors different from the digital Y'CbCr system.[9]

In digital video/image systems, Y'CbCr is the most common way to express color in a way suitable for compression/transmission. The confusion stems from computer implementations and text-books erroneously using the term YUV where Y'CbCr would be correct.

Types of sampling[edit]

To get a digital signal, Y'UV images can be sampled in several different ways; see chroma subsampling.

Converting between Y'UV and RGB[edit]


r0 = rgb[0];
g0 = rgb[1];
b0 = rgb[2];
r1 = rgb[3];
g1 = rgb[4];
b1 = rgb[5];

Y'UV files can be encoded in 12, 16 or 24 bits per pixel. The common formats are Y'UV444 (or YUV444), YUV411, Y'UV422 (or YUV422) and Y'UV420p (or YUV420). The apostrophe after the Y is often omitted, as is the "p" after YUV420p. In terms of actual file formats, YUV420 is the most common, as the data is more easily compressed, and the file extension is usually ".YUV". The relation between data rate and sampling (A:B:C) is defined by the ratio between Y to U and V channel.[10][11]


YUV444    3 bytes per pixel
YUV422    4 bytes per 2 pixels
YUV411    6 bytes per 4 pixels
YUV420p   6 bytes per 4 pixels, reordered

Y'UV444 to RGB888 conversion[edit]

The function [R, G, B] = Y'UV444toRGB888(Y', U, V) converts Y'UV format to simple RGB format


These formulae are based on the 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


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

Using the previous coefficients and noting that clamp() denotes clamping a value to the range of 0 to 255, the following formulae provide the conversion from Y'UV to RGB (NTSC version):

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


The ITU-R version of the formulae is different:

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 = \mathrm{clamp}(Y + 1.402 \times (Cr - 128))
G = \mathrm{clamp}(Y - 0.344 \times (Cb - 128) - 0.714 \times (Cr - 128))
B = \mathrm{clamp}(Y + 1.772 \times (Cb - 128))


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 to RGB888 conversion[edit]

Input: Read 4 bytes of Y'UV (u, y1, v, y2 )
u  = yuv[0];
y1 = yuv[1];
v  = yuv[2];
y2 = yuv[3];

Using this information it could be parsed as regular Y'UV444 format to get 2 RGB pixels info:

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


Y'UV411 to RGB888 conversion[edit]

Input: Read 6 bytes of Y'UV
Output: Writes 12 bytes of RGB
// 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);


Y'UV420p (and Y'V12 or YV12) to RGB888 conversion[edit]

Y'UV420p is a planar format, meaning that the Y', U, and V values are grouped together instead of interspersed. The reason for this is that by grouping the U and V values together, the image becomes much more compressible. When given an array of an image in the Y'UV420p format, all the Y' values come first, followed by all the U values, followed finally by all the V values.

The Y'V12 format is essentially the same as Y'UV420p, but it has the U and V data switched: the Y' values are followed by the V values, with the U values last. As long as care is taken to extract U and V values from the proper locations, both Y'UV420p and Y'V12 can be processed using the same algorithm.

As with most Y'UV formats, there are as many Y' values as there are pixels. Where X equals the height multiplied by the width, the first X indices in the array are Y' values that correspond to each individual pixel. However, there are only one fourth as many U and V values. The U and V values correspond to each 2 by 2 block of the image, meaning each U and V entry applies to four pixels. After the Y' values, the next X/4 indices are the U values for each 2 by 2 block, and the next X/4 indices after that are the V values that also apply to each 2 by 2 block.

Translating Y'UV420p to RGB is a more involved process compared to the previous formats. Lookup of the Y', U and V values can be done using the following method:

size.total = size.width * size.height;
y = yuv[position.y * size.width + position.x];
rgb = Y'UV444toRGB888(y, u, v);

Here "/" is Div not division.


As shown in the above image, the Y', U and V components in Y'UV420 are encoded separately in sequential blocks. A Y' value is stored for every pixel, followed by a U value for each 2×2 square block of pixels, and finally a V value for each 2×2 block. Corresponding Y', U and V values are shown using the same color in the diagram above. Read line-by-line as a byte stream from a device, the Y' block would be found at position 0, the U block at position x×y (6×4 = 24 in this example) and the V block at position x×y + (x×y)/4 (here, 6×4 + (6×4)/4 = 30).

Y'UV420sp (NV21) to ARGB8888 conversion[edit]


Java source code used on Android:

 * Converts YUV420 NV21 to ARGB8888
 * @param data byte array on YUV420 NV21 format.
 * @param width pixels width
 * @param height pixels height
 * @return a ARGB8888 pixels int array. Where each int is a pixels ARGB. 
public static int[] convertYUV420_NV21toARGB8888(byte [] data, int width, int height) {
    int size = width*height;
    int u_offset = size;  
    int v_offset = size * 1.25;
    int[] pixels = new int[size];
    int u, v, y1, y2, y3, y4;
    // i along Y and the final pixels
    // k along pixels U and V
    for(int i=0, k=0; i < size; i+=2, k++) {
    	y1 = data[i  ]&0xff;
    	y2 = data[i+1]&0xff;
    	y3 = data[width+i  ]&0xff;
    	y4 = data[width+i+1]&0xff;
    	v = data[v_offset + k]&0xff;
    	u = data[u_offset + k]&0xff;
    	v = v-128;
    	u = u-128;
    	pixels[i  ] = convertYUVtoARGB(y1, u, v);
    	pixels[i+1] = convertYUVtoARGB(y2, u, v);
    	pixels[width+i  ] = convertYUVtoARGB(y3, u, v);
    	pixels[width+i+1] = convertYUVtoARGB(y4, u, v);
    	if (i!=0 && (i+2)%width==0)
    		i += width;
    return pixels;
private static int convertYUVtoARGB(int y, int u, int v) {
    int r = y + (int)(1.772f*v);
    int g = y - (int)(0.344f*v + 0.714f*u);
    int b = y + (int)(1.402f*u);
    r = r>255? 255 : r<0 ? 0 : r;
    g = g>255? 255 : g<0 ? 0 : g;
    b = b>255? 255 : b<0 ? 0 : b;


  2. ^ CIELUV
  3. ^ CIE 1960 color space
  4. ^ Macadam, David L. (8/1/1937). "Projective Transformations of I. C. I. Color Specifications". Journal of the Optical society of America 27 (8): 294–297. doi:10.1364/JOSA.27.000294. Retrieved 12 April 2014. 
  9. ^ Poynton, Charles (1999-06-19). YUV and luminance considered harmful. Retrieved 2008-08-22. 
  10. ^ msdn.microsoft.com, Recommended 8-Bit YUV Formats for Video Rendering
  11. ^ msdn.microsoft.com, YUV Video Subtypes
  12. ^ fourcc.com YUV pixel formas

External links[edit]