要点:
1). OpenCV采用C++接口中的Mat图像数据结构,可以是24位的CV_8UC3类型(RGB彩色图像),或者8位的CV_8UC!类型(灰度图像)。
2). 将Mat的数据在MFC的View区显示,关键是为Mat设计DIB类型的MBP信息头,也就是结构体BITMAPINFO(详见MSDN)。
3). 将Mat图像数据交给MFC之前需要调cv::filp()函数将数据垂直翻转一下,具体原因可以参考BMP文件的存储结构。
该方法可以将OpenCV处理过的数据方便的在MFC的View区显示。
下面贴出一段演示代码,主要实现简单的读取任何类型的图像,然后在单文档的MFC程序View区显示。
代码如下所示:
//将XXX替换为工程的名称
1)首先位Doc类添加成员变量:
public: BITMAPINFOm_bmi; Matm_img; Mat m_drawImg;
2)并打开菜单添加消息ID_FILE_OPEN,消息处理函数为:
void CXXXDoc::OnFileOpen()//XXX表示工程名称 { // TODO: Add your command handler code here LPCTSTRlpszFilter="Image Files(*.jpg)|*.jpg|ImageFiles(*.bmp)|*.bmp|任何文件|*.*||"; CFileDialogfdlg(TRUE,lpszFilter,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,lpszFilter,NULL); CStringfilename; if(fdlg.DoModal()==IDOK) { filename=fdlg.GetPathName(); strings(filename.GetBuffer()); filename.ReleaseBuffer(); m_img=imread(s,1); flip(m_img,m_drawImg,0); m_bmi=CreateBitmapInfo(m_img); } }
3)其中,CreateBitmapInfo函数为:
BITMAPINFO CreateBitmapInfo(Mat workImg) // 建立位图信息 { BITMAPINFOHEADER BIH={40,1,1,1,8,0,0,0,0,0,0}; BITMAPINFO bmi; intbits, colors; RGBQUAD ColorTab[256]; if(CV_8UC3==workImg.type()) { bits=24; } if(CV_8UC1==workImg.type()) { bits=8; } if(bits>8) colors=0; else colors=1<<bits; BIH.biWidth =workImg.cols; BIH.biHeight =workImg.rows; BIH.biBitCount=(BYTE) bits; bmi.bmiHeader=BIH; if(bits==8) { // 256 色位图 for(inti=0;i<256;i++) { // 设置灰阶调色板 ColorTab[i].rgbRed=ColorTab[i].rgbGreen=ColorTab[i].rgbBlue=(BYTE)i; } memcpy(bmi.bmiColors,ColorTab, 1024); } return(bmi); }
4)在View类中添加WM_PAINT消息,响应函数如下:
void CXXXView::OnPaint()//XXX为工程名称 { CPaintDCdc(this); // devicecontext for painting // TODO: Add your message handler code here // Do not call CView::OnPaint() for painting messages CopenCVMFCDoc*pDoc = GetDocument(); ASSERT_VALID(pDoc); if(!pDoc) return; // TODO: 在此处为本机数据添加绘制代码 /* SetDIBitsToDevice(dc.m_hDC, 0, 0, pDoc->m_bmi.bmiHeader.biWidth, pDoc->m_bmi.bmiHeader.biHeight, 0, 0, 0, pDoc->m_bmi.bmiHeader.biHeight, pDoc->m_drawImg.data, (LPBITMAPINFO)&(pDoc->m_bmi), DIB_RGB_COLORS); */ //也可使用上面注释起来的SetDIBitsToDevice函数(不能实现拉伸) StretchDIBits(dc.m_hDC, 0, 0, pDoc->m_bmi.bmiHeader.biWidth, pDoc->m_bmi.bmiHeader.biHeight, 0, 0, pDoc->m_bmi.bmiHeader.biWidth, pDoc->m_bmi.bmiHeader.biHeight, pDoc->m_drawImg.data, (LPBITMAPINFO)&(pDoc->m_bmi), DIB_RGB_COLORS, SRCCOPY); Invalidate(FALSE); }