MFC+Opencv显示图像的几种方法

早上小师妹遇到mfc显示opencv图像的问题,过来请教我,趁机总结下以前用过的几种方法好了。


(1)使用opencv的CvvImage类

该方法比较简单,但是opencv2.x以上版本已经不支持CvvImage类,不过可以在网上下载该类的头文件和源文件,添加到工程里就可以使用了。

void CXXXDlg::DrawIplImage2MFC(IplImage* img, unsigned int id)
{
	CDC* pDC = GetDlgItem(id)->GetDC();  
	HDC hDC = pDC->GetSafeHdc();  	
	CvvImage cimg;  
	cimg.CopyOf( img );  
	CRect rect;  
	GetDlgItem(id)->GetClientRect(&rect);  	
	cimg.DrawToHDC(hDC, &rect);  
	ReleaseDC( pDC );  
}

函数参数中id是控件ID,比如IDC_STATIC(下同)。


(2)使用MFC的绘图函数
该方法利用MFC的绘图函数,将opencv图像数据先copy到缓冲去然后在控件上显示出来。

void CXXXDlg::DrawIplImage2MFC(IplImage* img, unsigned int id)
{
	BYTE *g_pBits;
	 HDC g_hMemDC;
	 HBITMAP g_hBmp, g_hOldBmp;
	 CDC *pDC;
	 CStatic *pic;
	 int width, height;
	 CRect rect;
	 pDC = GetDlgItem(id)->GetDC();
	 pic = (CStatic*)GetDlgItem(id);
	 pic->GetClientRect(&rect);
	 width = rect.Width();
	 height = rect.Height();
	 g_hMemDC =::CreateCompatibleDC(pDC->m_hDC);
	 BYTE bmibuf[sizeof(BITMAPINFO)+256 * sizeof(RGBQUAD)];
	 memset(bmibuf, 0, sizeof(bmibuf));
	 BITMAPINFO *pbmi = (BITMAPINFO*)bmibuf;
	 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	 pbmi->bmiHeader.biWidth = img->width;
	 pbmi->bmiHeader.biHeight = img->height;
	 pbmi->bmiHeader.biPlanes = 1;
	 pbmi->bmiHeader.biBitCount = 24;
	 pbmi->bmiHeader.biCompression= BI_RGB;
	 g_hBmp =::CreateDIBSection(g_hMemDC, pbmi, DIB_RGB_COLORS, (void**)&g_pBits, 0, 0);
	 g_hOldBmp = (HBITMAP)::SelectObject(g_hMemDC, g_hBmp);
	 BitBlt(g_hMemDC, 0, 0, width, height, pDC->m_hDC, 0, 0, SRCCOPY);
	 int l_width = WIDTHBYTES(img->width* pbmi->bmiHeader.biBitCount);
	 for (int row = 0; row < img->height;row++)  
	 memcpy(&g_pBits[row*l_width],&img->imageData[ (img->height - row - 1)*l_width], l_width);
	 TransparentBlt(pDC->m_hDC, 0, 0, width, height, g_hMemDC, 0, 0, img->width, img->height, RGB(0, 0, 0));
	 SelectObject(g_hMemDC, g_hOldBmp);
	 DeleteDC(g_hMemDC);
	 DeleteObject(pic);
	 DeleteObject(g_hBmp);
	 DeleteObject(g_hOldBmp);
}


(3)链接opencv窗口和MFC控件

该方法是将opencv的显示窗口与MFC的控件链接起来,效果是opencv的窗口恰好覆盖在控件上。

//pic是opencv窗口的标志符,name是窗口名字,ID同上,是MFC控件ID
bool CXXXDlg::attachWindow(string &pic,const char* name,int ID)
{
	pic=string(name);
	cv::namedWindow(pic, 1);
	HWND hWnd = (HWND) cvGetWindowHandle(name);
	HWND hParent = ::GetParent(hWnd);
	::SetParent(hWnd, GetDlgItem(ID)->m_hWnd);
	::ShowWindow(hParent, SW_HIDE);
	return true;
}
bool CXXXDlg::showImage(string pic,int id,cv::Mat mat)
{
	CRect rect;
	GetDlgItem(id)->GetClientRect(&rect);	
	cv::resize(mat,mat,cv::Size(rect.Width(),rect.Height()),CV_INTER_CUBIC);	
	imshow(pic,mat);
	return true;
}
</pre><pre>
使用方法是先链接opencv窗口的标识符和控件ID

string pic;
attachWindow(pic,"win",IDC_PIC);
然后在需要显示图像的地方调用showImage

Mat mat=imread("1.jpg");
showImage(pic,IDC_PIC,mat);	


  • 4
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值