VS2010+Opencv+MFC读取图像和视频显示在Picture控件

时间:2021-10-01 03:47:20

VS2010+Opencv+MFC读取图像和视频显示在Picture控件,供大家参考,具体内容如下

1.新建MFC对话框应用程序。

其余选项默认,单击完成,创建出对话框应用程序。删掉原来自带的一些控件,添加picture控件和两个按钮。

VS2010+Opencv+MFC读取图像和视频显示在Picture控件

VS2010+Opencv+MFC读取图像和视频显示在Picture控件

2.由于以后的代码会用到CvvImage类,而opencv2.3以后就去掉了对它的支持,这里先介绍添加CvvImage支持的方法,直接能用的可以略过这一步。

如下图添加相应的文件:

VS2010+Opencv+MFC读取图像和视频显示在Picture控件

这里附上两个文件的源码方便使用。

  1. #pragma once
  2.  
  3. #ifndef CVVIMAGE_CLASS_DEF
  4. #define CVVIMAGE_CLASS_DEF
  5. #include "opencv.hpp"
  6.  
  7. class CvvImage
  8.  
  9. {
  10.  
  11. public:
  12.  
  13. CvvImage();
  14.  
  15. virtual ~CvvImage();
  16.  
  17. virtual bool Create( int width, int height, int bits_per_pixel, int image_origin = 0 );
  18. virtual bool Load( const char* filename, int desired_color = 1 );
  19. virtual bool LoadRect( const char* filename,
  20. int desired_color, CvRect r );
  21.  
  22. #if defined WIN32 || defined _WIN32
  23. virtual bool LoadRect( const char* filename,
  24. int desired_color, RECT r )
  25.  
  26. {
  27.  
  28. return LoadRect( filename, desired_color,
  29. cvRect( r.left, r.top, r.right - r.left, r.bottom - r.top ));
  30.  
  31. }
  32.  
  33. #endif
  34.  
  35. virtual bool Save( const char* filename );
  36. virtual void CopyOf( CvvImage& image, int desired_color = -1 );
  37. virtual void CopyOf( IplImage* img, int desired_color = -1 );
  38. IplImage* GetImage() { return m_img; };
  39.  
  40. virtual void Destroy(void);
  41.  
  42. int Width() { return !m_img ? 0 : !m_img->roi ? m_img->width : m_img->roi->width; };
  43. int Height() { return !m_img ? 0 : !m_img->roi ? m_img->height : m_img->roi->height;};
  44. int Bpp() { return m_img ? (m_img->depth & 255)*m_img->nChannels : 0; };
  45.  
  46. virtual void Fill( int color );
  47. virtual void Show( const char* window );
  48.  
  49. #if defined WIN32 || defined _WIN32
  50.  
  51. virtual void Show( HDC dc, int x, int y, int width, int height,
  52. int from_x = 0, int from_y = 0 );
  53.  
  54. virtual void DrawToHDC( HDC hDCDst, RECT* pDstRect );
  55. #endif
  56. protected:
  57. IplImage* m_img;
  58.  
  59. };
  60.  
  61. typedef CvvImage CImage;
  62.  
  63. #endif
  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.  
  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.  
  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. }

在需要引用该类的地方添加如下引用:

VS2010+Opencv+MFC读取图像和视频显示在Picture控件

3.在Picture控件中显示图片

VS2010+Opencv+MFC读取图像和视频显示在Picture控件

如图所示修改控件ID,并删除按钮已存在的响应代码。双击显示图片添加以下代码:

  1. void CopencvtestDlg::OnBnClickedCancel()
  2. {
  3. // TODO: 在此添加控件通知处理程序代码
  4. CDC *pDC = GetDlgItem(IDC_STATIC)->GetDC();//根据ID获得窗口指针再获取与该窗口关联的上下文指针
  5. HDC hdc= pDC->GetSafeHdc(); // 获取设备上下文句柄
  6. CRect rect;
  7. // 矩形类
  8. GetDlgItem(IDC_STATIC)->GetClientRect(&rect); //获取box1客户区
  9. CvvImage cimg;
  10. IplImage *src; // 定义IplImage指针变量src
  11. src = cvLoadImage("D:\\me.bmp",-1); // 将src指向当前工程文件目录下的图像me.bmp
  12. cimg.CopyOf(src,src->nChannels);
  13.  
  14. cimg.DrawToHDC(hdc,&rect);
  15. //输出图像
  16. ReleaseDC( pDC );
  17. cimg.Destroy();
  18. //销毁
  19. }

4.播放视频

双击播放视频按钮,添加如下代码:

  1. void CopencvtestDlg::OnBnClickedOk()
  2. {
  3. // TODO: 在此添加控件通知处理程序代码
  4. //IplImage *src; // 定义IplImage指针变量src
  5. // src = cvLoadImage("D:\\me.bmp",-1); // 将src指向当前工程文件目录下的图像me.bmp
  6. // cvNamedWindow("me",0);//定义一个窗口名为lena的显示窗口
  7. // cvShowImage("me",src);//在lena窗口中,显示src指针所指向的图像
  8. // cvWaitKey(0);//无限等待,即图像总显示
  9. // cvDestroyWindow("me");//销毁窗口lena
  10. // cvReleaseImage(&src);//释放IplImage指针src
  11.  
  12. CDC *pDC = GetDlgItem(IDC_STATIC)->GetDC();//根据ID获得窗口指针再获取与该窗口关联的上下文指针
  13. HDC hdc= pDC->GetSafeHdc(); // 获取设备上下文句柄
  14. CRect rect;
  15. // 矩形类
  16. GetDlgItem(IDC_STATIC)->GetClientRect(&rect); //获取box1客户区
  17.  
  18. CvCapture *capture = cvCreateFileCapture ("D:\\tree.avi"); //读取视频
  19. if(capture==NULL) {
  20. printf("NO capture"); //读取不成功,则标识
  21. //return 1;
  22. };
  23. double fps=cvGetCaptureProperty(capture, CV_CAP_PROP_FPS ); //读取视频的帧率
  24. int vfps = 1000 / fps; //计算每帧播放的时间
  25. printf("%5.1f\t%5d\n",fps,vfps);
  26. double frames=cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_COUNT);//读取视频中有多少帧
  27. printf("frames is %f\n",frames);
  28. //cvNamedWindow("example",CV_WINDOW_AUTOSIZE); //定义窗口
  29. IplImage *frame;
  30.  
  31. CvvImage cimg;
  32.  
  33. while(1){
  34. frame = cvQueryFrame( capture ); //抓取帧
  35. cimg.CopyOf(frame,frame->nChannels);
  36. cimg.DrawToHDC(hdc,&rect);
  37. float ratio = cvGetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO); //读取该帧在视频中的相对位置
  38. printf("%f\n",ratio);
  39. if(!frame)break;
  40. //cvShowImage("IDC_STATIC",frame); //显示
  41.  
  42. char c = cvWaitKey(vfps);
  43. if(c == 27 )break;
  44. }
  45. ReleaseDC( pDC );
  46. cvReleaseCapture(&capture);
  47. cvDestroyWindow("example");
  48. }

最终效果:

VS2010+Opencv+MFC读取图像和视频显示在Picture控件

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/g120406191/article/details/20835225