OpenCV 2.4:在MFC中显示cv :: Mat [英] OpenCV 2.4 : Displaying a cv::Mat in MFC

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

问题描述

我正在将现有的代码库从IplImage *更新到较新的cv :: Mat.我想知道如何将我的cv :: Mat对象显示给MFC.我们正在使用的当前解决方案基于旧的CvvImage类:

I am updating an existing code base from IplImage* to the newer cv::Mat. I was wondering how to display my cv::Mat object to MFC. The current solution we are using is based on the old CvvImage class:

void DrawPicToHDC(IplImage *img, UINT ID, bool bOnPaint)
{
    CDC *pDC = GetDlgItem(ID)->GetDC();
    HDC hDC= pDC->GetSafeHdc();
    CRect rect;
    GetDlgItem(ID)->GetClientRect(&rect);
    CvvImage cimg;
    cimg.CopyOf( img );
    cimg.DrawToHDC( hDC, &rect );
    ReleaseDC( pDC );
}

我遇到了这个线程,但不幸的是,提供的答案不能满足我的需求,因为答案仍然需要您在显示之前将Mat转换为IplImage *.

I came across this thread but unfortunately the answer provided doesn't meet my needs because the answers still require you to convert the Mat to an IplImage* before displaying.

有什么方法可以仅使用cv :: Mat吗?非常感谢您的帮助.

Is there any way to do this using cv::Mat only? Any help is much appreciated.

更新: 在Kornel的答案的帮助下,我将上述功能调整为使用cv :: Mat.我现在不需要包含CvvImage类:

UPDATE: I adapted the above function to using cv::Mat with the help from Kornel's answer. I now do not need to include the CvvImage class:

void DrawPicToHDC(cv::Mat cvImg, UINT ID, bool bOnPaint)
{
    // Get the HDC handle information from the ID passed
    CDC *pDC = GetDlgItem(ID)->GetDC();
    HDC hDCDst = pDC->GetSafeHdc();
    CRect rect;
    GetDlgItem(ID)->GetClientRect(&rect);
    cv::Size winSize(rect.right, rect.bottom);

    // Resize the source to the size of the destination image if necessary
    cv::Mat cvImgTmp(winSize, CV_8UC3);
    if (cvImg.size() != winSize)
    {
        cv::resize(cvImg, cvImgTmp, winSize);
    }
    else
    {
        cvImgTmp = cvImg;
    }

    // Rotate the image
    cv::flip(cvImgTmp,cvImgTmp,0);

    // Initialize the BITMAPINFO structure
    BITMAPINFO bitInfo;
    bitInfo.bmiHeader.biBitCount = 24;
    bitInfo.bmiHeader.biWidth = winSize.width;
    bitInfo.bmiHeader.biHeight = winSize.height;
    bitInfo.bmiHeader.biPlanes = 1;
    bitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bitInfo.bmiHeader.biCompression = BI_RGB;
    bitInfo.bmiHeader.biClrImportant = 0;
    bitInfo.bmiHeader.biClrUsed = 0;
    bitInfo.bmiHeader.biSizeImage = 0;
    bitInfo.bmiHeader.biXPelsPerMeter = 0;
    bitInfo.bmiHeader.biYPelsPerMeter = 0;

    // Add header and OPENCV image's data to the HDC
    StretchDIBits(hDCDst, 0, 0,
        winSize.width, winSize.height, 0, 0,
        winSize.width, winSize.height,
        cvImgTmp.data, &bitInfo, DIB_RGB_COLORS, SRCCOPY);

    ReleaseDC( pDC );
}

推荐答案

假设我们有一个OpenCV映像cv::Mat cvImg,应将其转换为CImage* mfcImg.
当然,MFC图像应显示在MFC窗口中,即在CStatic winImg

Suppose we have an OpenCV image cv::Mat cvImg which one should be converted to CImage* mfcImg.
Of course the MFC image should be displayed on an MFC window i.e. in CStatic winImg

因此,应执行以下转换以便在MFC窗口中显示OpenCV图像:

So the following transformations should be performed in order to display an OpenCV image in an MFC window:

cv::Mat -> CImage -> CStatic

定义MFC窗口大小:

RECT r;
winImg.GetClientRect(&r);
cv::Size winSize(r.right, r.bottom);

cvImg的大小并不总是与MFC窗口的大小相同.

The size of cvImg is not always the same as an MFC window’s:

cv::Mat cvImgTmp(winSize, CV_8UC3);
if (cvImg.size() != winSize)
{
    cv::resize(cvImg, cvImgTmp, winSize);
}
else 
{
    cvImgTmp = cvImg.clone();
}

旋转图像:

cv::flip(cvImgTmp, cvImgTmp, 0);

创建MFC图像:

if (mfcImg)
{
    mfcImg->ReleaseDC();
    delete mfcImg; mfcImg = nullptr;
}

mfcImg = new CImage();
mfcImg->Create(winSize.width, winSize.height, 24);

对于mfcImg,您需要一个标题.使用BITMAPINFO结构创建它

For mfcImg you need a header. Create it by using BITMAPINFO structure

BITMAPINFO bitInfo;
bitInfo.bmiHeader.biBitCount = 24;
bitInfo.bmiHeader.biWidth = winSize.width;
bitInfo.bmiHeader.biHeight = winSize.height;
bitInfo.bmiHeader.biPlanes = 1;
bitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitInfo.bmiHeader.biCompression = BI_RGB;
bitInfo.bmiHeader.biClrImportant = 0;
bitInfo.bmiHeader.biClrUsed = 0;
bitInfo.bmiHeader.biSizeImage = 0;
bitInfo.bmiHeader.biXPelsPerMeter = 0;
bitInfo.bmiHeader.biYPelsPerMeter = 0;

将标头和OpenCV图片的数据添加到mfcImg

Add header and OpenCV image’s data to mfcImg

StretchDIBits(mfcImg->GetDC(), 0, 0,
    winSize.width, winSize.height, 0, 0,
    winSize.width, winSize.height,
    cvImgTmp.data, &bitInfo, DIB_RGB_COLORS, SRCCOPY
);

在MFC窗口中显示mfcImg

mfcImg->BitBlt(::GetDC(winImg.m_hWnd), 0, 0);

发布mfcImg(如果您不使用它的话):

Release mfcImg, if you will not use it:

if (mfcImg)
{
    mfcImg->ReleaseDC();
    delete mfcImg; mfcImg = nullptr;
}

这篇关于OpenCV 2.4:在MFC中显示cv :: Mat的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆