如何在MFC窗口中输出cv :: Mat

时间:2018-11-15 15:37:18

标签: c++ opencv mfc

我有2个程序,MFC程序和OpenCV。我应该如何统一程序? 如何在MFC窗口中输出cv :: Mat?我应该使用哪种MFC小部件?我应该如何将cv :: Mat转换为MFC小部件?

MFC程序:

#include <afxwin.h> 

        class CMyMainWnd : public CFrameWnd
        {
        public:
            CMyMainWnd() { Create(NULL, L"My title"); }
        };

        class CMyApp : public CWinApp
        {
        public:
            CMyApp() {};
            virtual BOOL InitInstance() {
                m_pMainWnd = new CMyMainWnd();
                m_pMainWnd->ShowWindow(SW_SHOW);
                return TRUE;
            }
        };

        CMyApp theApp;

OpenCV程序:

#include "opencv2/opencv.hpp"
#include <iostream>

using namespace std;
using namespace cv;

int main() {

    VideoCapture cap(0);

    while (1) {

        Mat frame;
        cap >> frame;

        if (frame.empty())
            break;

        imshow("Frame", frame);

        char c = (char)waitKey(25);
        if (c == 27)
            break;
    }

    cap.release();

    destroyAllWindows();

    return 0;
}

1 个答案:

答案 0 :(得分:1)

您的main示例的不同之处在于它不直接创建任何窗口。它使opencv创建窗口。

要复制该示例,只需将opencv循环移至CWinApp::InitInstance,而无需创建单独的MFC窗口。

要将opencv与MFC结合在一起,请使用opencv抓取视频帧,然后在MFC窗口上绘制该帧。

CWinApp::OnIdle可用于连续更新窗口。 opencv的frame包含位图位,可以使用HDC或类似功能将这些位直接复制到MFC窗口的SetDIBitsToDevice

class CMyMainWnd : public CFrameWnd
{
    cv::VideoCapture video;
public:
    CMyMainWnd()
    {
        video.open(0);
    }

    void CMyMainWnd::OnPaint()
    {
        CPaintDC dc(this);

        cv::Mat mat;
        video >> mat;
        if(mat.empty())
            return;

        BITMAPINFOHEADER bi = { sizeof(bi) };
        bi.biWidth = mat.cols;
        bi.biHeight = -mat.rows;
        bi.biBitCount = (WORD)(mat.channels() * 8);
        bi.biPlanes = 1;

        SetDIBitsToDevice(dc, 0, 0, mat.cols, mat.rows, 0, 0, 0, mat.rows,
            mat.data, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
    }

    DECLARE_MESSAGE_MAP()
};

BEGIN_MESSAGE_MAP(CMyMainWnd, CWnd)
    ON_WM_PAINT()
END_MESSAGE_MAP()

class CMyApp : public CWinApp
{
public:
    virtual BOOL InitInstance()
    {
        CWinApp::InitInstance();
        CMyMainWnd *wnd = new CMyMainWnd();
        m_pMainWnd = wnd;
        wnd->Create(NULL, L"My title");
        wnd->ShowWindow(SW_SHOW);
        return TRUE;
    }

    BOOL OnIdle(LONG lCount)
    {
        CWinApp::OnIdle(lCount);
        m_pMainWnd->Invalidate(FALSE);
        return TRUE;
    }
};

CMyApp theApp;