Thursday, January 28, 2010

RGB to Grayscale

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 weight of each color component. If we use same weight, for example, (R + G + B) / 3, then pure red, pure green and pure blue result in 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;
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
}

No comments:

Post a Comment