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

来源:互联网 发布:成都餐饮网络建设电话 编辑:程序博客网 时间:2024/05/29 04:55

原文地址:http://blog.csdn.net/u012250337/article/details/51601905

(1)使用opencv的CvvImage类

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

[cpp] view plain copy
  1. void CXXXDlg::DrawIplImage2MFC(IplImage* img, unsigned int id)  
  2. {  
  3.     CDC* pDC = GetDlgItem(id)->GetDC();    
  4.     HDC hDC = pDC->GetSafeHdc();       
  5.     CvvImage cimg;    
  6.     cimg.CopyOf( img );    
  7.     CRect rect;    
  8.     GetDlgItem(id)->GetClientRect(&rect);      
  9.     cimg.DrawToHDC(hDC, &rect);    
  10.     ReleaseDC( pDC );    
  11. }  

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


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

[cpp] view plain copy
  1. void CXXXDlg::DrawIplImage2MFC(IplImage* img, unsigned int id)  
  2. {  
  3.     BYTE *g_pBits;  
  4.      HDC g_hMemDC;  
  5.      HBITMAP g_hBmp, g_hOldBmp;  
  6.      CDC *pDC;  
  7.      CStatic *pic;  
  8.      int width, height;  
  9.      CRect rect;  
  10.      pDC = GetDlgItem(id)->GetDC();  
  11.      pic = (CStatic*)GetDlgItem(id);  
  12.      pic->GetClientRect(&rect);  
  13.      width = rect.Width();  
  14.      height = rect.Height();  
  15.      g_hMemDC =::CreateCompatibleDC(pDC->m_hDC);  
  16.      BYTE bmibuf[sizeof(BITMAPINFO)+256 * sizeof(RGBQUAD)];  
  17.      memset(bmibuf, 0, sizeof(bmibuf));  
  18.      BITMAPINFO *pbmi = (BITMAPINFO*)bmibuf;  
  19.      pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);  
  20.      pbmi->bmiHeader.biWidth = img->width;  
  21.      pbmi->bmiHeader.biHeight = img->height;  
  22.      pbmi->bmiHeader.biPlanes = 1;  
  23.      pbmi->bmiHeader.biBitCount = 24;  
  24.      pbmi->bmiHeader.biCompression= BI_RGB;  
  25.      g_hBmp =::CreateDIBSection(g_hMemDC, pbmi, DIB_RGB_COLORS, (void**)&g_pBits, 0, 0);  
  26.      g_hOldBmp = (HBITMAP)::SelectObject(g_hMemDC, g_hBmp);  
  27.      BitBlt(g_hMemDC, 0, 0, width, height, pDC->m_hDC, 0, 0, SRCCOPY);  
  28.      int l_width = WIDTHBYTES(img->width* pbmi->bmiHeader.biBitCount);  
  29.      for (int row = 0; row < img->height;row++)    
  30.      memcpy(&g_pBits[row*l_width],&img->imageData[ (img->height - row - 1)*l_width], l_width);  
  31.      TransparentBlt(pDC->m_hDC, 0, 0, width, height, g_hMemDC, 0, 0, img->width, img->height, RGB(0, 0, 0));  
  32.      SelectObject(g_hMemDC, g_hOldBmp);  
  33.      DeleteDC(g_hMemDC);  
  34.      DeleteObject(pic);  
  35.      DeleteObject(g_hBmp);  
  36.      DeleteObject(g_hOldBmp);  
  37. }  


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

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

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

[cpp] view plain copy
  1. string pic;  
  2. attachWindow(pic,"win",IDC_PIC);  
然后在需要显示图像的地方调用showImage

[cpp] view plain copy
  1. Mat mat=imread("1.jpg");  
  2. showImage(pic,IDC_PIC,mat);   
原创粉丝点击