1. ホーム
  2. c++

[解決済み】カメラから取得した1チャンネルの画像をwinAppiウィンドウに出力することはできますか?

2022-02-08 06:57:45

質問

サードパーティのSDKを使用してカメラから取得した画像へのポインタを持っています。画像は1バンド(モノラル8)です。私はそれをビットマップとしてwinAppiウィンドウに出力したいです。私はどうしたらいいでしょうか?

        HBITMAP hBitmap = NULL;
        BITMAPINFOHEADER bmih;
        bmih.biSize = sizeof(BITMAPINFOHEADER);
        bmih.biWidth = 1280;
        bmih.biHeight = 960;
        bmih.biPlanes = 1;
        bmih.biBitCount = 8;
        bmih.biCompression = BI_RGB;
        bmih.biSizeImage = 0;
        bmih.biXPelsPerMeter = 0;
        bmih.biYPelsPerMeter = 0;
        bmih.biClrUsed = 0;
        bmih.biClrImportant = 0;

        BITMAPINFO dbmi;
        ZeroMemory(&dbmi, sizeof(dbmi));
        dbmi.bmiHeader = bmih;
        dbmi.bmiColors->rgbBlue = 0;
        dbmi.bmiColors->rgbGreen = 0;
        dbmi.bmiColors->rgbRed = 0;
        dbmi.bmiColors->rgbReserved = 0;

        void* bits = &aquiredImageCPU.m_sMemory.ptr()[0];

    hBitmap = CreateDIBitmap(dc, &bmih, CBM_INIT, bits, &dbmi, DIB_RGB_COLORS);


    src = CreateCompatibleDC(dc);
            SelectObject(src, hBitmap);
             BitBlt(dc, 10,10,512, 512, src, 0,   0,   SRCCOPY); 

画像を行列として出力し、私のライブラリ(matlabs imsaveに似たimsaveを使用するライブラリ)を使ってプリビジョンすると、画像は問題ない(グレースケール画像)ことがわかります。しかし、それをwinAppiウィンドウに出力すると、RGBに変換されてしまいます。私は、それが関係していると思います。

          HDC dc = GetDC(hwnd);
          src = CreateCompatibleDC(dc);  

何かご提案があればお願いします。 ありがとうございます。

同じようなケースで私が行ったのは、8ビットのチャンクの後に、8ビットごとに2回コピーすることです。それは動作しますが、それは高価であり、私は本当のタイルのアプリケーションを持っている必要があります。

        auto outputImageHight = 1280;
        auto outputImageWidth = 960;
        unsigned char *myArray = new unsigned char[3 * outputImageHight * outputImageWidth];

        for (int i = 0; i < outputImageHight; i++)
        for (int j = 0; j < outputImageWidth; j++)
        {
        unsigned char ucTmp = (unsigned char)(image(i, j));

        myArray[3 * (i + outputImageHight * j) + 0] = ucTmp;
        myArray[3 * (i + outputImageHight * j) + 1] = ucTmp;
        myArray[3 * (i + outputImageHight * j) + 2] = ucTmp;
        }

解決方法は?

8ビットビットマップには、カラーテーブルが必要です。 グレースケールにしたいので、256段階のグレーになるようにカラーテーブルを設定しなければなりません。 最初の一色を黒に設定したのは正しいが、残りの一色を設定していない。

BITMAPINFOは実は可変長の構造体なんです。 bmiColorsフィールドは、カラーテーブルの最初の色のプレースホルダーに過ぎません。 カラーテーブル全体のために余分なスペースを割り当て、それを埋める必要があります。

std::size_t size = sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD);
std::vector<char> buffer(size);
BITMAPINFO *dbmi = reinterpret_cast<BITMAPINFO *>(buffer.data());
ZeroMemory(dbmi, size); // probably unnecessary
dbmi->bmiHeader = bmih;
for (int i = 0; i < 256; ++i) {
  dbmi->bmiColors[i].rgbBlue = i;
  dbmi->bmiColors[i].rgbGreen = i;
  dbmi->bmiColors[i].rgbRed = i;
  dbmi->bmiColors[i].rgbReserved = 0;
}