Page 1 of 1

RGB565 to 16-bit grayscale problem

Posted: Wed May 10, 2017 1:30 pm
by Pethead
I am trying to do some image processing on STM32F4 and I'm having some problems with the RGB565 to grayscale conversion..

When I run the following code I get the regular image as can be seen in the attached picture and all the colors are as they should.

Code: Select all

uint16_t rgb565Img[19200];
uint16_t outImage[19200];

void rgb565ToGray(void)
{
   uint16_t i;
   uint8_t r, g, b;
   uint16_t rgb565;

    for(i = 0; i < 19200; i++)
    {
       rgb565 = rgb565Img[i];

       r = (rgb565 >> 11) & 0x1F;
       g = (rgb565 >> 5) & 0x3F;
   b = (rgb565 << 0) & 0x1F;

   outImage[i] = r << 11 | g << 5 | b;   // Regular image
    }
}


However, when I change the last line to outImage[i] = 0x00 << 11 | 0x00 << 5 | 0x3f; it generates green, but it should be blue

when I change it to outImage[i] = 0x1F << 11 | 0x00 << 5 | 0x00; it is blue when it should be red

when I change it to outImage[i] = 0x00 << 11 | 0x3E << 5 | 0x00; it is red when it should in fact be green?

So from that I guess the output format from my original image is BRG556? Since it also produces yellow when I put 0x07FF; which is full red and green and blue when I put 0xF800. So if that is true then the output format must be BRG556??

Then I change it to the following and all the colors are distorted as can be seen in the picture...:

Code: Select all

uint16_t rgb565Img[19200];
uint16_t outImage[19200];

static void rgb565ToGray(void)
{
   uint16_t i;
   uint8_t r, g, b;
   uint16_t rgb565;
   uint8_t gray;

    for(i = 0; i < 19200; i++)
    {
       rgb565 = rgb565Img[i];

       b = (rgb565 >> 11) & 0x1F;
       r = (rgb565 >> 6) & 0x1F;
   g = (rgb565 << 0) & 0x3F;
   
   outImage[i] = b << 11 | r << 5 | g;
    }
}


Any ideas of what I might be doing wrong? I am super confused right now, first I thought it might have something to do with big/little endian but taht doesn't make sense either?

If I to the grayscale conversion on my desktop after I've sent the data over a socket application on the desktop side I can do the grayscale conversion just fine

Code: Select all

               
   quint16 rgb565 = ((quint8)mData.at(pos + 0) << 8) | (quint8)mData.at(pos + 1);
   quint8 r = (rgb565 >> 8) & 0xF8;
   quint8 g = (rgb565 >> 3) & 0xFC;
   quint8 b = (rgb565 << 3) & 0xF8;
   
   quint16 gray = (0.2126 * r) + 0.7152 * g + (0.0722 * b);
        QColor pixel(gray,gray,gray);
        img.setPixel(mWidth - i - 1, j, pixel.rgb());