gpt4 book ai didi

c++ - OpenCV 2.4:在 MFC 中显示 cv::Mat

转载 作者:太空宇宙 更新时间:2023-11-03 22:12:53 28 4
gpt4 key购买 nike

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

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 );
}

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

有没有办法只使用 cv::Mat 来做到这一点?非常感谢任何帮助。

更新:在 Kornel 的回答的帮助下,我将上述函数改编为使用 cv::Mat。我现在不需要包含 CvvImage 类:

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

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

cv::Mat -> CImage -> CStatic

定义 MFC 窗口大小:

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

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

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,您需要一个 header 。使用BITMAPINFO结构

创建
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;

将 header 和 OpenCV 图像的数据添加到 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,如果您不使用它:

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

关于c++ - OpenCV 2.4:在 MFC 中显示 cv::Mat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28997560/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com