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