如何在 MFC 视图上显示 OpenCV Mat

How to display OpenCV Mat on MFC View(如何在 MFC 视图上显示 OpenCV Mat)

本文介绍了如何在 MFC 视图上显示 OpenCV Mat的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为在 MFC 视图上显示 OpenCV2 Mat 很简单,但事实并非如此.这只是我在 google 上找到的相关资料.请原谅我的无知,但我找不到任何其他材料来展示如何将 SetDIBitsToDevice 与一维数组数据"成员返回一起使用.更具体地说,我需要知道如何为函数指定 BITMAPINFO.我要回到旧的 C 风格 OpenCV 来使用 MFC 吗?

I thought displaying OpenCV2 Mat on MFC View is simple but is not. This is only relevant material I found on google. Excuse me for my ignorance but I can't find any other materials showing how to use SetDIBitsToDevice with one dimensional array "data" member returns. More specifically, I need to know how to specify BITMAPINFO for the function. Do I go back to Old C-style OpenCV to work with MFC?

更新:

我发现 SetDIBitsToDevice 的一个例子 这实际上是用于旧的 C 风格的 OpenCV.但是将其转换为 OpenCV2 很简单.我需要提到一些事情才能让它发挥作用:

I found an example of SetDIBitsToDevice which is actually for old C-style OpenCV. But it was straightforward to convert it for OpenCV2. There are things I need to mention to make it work:

  1. Bpp 方法效果不佳,因为 Mat 的深度返回 0.我只是这样更改:

  1. Bpp method does not work well as Mat's depth returns 0. I just changed like this:

static int Bpp(cv::Mat img) { return 8 * img.channels(); } 

  • Mat 没有原始成员.但是对于 FillBitmapInfo 方法的 origin 参数,简单地放置 0 就可以了.

  • Mat does not have origin member. But simply putting 0 is fine for origin argument of FillBitmapInfo method.

    除此之外,以下代码效果很好.希望这对其他开发者也有帮助.

    Other than that, following code works great. Hope this helps other devs too.

    void COpenCVTestView::OnDraw(CDC* pDC)
    {
    COpenCVTestDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;
    if(pDoc->m_cvImage.empty()) return;
    // TODO: add draw code for native data here
    int height=pDoc->m_cvImage.rows;
    int width=pDoc->m_cvImage.cols;
    uchar buffer[sizeof( BITMAPINFOHEADER ) + 1024]; 
    BITMAPINFO* bmi = (BITMAPINFO* )buffer; 
    FillBitmapInfo(bmi,width,height,Bpp(pDoc->m_cvImage),0);
    SetDIBitsToDevice(pDC->GetSafeHdc(), 0, 0, width,
        height, 0, 0, 0, height, pDoc->m_cvImage.data, bmi,
        DIB_RGB_COLORS);
    }
    void COpenCVTestView::FillBitmapInfo(BITMAPINFO* bmi, int width, int height, int bpp, int origin) 
    { 
    assert(bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32)); 
    
    BITMAPINFOHEADER* bmih = &(bmi->bmiHeader); 
    
    memset(bmih, 0, sizeof(*bmih)); 
    bmih->biSize = sizeof(BITMAPINFOHEADER); 
    bmih->biWidth = width; 
    bmih->biHeight = origin ? abs(height) : -abs(height); 
    bmih->biPlanes = 1; 
    bmih->biBitCount = (unsigned short)bpp; 
    bmih->biCompression = BI_RGB; 
    
    if (bpp == 8) 
    { 
        RGBQUAD* palette = bmi->bmiColors; 
    
                for (int i = 0; i < 256; i++) 
        { 
            palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i; 
            palette[i].rgbReserved = 0; 
        } 
    } 
    }
    

    推荐答案

    来自 MSDN:

    lpvBits [in]指向存储为字节数组的颜色数据的指针.有关详细信息,请参阅以下备注部分.

    lpvBits [in] A pointer to the color data stored as an array of bytes. For more information, see the following Remarks section.

    这是您必须使用从 Mat::data 返回的数据初始化的指针.

    This is the pointer you must init with the data returned from Mat::data.

    这篇关于如何在 MFC 视图上显示 OpenCV Mat的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

  • 本文标题为:如何在 MFC 视图上显示 OpenCV Mat

    基础教程推荐