MFC对话框和opencv的结合 读入视频

来源:互联网 发布:淘宝店铺库存数量设置 编辑:程序博客网 时间:2024/05/16 04:53

这几天在做一个设计,要用到MFC和opencv的结合,上网查了一下,发现这方面的知识不是很多,连一个简单的视频读入都有点麻烦,经过重重困难,终于做出来,为了给初学者少走弯路,现在给出大概流程和主要代码。

1,打开VC,建立一个工程,基于MFC的对话框。(我命名为Video)

2,设置opencv的lib。

3,找到resource的dialog,设置对话框,添加一个picture按键,一个open按钮,play按钮,exit按钮。open,play,exit的ID分别为IDC_OPEN,IDC_PLAY,IDC_EXIT.然后双击这三个按钮,添加消息处理函数。

4,在class中,右键单击VideoDlg,选中Add Window Message,添加OnTimer函数,并在其中添加如下代码:

 if(IsAviFile)
 {//选择播放视频
  if(framepos>myvideo.m_totalframes)
  {//判断视屏是否已经是最后一帧,即是否播完
   framepos=0;                      //回到第一帧,继续播放
   KillTimer(1);
  }
  else
  {
   myvideo.PlayVideo(framepos);     //播放第framepos帧
   framepos++;                      //下一帧的位置
  }
  
 }

5,在open的消息处理函数中,添加如下代码:

    if(IsPlaying)
 {
  MessageBox("请先停止当前文件的播放","提示",0);
  //GetDlgItem(IDC_STOP)->SetFocus();
  return;
 }
 if(IsAviFile)
 {//关闭先前已经打开了AVI视频文件
  myvideo.CloseFile();
 }
 
 
    //打开视频文件
 CString szFilters="Data Files (*.avi)|*.avi|All Files (*.*)|*.*||";
 
 CFileDialog fileDlg(TRUE,NULL,"*.avi",OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,szFilters,this);
 
 if (fileDlg.DoModal()==IDOK)
 {
  KillTimer(1);

  pwnd=GetDlgItem(IDC_STATIC1);   //获取显示视频图像的控件ID
  pdc =pwnd->GetDC();
     hdc=pdc->GetSafeHdc();          //获取句柄
  GetDlgItem(IDC_STATIC1)->GetClientRect(rect);  //获取控件的RECT
  if(myvideo.OpenVideo(fileDlg.GetPathName(),hdc,rect)) //构造视频播放对象
  {
   IsAviFile=TRUE;                   //当前用户选择了播放AVI视频文件
   framepos=0;                       //第一帧播放
   myvideo.PlayVideo(0);             //预览第一帧图像

   //初始化对话框界面

   GetDlgItem(IDC_PLAY)->EnableWindow(TRUE);

  }
  
 }

6:在PLAY的函数中,添加如下代码:


 IsPlaying=TRUE;

 int speed=myvideo.GetPlaySpeed();      //获取视频本身的播放速度

 SetTimer(1,speed,NULL);                //每隔一段时间读出一帧视频图像
7:在EXIT的函数中,添加如下代码:

int user_choice=MessageBox("您确定要退出吗?","退出",1);
 if(user_choice==IDOK)
 {
  
  CDialog::OnCancel();
 }

9:到了这一步,没有定义上述三个函数所用到的一些变量,因此,要定义,

 

public:
 Video myvideo;         //定义播放视频类对象
 int framepos;          //记录播放视频帧位置
 bool IsPlaying;        //判断是否正在播放
 bool IsPausing;        //判断是否暂停中
 bool IsAviFile;        //判断是否是播放AVI视频文件
 
 CRect rect;             
 CWnd *pwnd;            
 CDC *pdc;
    HDC hdc;

10:还缺一个播放视频的函数功能,用一个类表示,新建一个类。在其头文件添加#include "cv.h"    #include "highgui.h",还要声明,

 

 

CvvImage m_showimage;        //CvvImage对象,用于显示帧到控件
 IplImage *m_pframe;          //获取帧
 CvCapture *m_pcapture;       //捕获
 CString m_filepath;          //文件路径
 CRect m_rect;                //播放区域
    HDC m_hdc;                   //用于显示帧图像的句柄
 bool m_isplay;               //判断是否播放中
 int m_framepos;              //帧位置
 int m_totalframes;           //帧总数
 int m_fps; 
    UINT m_timer;                //定时器
 int m_speed;                 //播放速度

 

 

在cpp文件中,添加如下代码:

 

int Video::OpenVideo(CString FilePath, HDC hdc, CRect rect)
{

 CvCapture *capture;
 capture=cvCaptureFromAVI(FilePath);      //捕获视频
 if(!capture)
 {
  AfxMessageBox("打开文件失败!");
  return 0;
 }
 m_rect=rect;                       //获得picture控件的RECT   
 m_hdc=hdc;                         //获得picture控件的画图句柄
 m_filepath=FilePath;               //获得视频文件路径
 m_pcapture=capture;
 m_totalframes = (int)cvGetCaptureProperty(m_pcapture, CV_CAP_PROP_FRAME_COUNT);  //获取视频帧总数
    if(m_totalframes==0)
 {
  AfxMessageBox("不能打开该格式文件!");
  return 0;
 }
 m_fps=(int)cvGetCaptureProperty(m_pcapture,CV_CAP_PROP_FPS);   //帧率
 return 1;

}

void Video::CloseFile()
{

 if(m_pcapture)
 {
  cvReleaseCapture(&m_pcapture);
 }

}

void Video::PlayVideo(int frame_pos)
{

 if(frame_pos>m_totalframes)
 {
  return;
 }
 m_framepos=frame_pos;                      //播放帧开始位置
 cvSetCaptureProperty(m_pcapture, CV_CAP_PROP_POS_FRAMES, (m_framepos%m_totalframes)); //设置播放帧位置
   
 m_pframe=cvQueryFrame(m_pcapture);         //获取一帧
 if(m_pframe)
 {
  m_showimage.CopyOf(m_pframe,1);    
  m_showimage.DrawToHDC(m_hdc,&m_rect);   //显示到控件

  m_showimage.DrawToHDC(m_hdc,&m_rect);   //显示到控件
 }

}

int Video::GetPlaySpeed()
{

 if(m_fps>0&&m_fps<1000)
 {
  m_speed=(int)(1000/m_fps);        //每一帧多少毫秒
  return m_speed;
 }
   return 0;

}

 

 

 

还有,在构造函数中要添加:

m_filepath="";             //文件路径
 m_isplay=FALSE;            //判断是否播放中
 m_framepos=0;              //帧位置
 m_totalframes=0;           //帧总数
 m_fps=0;                   //帧率
 m_speed=20;                //播放速度,初始为20

0 0
原创粉丝点击