Rodrigo Strauss
Rodrigo Strauss

Reputation: 2065

How to convert yuy2 to a BITMAP in C++

I'm using a security camera DLL to retreive the image from the camera. The DLL call a function of my program passing the image buffer as a parameter, but the image is in yuy2 format. I need to convert this buffer to RGB, but I tried every formula I found on Internet with no success. Every example I tried (including http://msdn.microsoft.com/en-us/library/aa904813(VS.80).aspx#yuvformats_2) gives me wrong colors.

I'm able to convert the buffer to a BW image using only the Y component of the pixel, but I really need the color picture. I debugged (assembly only) the DLL that shows the image in the screen and it uses DirectDraw to do this.

Upvotes: 7

Views: 12327

Answers (4)

Rodrigo Strauss
Rodrigo Strauss

Reputation: 2065

This formula worked:

int C = luma - 16;
int D = cr - 128;
int E = cb - 128;
r = (298*C+409*E+128)/256;
g = (298*C-100*D-208*E+128)/256;
b = (298*C+516*D+128)/256;

I got this from a matlab example.

The gotcha is: in memory, Windows bitmaps aren't RGB, they are BGR. If you are writing to a memory buffer, you need to do something like this:

rgbbuffer[rgbindex] = (char)b;
rgbbuffer[rgbindex + 1] = (char)g;
rgbbuffer[rgbindex + 2] = (char)r;

Upvotes: 3

Mark Ransom
Mark Ransom

Reputation: 308462

Using the information from the Microsoft link in the question:

for (int i = 0;  i < width/2;  ++i)
{
    int y0 = ptrIn[0];
    int u0 = ptrIn[1];
    int y1 = ptrIn[2];
    int v0 = ptrIn[3];
    ptrIn += 4;
    int c = y0 - 16;
    int d = u0 - 128;
    int e = v0 - 128;
    ptrOut[0] = clip(( 298 * c + 516 * d + 128) >> 8); // blue
    ptrOut[1] = clip(( 298 * c - 100 * d - 208 * e + 128) >> 8); // green
    ptrOut[2] = clip(( 298 * c + 409 * e + 128) >> 8); // red
    c = y1 - 16;
    ptrOut[3] = clip(( 298 * c + 516 * d + 128) >> 8); // blue
    ptrOut[4] = clip(( 298 * c - 100 * d - 208 * e + 128) >> 8); // green
    ptrOut[5] = clip(( 298 * c + 409 * e + 128) >> 8); // red
    ptrOut += 6;
}

Upvotes: 13

Alan
Alan

Reputation: 4933

If you were already using DirectShow to get video data out of the security camera, then you could simply add the "Color Space Converter Filter" to your DirectShow graph. But if you aren't using DirectShow already (it sounds like you're not) then it will be much, much simpler to just convert the data to RGB yourself using the formulas that Daniel linked to. Adding DirectShow to a project is very complicated.

Upvotes: 1

Daniel Mošmondor
Daniel Mošmondor

Reputation: 19976

You will have to write your own converter. GDI+ doesn't know how to deal with YUY2 bitmaps.

Look here.

Please note that 2 pixels share same color values and have different luminance values.

Here are some formulas to help you write your converter.

Upvotes: 0

Related Questions