Introduction

This article is for beginners in image processing especially those who like to do in C++. Here I am try to describes the logic of
RGB to YCbCr conversion and Chroma sampling. We can find many articles over the internet, which explains the logic and theories behind this conversion. But it
is hard to find a C++ code that uses different Chroma sampling schemes. One more thing, this is not a robust code, if you want to use it in your project
please re-write it according to your skill.

According to wiki “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…. “You can read more from http://en.wikipedia.org/wiki/YUV.

In simple sentence, YUV is an image compression technique or part of an image compression technique which omits some details from the
image, which cannot be detected by human eye. In YUV, Y represents luminance or light intensity of the image; U and V are the color components. During image
compression we cannot omit any luminance[Y] information but we can omit some color or chrominance components based on Chroma sub sampling schemas.

Before going to the next line you should ensure that you have a better understanding about the YUV color space.

How it Works

It’s a simple arithmetic to convert RGB to YUV. The formula
is based on the relative contributions that red, green, and blue make to the
luminance and chrominance factors. There are several different formulas in use
depending on the target monitor.<o:p />

Here I am chooses ITU-R version formula<o:p />

RGB to YUV<o:p />

Y = 0.299 * R + 0.587 * G +
0.114 * B<o:p />

U = -0.1687 * R – 0.3313* G
+ 0.5 * B + 128<o:p />

V = 0.5 * R – 0.4187 * G –
0.813 * B + 128

YUV to RGB<o:p />

R = Y+ 0 * U + 1.13983 * V<o:p />

G = Y+ -0.39465 * U + -0.58060
* V<o:p />

B = Y+ -0.03211 * U + 0 * V<o:p />

Now we have the YUV data and it’s time to apply Chroma sampling,
all about Chroma sampling is shown in the below image. <o:p />

The available chroma samplings are given below<o:p />

Chroma Sampling<o:p />

Output Y size corresponding to a 4x4 block<o:p />

4:4:4<o:p />

Y - for each pixel, Cr and Cb-For each pixel<o:p />

4:4: 0<o:p />

Y - for each pixel, Cr and Cr For each pixel of alternate rows<o:p />

4:2:2<o:p />

Y - for each pixel, Cr and Cr For each pixel of alternate columns<o:p />

4:2: 0<o:p />

Y - for each pixel, Cr and Cr For each pixel of alternate columns
and rows<o:p />

4:1:1<o:p />

Y - for each pixel, Cr and Cr For each pixel of every 4th columns<o:p />

4:1: 0<o:p />

Y - for each pixel, Cr and Cr For each pixel of every 4th columns
and rows<o:p />

This image is taken from the article “Chrominance Sub sampling in
Digital Images” by Douglas A. Kerr

<o:p />You can select different chroma sampling and image views from
corresponding combo boxes in the GUI as shown below

Depending upon the chroma sampling the reconstructed image may
have some small errors like figure below figure[it uses chroma sampling 4:1: 0 ], we can apply some filtering methods to enhance the image.

Using the code

The RGB to YUV conversion takes place in the RGBtoYUV class. The methods available in
the
RGBtoYUV class are given below.

May I ask about executable (windows x86) binary that can output a jpg in yv12 or yuv colorspace.

I mean converter type of application not just number calculating.

I search around google for 30 minutes and find out nothing. Basically I've import a JPG logo to AviDemux but it required JPG format with YV12 or YUV colorspace. And in homepage they recommended XnView, my PC already have got one version of XnView but doesn't seem to convert well. End-up the same warning that not support colorspace.

Can anyone give me suggestion? I know it's community of elite coder and developer, not end-user but I don't see anywhere else to ask... thanks.

Hey, I found there are some pixels which looks quit blue(obviously not like orginal pixel) in mode 4:2:2, seems get wrong result for some pixels.Yes, I debug and found that some pixel get less than 0 and some get large than 255, if I clamp pixel value to 0 and 255, I get the right result. Seems dconversionmatrix is not the right one?