【问题标题】:How to output cv::Mat in MFC window如何在 MFC 窗口中输出 cv::Mat
【发布时间】:2019-01-01 09:12:45
【问题描述】:

我有 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;
}

【问题讨论】:

  • 请编辑问题以将其限制为具有足够详细信息的特定问题,以确定适当的答案。避免一次问多个不同的问题。请参阅“如何提问”页面以获得澄清此问题的帮助。

标签: c++ opencv mfc


【解决方案1】:

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

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

要将opencv与MFC结合,使用opencv抓取视频帧,并在MFC窗口上绘制帧。

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

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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-23
    • 2019-06-17
    • 1970-01-01
    • 1970-01-01
    • 2014-06-21
    相关资源
    最近更新 更多