First, the basic

For color turn grayscale, there is a well-known psychological formula:

Gray = r*0.299 + g*0.587 + b*0.114

Second, integer algorithm

In practical applications, it is desirable to avoid low-speed floating-point operations, so integer arithmetic is required.

Note that the coefficients are all 3-bit accurate, and we can scale them up to 1000 times times to implement an integer arithmetic:

Gray = (r*299 + g*587 + b*114 + 500)/1000

RGB is generally 8-bit precision, now scaling 1000 times times, so the above operation is a 32-bit integer operation. Note that the next Division is integer division, so it needs to be rounded with the 500来 implementation.

Because the algorithm requires 32-bit arithmetic, another variant of the formula is popular:

Gray = (r*30 + g*59 + b*11 + 50)/100

However, although the previous formula is a 32-bit integer operation, it is possible to use a 16-bit integer multiplication instruction according to the characteristics of the integer multiplication directive of the 80x86 system. And now 32 people have been popularized (AMD64 all come out), so we recommend using the previous formula.

Three, Integer shift algorithm

The integer algorithm above is fast, but one thing still restricts speed, which is the last division. The shift is much faster than division, so you can scale the coefficients to an integer power of 2.

Accustomed to using 16-bit precision, 2 of the 16 power is 65536, so this calculation factor:

0.299 * 65536 = 19595.264≈19595

0.587 * 65536 + (0.264) = 38469.632 + 0.264 = 38469.896≈38469

0.114 * 65536 + (0.896) = 7471.104 + 0.896 = 7472

Many people may have seen it, and the rounding method I'm using is not rounded. Rounding will have a greater error, the previous calculation should be calculated in conjunction with the error, rounding is the method of the tail:

The written expression is:

Gray = (r*19595 + g*38469 + b*7472) >> 16

Coefficients of 2 to 20-bit accuracy:

Gray = (r*1 + g*2 + b*1) >> 2

Gray = (r*2 + g*5 + b*1) >> 3

Gray = (r*4 + g*10 + b*2) >> 4

Gray = (r*9 + g*19 + b*4) >> 5

Gray = (r*19 + g*37 + b*8) >> 6

Gray = (r*38 + g*75 + b*15) >> 7

Gray = (r*76 + g*150 + b*30) >> 8

Gray = (r*153 + g*300 + b*59) >> 9

Gray = (r*306 + g*601 + b*117) >> 10

Gray = (r*612 + g*1202 + b*234) >> 11

Gray = (r*1224 + g*2405 + b*467) >> 12

Gray = (r*2449 + g*4809 + b*934) >> 13

Gray = (r*4898 + g*9618 + b*1868) >> 14

Gray = (r*9797 + g*19235 + b*3736) >> 15

Gray = (r*19595 + g*38469 + b*7472) >> 16

Gray = (r*39190 + g*76939 + b*14943) >> 17

Gray = (r*78381 + g*153878 + b*29885) >> 18

Gray = (r*156762 + g*307757 + b*59769) >> 19

Gray = (r*313524 + g*615514 + b*119538) >> 20

Look closely at the table above, the accuracy is actually the same: 3 and 4, 7 and 8, 10 and 11, 13 and 14, 19 and 20

So the best formula for a 16-bit operation is to use 7-bit precision, which is 100 times times more accurate than the previous one, and is fast:

Gray = (r*38 + g*75 + b*15) >> 7

In fact, the most interesting thing is that the 2-bit precision, completely can be shifted optimization:

Gray = (R + (WORD) g<<1 + B) >> 2

========================

Use the most RGB color space in the computer, respectively, corresponding to red, green, blue three colors, by leveling the proportions of three components to form a variety of colors. You can generally use 1, 2, 4, 8, 16, 24, 32 bits to store the three colors, but now a component is the largest of 8 bits to represent, the maximum is 255, for 32-bit color, high 8 is used to express the degree of clarity. Color graphs generally refer to more than 16 figures. One of the special shades of grayscale is that the three components that make up the color are equal, while the general grayscale is less than 8 bits.

In color TV system, a color space called YUV is usually used, where Y is the luminance signal, and the YUV space solves the compatibility problem of color TV and monochrome TV.

For the human eye, the luminance signal is the most sensitive, if the color image to convert to grayscale image, only need to convert to save brightness signal can be.

The Y conversion formula from RGB to YUV space is:

Y = 0.299r+0.587g+0.114b

In WINDOWS, a figure that represents more than 16 figures is a bit different from the following diagram; The 16-bit graph uses a color palette to represent the selection of a specific color, each cell of the palette is 4 bytes, one of which is transparency, and the specific pixel value stores the index, which is 1, 2, 4, 8 bits, respectively. More than 16 figures directly use pixels to represent colors.

=================================================

So how do you convert a color map to a grayscale image?

There is a color palette in the grayscale chart, first you need to determine the color of the palette to take the value. As we mentioned earlier, the three components of a grayscale graph are equal.

When converting to 8-bit, there are 256 colors in the palette, each from 0 to 255 and three components equal.

When converting to 4-bit, the palette has 16 colors, evenly spaced 255 color values, and three components are equal.

When converting to 2-bit, the palette is divided into 4 colors, equal intervals of 255 colors, and three components equally.

When converting to 1-bit, two colors in the palette are 0 and 255, which represent black and white.

When the color is converted to grayscale, the corresponding value is calculated according to the formula, which is actually the level of brightness, brightness from 0 to 255, because different bits have different luminance levels, so the specific value of Y is as follows:

Y = y/(1<< (8-number of bits converted));

The last point to note is that the Y value is stored differently, and the corresponding Y value is saved with the corresponding number of digits.

//----------------------------------------------------------

RGB565 Turn 8-bit grayscale

//----------------------------------------------------------

TUint8 Gm_red,gm_green,gm_blue;

TInt16 *des_ptr;

TInt16 *pt;

PT = (TInt16 *) P8; RGB565 Flow

for (TInt j=0;j{

for (TInt i = w;i>0;i--)

{

gm_red = ((* (* (TINT16 *) PT) & 0xf800) >> 8;

Gm_green = ((* (* (TINT16 *) PT) & 0X07E0) >> 3;

Gm_blue = ((* (* (TINT16 *) PT) & 0x001f) << 3;

P[0] = (TUint8) ((gm_red*77+gm_green*150+gm_blue*29+128)/256);

p++;

pt++;

}

}

p = qt; Grayscale Chart pointer

Converting from RGB to gray-color algorithm