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 }
原文地址:https://www.cnblogs.com/ckrgd/p/14122012.html