MFC的View區顯示OpenCV的Mat數據結構圖像,24位彩色或者8位灰度圖像


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM