• vc++ MFC opencv 显示摄像头图像的2种方法


    1.通过 vvimage 类显示到MFC控件中

    参考

    opencv -- cvvimage 的使用 opencv2.1后版本

    Cvvimage.h 文件

     1 #pragma once
     2 #ifndef CVVIMAGE_CLASS_DEF
     3 #define CVVIMAGE_CLASS_DEF
     4 #include "opencv.hpp"
     5 #include <windows.h>
     6 /* CvvImage class definition */
     7 class  CvvImage
     8 {
     9 public:
    10    CvvImage();
    11    virtual ~CvvImage();
    12    /* Create image (BGR or grayscale) */
    13    virtual bool  Create( int width, int height, int bits_per_pixel, int image_origin = 0 );
    14    /* Load image from specified file */
    15    virtual bool  Load( const char* filename, int desired_color = 1 );
    16    /* Load rectangle from the file */
    17    virtual bool  LoadRect( const char* filename,
    18       int desired_color, CvRect r );
    19 #if defined WIN32 || defined _WIN32
    20    virtual bool  LoadRect( const char* filename,
    21       int desired_color, RECT r )
    22    {
    23       return LoadRect( filename, desired_color,
    24          cvRect( r.left, r.top, r.right - r.left, r.bottom - r.top ));
    25    }
    26 #endif
    27    /* Save entire image to specified file. */
    28    virtual bool  Save( const char* filename );
    29    /* Get copy of input image ROI */
    30    virtual void  CopyOf( CvvImage& image, int desired_color = -1 );
    31    virtual void  CopyOf( IplImage* img, int desired_color = -1 );
    32    IplImage* GetImage() { return m_img; };
    33    virtual void  Destroy(void);
    34    /* width and height of ROI */
    35    int Width() { return !m_img ? 0 : !m_img->roi ? m_img->width : m_img->roi->width; };
    36    int Height() { return !m_img ? 0 : !m_img->roi ? m_img->height : m_img->roi->height;};
    37    int Bpp() { return m_img ? (m_img->depth & 255)*m_img->nChannels : 0; };
    38    virtual void  Fill( int color );
    39    /* draw to highgui window */
    40    virtual void  Show( const char* window );
    41  
    42 #if defined WIN32 || defined _WIN32
    43    /* draw part of image to the specified DC */
    44    virtual void  Show( HDC dc, int x, int y, int width, int height,
    45       int from_x = 0, int from_y = 0 );
    46    /* draw the current image ROI to the specified rectangle of the destination DC */
    47    virtual void  DrawToHDC( HDC hDCDst, RECT* pDstRect );
    48 #endif
    49 protected:
    50    IplImage*  m_img;
    51 };
    52 typedef CvvImage CImage;
    53 #endif
    View Code

    Cvvimage.cpp文件

      1 #include "StdAfx.h"
      2 #include "CvvImage.h"
      3 //
      4 // Construction/Destruction
      5 //
      6 CV_INLINE RECT NormalizeRect( RECT r );
      7 CV_INLINE RECT NormalizeRect( RECT r )
      8 {
      9    int t;
     10    if( r.left > r.right )
     11    {
     12       t = r.left;
     13       r.left = r.right;
     14       r.right = t;
     15    }
     16    if( r.top > r.bottom )
     17    {
     18       t = r.top;
     19       r.top = r.bottom;
     20       r.bottom = t;
     21    }
     22  
     23    return r;
     24 }
     25 CV_INLINE CvRect RectToCvRect( RECT sr );
     26 CV_INLINE CvRect RectToCvRect( RECT sr )
     27 {
     28    sr = NormalizeRect( sr );
     29    return cvRect( sr.left, sr.top, sr.right - sr.left, sr.bottom - sr.top );
     30 }
     31 CV_INLINE RECT CvRectToRect( CvRect sr );
     32 CV_INLINE RECT CvRectToRect( CvRect sr )
     33 {
     34    RECT dr;
     35    dr.left = sr.x;
     36    dr.top = sr.y;
     37    dr.right = sr.x + sr.width;
     38    dr.bottom = sr.y + sr.height;
     39  
     40    return dr;
     41 }
     42 CV_INLINE IplROI RectToROI( RECT r );
     43 CV_INLINE IplROI RectToROI( RECT r )
     44 {
     45    IplROI roi;
     46    r = NormalizeRect( r );
     47    roi.xOffset = r.left;
     48    roi.yOffset = r.top;
     49    roi.width = r.right - r.left;
     50    roi.height = r.bottom - r.top;
     51    roi.coi = 0;
     52  
     53    return roi;
     54 }
     55 void  FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp, int origin )
     56 {
     57    assert( bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32));
     58  
     59    BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
     60  
     61    memset( bmih, 0, sizeof(*bmih));
     62    bmih->biSize = sizeof(BITMAPINFOHEADER);
     63    bmih->biWidth = width;
     64    bmih->biHeight = origin ? abs(height) : -abs(height);
     65    bmih->biPlanes = 1;
     66    bmih->biBitCount = (unsigned short)bpp;
     67    bmih->biCompression = BI_RGB;
     68    if( bpp == 8 )
     69    {
     70       RGBQUAD* palette = bmi->bmiColors;
     71       int i;
     72       for( i = 0; i < 256; i++ )
     73       {
     74          palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
     75          palette[i].rgbReserved = 0;
     76       }
     77    }
     78 }
     79 CvvImage::CvvImage()
     80 {
     81    m_img = 0;
     82 }
     83 void CvvImage::Destroy()
     84 {
     85    cvReleaseImage( &m_img );
     86 }
     87 CvvImage::~CvvImage()
     88 {
     89    Destroy();
     90 }
     91 bool  CvvImage::Create( int w, int h, int bpp, int origin )
     92 {
     93    const unsigned max_img_size = 10000;
     94  
     95    if( (bpp != 8 && bpp != 24 && bpp != 32) ||
     96       (unsigned)w >=  max_img_size || (unsigned)h >= max_img_size ||
     97       (origin != IPL_ORIGIN_TL && origin != IPL_ORIGIN_BL))
     98    {
     99       assert(0); // most probably, it is a programming error
    100       return false;
    101    }
    102    if( !m_img || Bpp() != bpp || m_img->width != w || m_img->height != h )
    103    {
    104       if( m_img && m_img->nSize == sizeof(IplImage))
    105          Destroy();
    106       /* prepare IPL header */
    107       m_img = cvCreateImage( cvSize( w, h ), IPL_DEPTH_8U, bpp/8 );
    108    }
    109    if( m_img )
    110       m_img->origin = origin == 0 ? IPL_ORIGIN_TL : IPL_ORIGIN_BL;
    111    return m_img != 0;
    112 }
    113 void  CvvImage::CopyOf( CvvImage& image, int desired_color )
    114 {
    115    IplImage* img = image.GetImage();
    116    if( img )
    117    {
    118       CopyOf( img, desired_color );
    119    }
    120 }
    121 #define HG_IS_IMAGE(img)                                                  
    122    ((img) != 0 && ((const IplImage*)(img))->nSize == sizeof(IplImage) && 
    123    ((IplImage*)img)->imageData != 0)
    124 void  CvvImage::CopyOf( IplImage* img, int desired_color )
    125 {
    126    if( HG_IS_IMAGE(img) )
    127    {
    128       int color = desired_color;
    129       CvSize size = cvGetSize( img ); 
    130       if( color < 0 )
    131          color = img->nChannels > 1;
    132       if( Create( size.width, size.height,
    133          (!color ? 1 : img->nChannels > 1 ? img->nChannels : 3)*8,
    134          img->origin ))
    135       {
    136          cvConvertImage( img, m_img, 0 );
    137       }
    138    }
    139 }
    140 bool  CvvImage::Load( const char* filename, int desired_color )
    141 {
    142    IplImage* img = cvLoadImage( filename, desired_color );
    143    if( !img )
    144       return false;
    145  
    146    CopyOf( img, desired_color );
    147    cvReleaseImage( &img );
    148  
    149    return true;
    150 }
    151 bool  CvvImage::LoadRect( const char* filename,
    152                    int desired_color, CvRect r )
    153 {
    154    if( r.width < 0 || r.height < 0 ) return false;
    155  
    156    IplImage* img = cvLoadImage( filename, desired_color );
    157    if( !img )
    158       return false;
    159    if( r.width == 0 || r.height == 0 )
    160    {
    161       r.width = img->width;
    162       r.height = img->height;
    163       r.x = r.y = 0;
    164    }
    165    if( r.x > img->width || r.y > img->height ||
    166       r.x + r.width < 0 || r.y + r.height < 0 )
    167    {
    168       cvReleaseImage( &img );
    169       return false;
    170    }
    171    /* truncate r to source image */
    172    if( r.x < 0 )
    173    {
    174       r.width += r.x;
    175       r.x = 0;
    176    }
    177    if( r.y < 0 )
    178    {
    179       r.height += r.y;
    180       r.y = 0;
    181    }
    182    if( r.x + r.width > img->width )
    183       r.width = img->width - r.x;
    184  
    185    if( r.y + r.height > img->height )
    186       r.height = img->height - r.y;
    187    cvSetImageROI( img, r );
    188    CopyOf( img, desired_color );
    189    cvReleaseImage( &img );
    190    return true;
    191 }
    192 bool  CvvImage::Save( const char* filename )
    193 {
    194    if( !m_img )
    195       return false;
    196    cvSaveImage( filename, m_img );
    197    return true;
    198 }
    199 void  CvvImage::Show( const char* window )
    200 {
    201    if( m_img )
    202       cvShowImage( window, m_img );
    203 }
    204 void  CvvImage::Show( HDC dc, int x, int y, int w, int h, int from_x, int from_y )
    205 {
    206    if( m_img && m_img->depth == IPL_DEPTH_8U )
    207    {
    208       uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
    209       BITMAPINFO* bmi = (BITMAPINFO*)buffer;
    210       int bmp_w = m_img->width, bmp_h = m_img->height;
    211       FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(), m_img->origin );
    212       from_x = MIN( MAX( from_x, 0 ), bmp_w - 1 );
    213       from_y = MIN( MAX( from_y, 0 ), bmp_h - 1 );
    214       int sw = MAX( MIN( bmp_w - from_x, w ), 0 );
    215       int sh = MAX( MIN( bmp_h - from_y, h ), 0 );
    216       SetDIBitsToDevice(
    217          dc, x, y, sw, sh, from_x, from_y, from_y, sh,
    218          m_img->imageData + from_y*m_img->widthStep,
    219          bmi, DIB_RGB_COLORS );
    220    }
    221 }
    222 void  CvvImage::DrawToHDC( HDC hDCDst, RECT* pDstRect ) 
    223 {
    224    if( pDstRect && m_img && m_img->depth == IPL_DEPTH_8U && m_img->imageData )
    225    {
    226       uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
    227       BITMAPINFO* bmi = (BITMAPINFO*)buffer;
    228       int bmp_w = m_img->width, bmp_h = m_img->height;
    229       CvRect roi = cvGetImageROI( m_img );
    230       CvRect dst = RectToCvRect( *pDstRect );
    231       if( roi.width == dst.width && roi.height == dst.height )
    232       {
    233          Show( hDCDst, dst.x, dst.y, dst.width, dst.height, roi.x, roi.y );
    234          return;
    235       }
    236       if( roi.width > dst.width )
    237       {
    238          SetStretchBltMode(
    239             hDCDst,           // handle to device context
    240             HALFTONE );
    241       }
    242       else
    243       {
    244          SetStretchBltMode(
    245             hDCDst,           // handle to device context
    246             COLORONCOLOR );
    247       }
    248       FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(), m_img->origin );
    249       ::StretchDIBits(
    250          hDCDst,
    251          dst.x, dst.y, dst.width, dst.height,
    252          roi.x, roi.y, roi.width, roi.height,
    253          m_img->imageData, bmi, DIB_RGB_COLORS, SRCCOPY );
    254    }
    255 }
    256 void  CvvImage::Fill( int color )
    257 {
    258    cvSet( m_img, cvScalar(color&255,(color>>8)&255,(color>>16)&255,(color>>24)&255) );
    259 }
    View Code

    调用方法是直接把这2个文件加入到工程

     1 CvvImage m_CvvImage;
     2 CDC *pDC;//关闭时释放
     3 CRect CameraPicRect;
     4 HDC hDC;
     5 CvCapture* Capture;
     6 IplImage* frame;
     7 
     8 Capture = cvCreateCameraCapture(0);//要使用的摄像头索引
     9 if (Capture == 0)
    10 {
    11     MessageBox(_T("无法连接摄像头!!!"));
    12     return;
    13 }
    14 pDC = GetDlgItem(IDC_PIC_STATIC)->GetDC();//获取显示控件的句柄
    15 GetDlgItem(IDC_PIC_STATIC)->GetClientRect(&CameraPicRect);//得到控件尺寸
    16 hDC = pDC->GetSafeHdc();//获取显示控件的句柄
    17 
    18 frame = cvQueryFrame(Capture); //从摄像头或者文件中抓取并返回一帧
    19 m_CvvImage.CopyOf(frame, 1); //复制该帧图像
    20 m_CvvImage.DrawToHDC(hDC, &CameraPicRect); //显示到设备的矩形框内
    21 
    22 //保存图像文件
    23 IplImage* TakePictureFrame;
    24 TakePictureFrame = frame;
    25 char ImagePathName[256] = "123.jpg";
    26 IplImage *m_snap = cvCreateImage(cvGetSize(TakePictureFrame), TakePictureFrame->depth, TakePictureFrame->nChannels);
    27 cvCopy(TakePictureFrame, m_snap, NULL);
    28 cvSaveImage(ImagePathName, m_snap); //把图像写入指定文件夹的文件中去
    29 cvReleaseImage(&m_snap);

    2.新版本的opencv Cvvimage 类没有,改成了Mat

    把 imshow 显示 Mat 的对话框窗口添加到MFC

    参考

    MFC显示Mat图片

     1 cv::Mat frame;
     2 cv::Mat showFrame;
     3 
     4 cv::namedWindow("view", cv::WINDOW_AUTOSIZE);
     5 HWND hWnd = (HWND)cvGetWindowHandle("view");
     6 HWND hParent = ::GetParent(hWnd);
     7 ::SetParent(hWnd, GetDlgItem(IDC_STA_TakePhoto)->m_hWnd);
     8 ::ShowWindow(hParent, SW_HIDE);
     9 CRect picRect;
    10 GetDlgItem(IDC_STA_TakePhoto)->GetClientRect(picRect);
    11 cv::VideoCapture capture(0);
    12 if (!capture.isOpened())
    13 {
    14     MessageBox(_T("打开摄像头失败"));
    15 }
    16 capture >> frame;
    17 resize(frame, showFrame, cv::Size(picRect.Width(), picRect.Height()));
    18 imshow("view", showFrame);
    19 cv::waitKey(30);//没有这个显示不了
    20 
    21 //保存图片
    22 strPathName = strPath + strName;//这里用完整路径
    23 char chPathName[MAX_PATH];
    24 WideCharToMultiByte(CP_ACP, 0, LPCTSTR(strPathName), -1, chPathName, MAX_PATH, NULL, NULL);
    25 BOOL ret;
    26 ret = imwrite(chPathName, frame);
    27 if (!ret)
    28 {
    29     MessageBox(_T("照片保存失败"));
    30 }
  • 相关阅读:
    《Google 软件测试之道》摘录
    UIRecorder环境搭建及录制实现
    网易《人性的哲学与科学》笔记
    网易《公正:该如何做是好?》笔记(不定时更新)
    自助饮料机实现
    网易《社会心理学》笔记(不定时更新)
    uiautomator +python 安卓UI自动化尝试
    doc
    doc
    doc
  • 原文地址:https://www.cnblogs.com/ckrgd/p/14122012.html
Copyright © 2020-2023  润新知