C++ C++;:灰度位图标题和实时绘制+;opencv图像处理

C++ C++;:灰度位图标题和实时绘制+;opencv图像处理,c++,opencv,image-processing,bitmap,visual-studio-2017,C++,Opencv,Image Processing,Bitmap,Visual Studio 2017,我试图显示来自单色照相机(Adimec N5A/CXP,带有GenIcam标准)的实时图像 从供应商的一个例子(但在RGB 24中),我或多或少能够显示图像,但颜色渲染非常奇怪(颜色和阴影而不是灰度)。我想我在位图头声明中做错了什么: bitmapInfo = (LPBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)); bitmapInfo->bmiHeader.biSize = sizeof(BITM

我试图显示来自单色照相机(Adimec N5A/CXP,带有GenIcam标准)的实时图像

从供应商的一个例子(但在RGB 24中),我或多或少能够显示图像,但颜色渲染非常奇怪(颜色和阴影而不是灰度)。我想我在位图头声明中做错了什么:

    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;
    }
    */
我不知道用什么代替DIB_RGB_颜色作为最后一个参数。我只找到了这个参数的另一个值,即DIB_PAL_COLORS。我想应该有灰度的选项

这是我计划的第一步。。。如果您对如何将图像指针推入opencv容器有任何建议,我也非常乐意:-)


非常感谢

看来你们很接近了。显示灰度图像的方法是使用调色板。这只是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;
}
分配结构。我把它放在堆栈上使用,所以我不需要担心清理

BITMAPINFO* bmi(static_cast<BITMAPINFO*>(alloca(bmi_size)));
注意:由于我们有一个完整的256项调色板,
biClrUsed
可以设置为0。发件人:

如果此值为零,位图将使用与
bibibitcount
成员的值相对应的最大颜色数

接下来,设置调色板(基本上就是注释掉的代码部分)


我使用调色板显示灰度图像(生成起来非常简单)。在我即将出发时,快速粘贴我的代码:--数据指针是原始
cv::Mat
payload。我回来后会写一个答案。(那里可能有一些WTL位,但这与WinAPI非常接近)Hi Dan,我能请你提供更多帮助吗?如何使用cv::Mat从内存缓冲区加载图像?我想我应该使用cv::imdecode,但我不能。我想缓冲区类型有问题。”Mat srcImg=imdecode(imagePointer,0);'内存缓冲区中有什么?原始图像数据(如上所述)?或者它是PNG、JPEG等格式的编码图像数据?如果它已经是原始图像数据,则使用(请注意,它不会复制数据,您负责确保指针在
Mat
包装有效期内保持有效)
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;
}
int32_t const bmi_size(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256);
BITMAPINFO* bmi(static_cast<BITMAPINFO*>(alloca(bmi_size)));
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;
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;
    }
}
HBITMAP bitmap = ::CreateDIBitmap(dc
    , &bmi->bmiHeader
    , CBM_INIT
    , data // Pointer to raw pixel data
    , bmi
    , DIB_RGB_COLORS);