要點:
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); }