OpenCV 2.4:在MFC中显示cv::Mat
OpenCV 2.4 : Displaying a cv::Mat in MFC
我正在将现有的代码库从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 );
}
我遇到了这个线程,但不幸的是提供的答案不能满足我的需求,因为答案仍然要求您在显示之前将垫子转换为 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
,您需要一个标头。使用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;
将标题和 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;
}
相关文章:
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 字符串-C++后显示的随机字符
- 继承期间显示未知行为的子类
- 仅使用绝对值对数组进行排序,并在C++中显示实际值
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 程序崩溃并显示"std::out_of_range"错误
- 在 QML VideoOutput 中将 cv::mat 显示为 QVideoFrame
- C++/openCV - 为什么显示图像会产生 Linux 分割错误?(打开CV错误?
- 在qpixMap中显示一个CV :: MAT(键入CV_32F)
- 在图片框中显示cv::Mat格式的网络摄像头提要
- 如何显示窗口大小不同的输出图像?通过使用 cv::Mat
- OpenCV 2.4:在MFC中显示cv::Mat
- 将我的阵列移动到 Mat 并使用打开的 CV 显示图像
- 使用直接显示控制相机,并使用打开的CV捕获图像
- 为什么我无法在 Open CV 中正确显示矩形?
- cv::imshow 在不同的线程上不显示 cv::mat 颜色
- 如何在Windows窗体应用程序中显示cv::Mat
- 显示带有cv::viz模块的WCloud
- 调试断言失败!在人脸识别打开Cv的检测和显示功能中