MFCのView領域にはOpenCVのMatデータ構造画像、24ビットカラーまたは8ビット階調画像が表示される

6147 ワード

要点:1).OpenCVはC++インタフェースのMat画像データ構造を採用し、24ビットのCV_8 UC 3タイプ(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);
}