# Luminance

### RGB to Grayscale

In order to convert RGB or BGR color image to grayscale image, we are frequently use the following conversion formulae:

Luminace = 0.3086 * Red + 0.6094 * Green + 0.0820 * Blue
Luminace = 0.299 * Red + 0.587 * Green + 0.114 * Blue

Notice that the luminance intensity is a sum of different weights of each color component. If we use same weight, for example, R/3 + G/3 + B/3, then pure red, pure green and pure blue result in the same gray scale level. And the other reason for using different weights is that human eye is more sensitive on green and red components than blue channel.

### Fast Approximation

Implementing the conversion formula is quite simple in C/C++;

``````
// interleaved color, RGBRGB...
for ( i = 0; i < size; i += 3 )
{
// add weighted sum then round
out[i] = (unsigned char)(0.299*in[i] + 0.587*in[i+1] + 0.114*in[i+2] + 0.5);
}

``````

Since multiplication in integer domain is much faster than in float, we rewrite the formula like this for faster computation in integer domain;
Luminance = (2 * Red + 5 * Green + 1 * Blue) / 8

Furthermore, we can optimize the code by substituting the multiplication and division into bit shift operators and addition. I have found this is about 4 times faster than the original float computation.

``````
int tmp;
for ( i = 0; i < size; i += 3 )
{
// faster computation, (2*R + 5*G + B) / 8
tmp = in[i] << 1;                   // 2 * red
tmp += in[i+1] << 2 + in[i+1];      // 5 * green
tmp += in[i+2];                     // 1 * blue
out[i] = (unsigned char)(tmp >> 3); // divide by 8
}

``````

### Example This program reads a color image in BMP format and converts it to the gray scale image. It uses OpenGL and GLUT/FreeGLUT to render the original image and the gray scale image side by side on the screen. It measures the elapsed time to compare the floating computation with the fast estimation.

This program also contains BMP loader and writer codes. Please look at Bmp.h and Bmp.cpp files for more details.