WICConvertBitmapSource BGR to Gray unexpected pixel format conversion
Asked Answered
E

1

10

I am using WICConvertBitmapSource function to convert pixel format from BGR to Gray and I'm getting unexpected pixel values.

...

pIDecoder->GetFrame( 0, &pIDecoderFrame ); 

pIDecoderFrame->GetPixelFormat( &pixelFormat ); // GUID_WICPixelFormat24bppBGR

IWICBitmapSource * dst;
WICConvertBitmapSource( GUID_WICPixelFormat8bppGray, pIDecoderFrame, &dst );

Example on 4x3 image with following BGR pixel values:

[  0,   0, 255,   0, 255,   0, 255,   0,   0;
   0, 255, 255, 255, 255,   0, 255,   0, 255;
   0,   0,   0, 119, 119, 119, 255, 255, 255;
 233, 178,  73, 233, 178,  73, 233, 178,  73]

Gray pixel values I am getting:

[127, 220,  76;
 247, 230, 145;
   0, 119, 255;
 168, 168, 168]

Gray pixel values I expected to get (ITU-R BT.601 conversion)

[ 76, 149,  29;
 225, 178, 105;
   0, 119, 255;
 152, 152, 152]

What kind of conversion is happening in the background, and is there a way to force conversion to my wanted behaviour?

Also worth mentioning, the conversions are working properly (as expected) for Gray -> BGR and BGRA -> BGR

Enkindle answered 10/3, 2021 at 13:53 Comment(0)
D
2

As for the question "What kind of conversion is happening in the background": it seems like a different conversion algorithm is used. Using the WINE project to calculate the greyscale values, seem to give the same results, so it gives us a pretty good approximation what is happening. The formula used is R * 0.2126 + G * 0.7152 + B * 0.0722.

copypixels_to_8bppGray (source):

float gray = (bgr[2] * 0.2126f + bgr[1] * 0.7152f + bgr[0] * 0.0722f) / 255.0f;

In addition to that, it is corrected for the sRGB color space.

copypixels_to_8bppGray (source):

gray = to_sRGB_component(gray) * 255.0f;

to_sRGB_component (source):

static inline float to_sRGB_component(float f)
{
    if (f <= 0.0031308f) return 12.92f * f;
    return 1.055f * powf(f, 1.0f/2.4f) - 0.055f;
}

Plugging in some values:

    B    G    R    WINE          You're getting
      0    0  255  127.1021805   127
      0  255    0  219.932749    220
    255    0    0   75.96269736   76
    0    255  255  246.7295889   247
    255  255    0  229.4984163   230
    255    0  255  145.3857605   145
      0    0    0   12.92          0

As for the other question, I'm too unfamiliar with the framework to answer that, so I'll leave that open for others to answer.

Dictum answered 10/3, 2021 at 18:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.