zoukankan      html  css  js  c++  java
  • 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);
    }
  • 相关阅读:
    Asp.net实现URL重写
    IHttpModule不起作用的两个原因
    从客户端中检测到有潜在危险的 request.form值[解决方法]
    PHP $_SERVER详解
    string.Format 格式化日期格式
    图解正向代理、反向代理、透明代理
    Javacard 解释器怎样在API类库中找到源文件调用的类、方法或者静态域?
    API
    指令集
    机器码与字节码
  • 原文地址:https://www.cnblogs.com/ledao/p/2942233.html
Copyright © 2011-2022 走看看