Y’CbCr (“YUV”) conversion – part 2

Now the fun part : the implementation using Processing.js

We will load the original picture as in the previous example:

img = loadImage(“Yosemite.jpg”);

Then we will go through all the pixels by 2 loops:

for (int y = 0; y < img.height; y++) { //we loop through every line
for (int x = 0; x < img.width; x++) { //we loop through every column

We then compute the 1D coordinate of the current pixel. Images are 2D arrays, but are stored and managed as 1D arrays in Processing. Computing this location once will allow to save time, and have cleaner code.

int loc = y*img.width + x; //computing 1D location of current pixel.

Then for every pixel we compute Y’, Cb and Cr values, using the formulas from the previous post.

// Compute Y’CbCr – output range [0-255] if input range is [0-255]
// Y’ = 0.299 R’ + 0.587 G’ + 0.114 B’
// Cb = – 0.1687 R’ – 0.3313 G’ + 0.5 B’ + 127.5
// Cr = 0.5 R’ – 0.4187 G’ – 0.0813 B’ + 127.5

float r = red(img.pixels[loc]);
float g = green(img.pixels[loc]);
float b = blue(img.pixels[loc]);

Y[loc] = round(0.299 * r + 0.587 * g + 0.114 * b);
Cb[loc] = round(-0.1687 * r – 0.3313 * g + 0.5 * b + 127.5);
Cr[loc] = round(0.5 * r – 0.4187 * g – 0.0813 * b + 127.5);

After that we have 3 int arrays, for Y’, Cb and Cr channels. Here we could add later some image processing tricks.

For now, we will just display the 3 channels as “RGB” pictures. For the Y’ channel, we will consider a greyscale picture, so with R=G=B=Y’.

Cb channel will be displayed a blue, and Cr as red. This is just to create a representation of these channels. In later posts we will work on re-creating the RGB from a processed Y’CbCr.

Finally, all the pictures are displayed : original and Y’CbCr channels representations.

You can check the result here. As always, there is a link to the full source code.

Feel free to comment, correct, or share ! Thanks ! 🙂

Tags: , ,