OpenCV 2.4 : Displaying a cv::Mat in MFC(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 窗口大小:
Define MFC window size:
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 映像:
Create an MFC image:
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;
将header和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
Display mfcImg
in MFC window
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:OpenCV 2.4:在 MFC 中显示 cv::Mat
基础教程推荐
- Windows Media Foundation 录制音频 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01