C ++: grayscale bitmap title and live painting + opencv image processing

I am trying to display live images coming from a monochrome camera (Adimec N5A / CXP, with GenIcam standard).

From an example coming from a vendor (but in RGB 24), I am more or less able to display an image, but the color rendering is very strange (colors and shadows instead of shades of gray). I think I did something wrong in the bitmap title declaration:

    bitmapInfo = (LPBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD));
    bitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bitmapInfo->bmiHeader.biPlanes = 1;
    bitmapInfo->bmiHeader.biBitCount = 8; // 24
    bitmapInfo->bmiHeader.biCompression = BI_RGB;
    bitmapInfo->bmiHeader.biSizeImage = 0;
    bitmapInfo->bmiHeader.biXPelsPerMeter = 0;
    bitmapInfo->bmiHeader.biYPelsPerMeter = 0;
    bitmapInfo->bmiHeader.biClrUsed = 256;
    bitmapInfo->bmiHeader.biClrImportant = 0;
    bitmapInfo->bmiHeader.biWidth = (LONG)width;
    bitmapInfo->bmiHeader.biHeight = -(LONG)height;
    /*
    RGBQUAD* bmiColors = (RGBQUAD*)(bitmapInfo->bmiColors);
    for (size_t index = 0; index < 256; ++index)
    {
        bmiColors[index].rgbBlue = (BYTE)index;
        bmiColors[index].rgbGreen = (BYTE)index;
        bmiColors[index].rgbRed = (BYTE)index;
        bmiColors[index].rgbReserved = 0;
    }
    */

I found in the bmiColors field of the BITMAPINFO structure that the biClrUsed parameter should be set to 256. Then I do not know if I need to write a block to describe 'bmiColors. I would like to use only one byte per pixel instead of the r, g and b components.

( "OnPaint" ) "SetDIBitsToDevice" . :

unsigned char *imagePtr = liveState.currentBuffer->getInfo<unsigned char *>(liveState.grabber, gc::BUFFER_INFO_BASE);

:

::SetDIBitsToDevice(dc, 0, 0, (DWORD)liveState.width, (DWORD)liveState.height, 0, 0, 0, (UINT)liveState.height, imagePtr, liveState.bitmapInfo, DIB_RGB_COLORS);

, DIB_RGB_COLORS . , DIB_PAL_COLORS. , ?

... , opencv, :-).

!

+4
1

, . - . 256 RGB, :

std::vector<RGBQUAD> pal(256);
for (int32_t i(0); i < 256; ++i) {
    pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = i;
    pal[i].rgbReserved = 0;
}

BITMAPINFOHEADER, 256 RGBQUAD , .

int32_t const bmi_size(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256);

. , _alloca, .

BITMAPINFO* bmi(static_cast<BITMAPINFO*>(alloca(bmi_size)));

BITMAPINFOHEADER, .

bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi->bmiHeader.biWidth = static_cast<LONG>(width);
bmi->bmiHeader.biHeight = static_cast<LONG>(-height);
bmi->bmiHeader.biPlanes = 1;
bmi->bmiHeader.biBitCount = 8;
bmi->bmiHeader.biCompression = BI_RGB;

. 256 , biClrUsed 0. docs:

, , biBitCount...

( , ).

for (uint32_t i(0); i < 256; ++i) {
    if (pal.size() > i) {
        bmi->bmiColors[i] = pal[i];
    } else {
        bmi->bmiColors[i].rgbRed
            = bmi->bmiColors[i].rgbGreen
            = bmi->bmiColors[i].rgbBlue
            = bmi->bmiColors[i].rgbReserved = 0;
    }
}

. . . , biClrUsed, .

. SetDIBitsToDevice - DIB_RGB_COLORS, " RGB".

CreateDIBitmap DDB, BitBlt.

HBITMAP bitmap = ::CreateDIBitmap(dc
    , &bmi->bmiHeader
    , CBM_INIT
    , data // Pointer to raw pixel data
    , bmi
    , DIB_RGB_COLORS);
+1

Source: https://habr.com/ru/post/1696112/


All Articles