posts - 36,  comments - 28,  trackbacks - 0
 

#include <afx.h>
#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>

using namespace std;

/////////////////////////////////////////////////////////
//
作者:Flobert_Young
//
日期:2008-05-22
//
说明:
//  
需要配置OpenCV的开发环境,并且一定要确保当前Project里加入了cv.lib cxcore.lib highgui.lib
//
链接错误解决方法:
//  
编译时出现unresolved   external   symbol   __endthreadex 的处理方法
//  
菜单   Project->Settings...      C/C++   页,
//  
   Category   下拉框里选择   Code   Generation
//  
然后在   Use   run-time   library   里选择
//   Debug   Multithreaded   (   Debug  
版本时用   )
//  
或者   Multithreaded   (   release   版本时用).
/////////////////////////////////////////////////////////

enum CaptureCase
{
CAP_FROM_CAM = 0,
CAP_FROM_VIDEO = 1,
};

enum PlayVideoCase
{
FRAME_BY_FRAME = 0,
FRAME_BY_INDEX = 1,
};

//////////////////////////////////////
//
函数声明
int FrameByFrame(CvVideoWriter * pVideoWriter,IplImage *pFrame,bool bSave,
     CvCapture * pCapture,char *pVideoSaveName,int nWaitKeyTime);

int FrameByIndex(CvCapture * pCapture,IplImage *pFrame,

     int cap_prop,int cap_prop_value,
     CString strSaveImagePath);

//////////////////////////////////////
//
主函数部分
int main()
{
int ret = 0;
bool bErr = 0;
bool bSave = 0; //0 -
不保存视频文件;1 - 保存视频文件
CaptureCase cap_case = CAP_FROM_VIDEO;   //
设置成从视频文件中获取图像
PlayVideoCase play_case = FRAME_BY_FRAME; //
设置成一帧一帧的播放视频文件
int nWaitKeyTime = 40; //
显示图像所间隔的时间,以毫秒为单位

//////////////////////////////////////
//
变量声明
CvCapture * pCapture = NULL; //
用于在视频中捕获图像
char szVideoFileName[] = "C:\\
电影.AVI";   //!将打开的视频文件名设置成"C:\\1.mpg"
char szVideoSaveName[] = "C:\\VideoSave.avi"; //!
将保存视频文件的名字设置成"C:\\VideoSave.avi"
CString strSaveImagePath = "C:\\";    //!
保存图片的目录名
CvVideoWriter * pVideoWriter = NULL; //
用于保存视频文件
IplImage * pFrame = NULL;
IplImage * pImage = NULL;

switch(cap_case)
{
case CAP_FROM_CAM:
   //
函数cvCaptureFromCAM()参数说明:
   //
要使用的摄像头索引。如果只有一个摄像头或者用哪个摄像头也无所谓,那使用参数-1应该便可以。
   pCapture = cvCaptureFromCAM(-1); //
和函数cvCreateCameraCapture()有什么区别???
   if(NULL==pCapture) //
打开摄像头
   {
    cout<<"ERROR:
摄像头读取失败!"<<endl;
    bErr = 1;
   }
   break;

case CAP_FROM_VIDEO: //打开视频文件
   pCapture = cvCaptureFromFile(szVideoFileName); //
和函数cvCreateFileCapture()有什么区别???
   if(NULL==pCapture)
   {
    cout<<"ERROR:
视频文件读取失败!"<<endl;
    bErr = 1;
   }
   break;
}

if(!bErr)
{
   switch(play_case)
   {
   case FRAME_BY_FRAME:
    FrameByFrame(pVideoWriter,pFrame,bSave,pCapture,szVideoFileName,nWaitKeyTime);
    break;

   case FRAME_BY_INDEX:
    //
在窗口上显示视频的61%部分的那一帧图像
    int cap_prop_value = 61;
    FrameByIndex(pCapture,pFrame,CV_CAP_PROP_POS_AVI_RATIO,cap_prop_value,strSaveImagePath);
    break;
   }
}


char ch;
cin>>ch;


return ret;
}

int FrameByFrame(CvVideoWriter * pVideoWriter,IplImage *pFrame,bool bSave,
     CvCapture * pCapture,char *pVideoSaveName,int nWaitKeyTime)
{
int ret = 0;
/****************************************/
///////////////////////////
//1.
逐帧读取视频
int nCurFrameIndex = 0;
cvNamedWindow("Frame_By_Frame",1);

//在图像窗口左上角显示“Current Frame: **”字符串
CString strFrameString;
CvFont font;
cvInitFont( &font,CV_FONT_HERSHEY_SIMPLEX,0.5,0.5,0,2,8 );

//
创建视频文件写入器
//
第二个参数fourcc - 四个字符用来表示压缩帧的codec
//
例如,CV_FOURCC('P','I','M','1')MPEG-1 codec
//CV_FOURCC('M','J','P','G')
motion-jpeg codec等。
//
Win32下,如果传入参数-1,可以从一个对话框中选择压缩方法和压缩参数。
//
这里是按20/s进行写入视频文件的,但是当右键"C:\\VideoSave.avi"属性 -> 摘要,
//
发现持续时间: 0:00:02   帧速率: 500/???
//
如果改成30/s,则发现属性改为持续时间: 0:00:01   帧速率: 750/???
if(1==bSave)
{
   pVideoWriter = cvCreateVideoWriter(pVideoSaveName,-1,20,cvSize(640,480),1);
}
if((NULL!=pVideoWriter&&bSave)||(!bSave))
{  
   while(pFrame = cvQueryFrame(pCapture))
   {
    if(1==bSave)
    {
     //
将获取的视频文件一帧一帧的写入要保存的视频文件中
     cvWriteFrame(pVideoWriter,pFrame);
    }
   
    nCurFrameIndex++;
    strFrameString.Format("Current Frame: %d",nCurFrameIndex);
    cvPutText( pFrame,strFrameString,cvPoint( 5,pFrame->height-15 ),&font,cvScalar( 0,255,0 ) );
   
    cvShowImage("Frame_By_Frame",pFrame);
    if(0==bSave) //
如果是保存视频时,则加快显示速度
    {
     cvWaitKey(nWaitKeyTime);
    }
    else
    {
     cvWaitKey(10); //
如果选择保存视频时,好像不能够正常显示图像???
    }
   }
  
   if(1==bSave)
   {
    //
释放视频写入器
    cvReleaseVideoWriter(&pVideoWriter);
   }
  
   cvDestroyWindow("Frame_By_Frame");
   cvReleaseCapture(&pCapture);
}
else
{
   cout<<"ERROR:
创建CvVideoWriter * 失败!"<<endl;
}
/****************************************/

ret = 1;
return ret;
}

int FrameByIndex(CvCapture * pCapture,IplImage *pFrame,int cap_prop,int cap_prop_value,
     CString strSaveImagePath)
{
int ret = 0;

/****************************************/
///////////////////////////
//2.
读取第i帧视频
cvNamedWindow("FrameIndex_i",1);
//
目前这个函数对视频文件只支持:
//CV_CAP_PROP_POS_MSEC, CV_CAP_PROP_POS_FRAMES, CV_CAP_PROP_POS_AVI_RATIO
switch(cap_prop)
{
case CV_CAP_PROP_POS_MSEC:
   //
读取视频中第cap_prop_value秒的图像
   cvSetCaptureProperty(pCapture,CV_CAP_PROP_POS_MSEC,cap_prop_value);
   break;
  
case CV_CAP_PROP_POS_FRAMES:
   //
读取视频中第cap_prop_value帧的图像
   cvSetCaptureProperty(pCapture,CV_CAP_PROP_POS_FRAMES,cap_prop_value);
   break;
  
case CV_CAP_PROP_POS_AVI_RATIO:
   //
读取视频中cap_prop_value%处的图像
   double ratio = cap_prop_value/100.0; //100.0
是为了将除法的结果转化成浮点型
   cvSetCaptureProperty(pCapture,CV_CAP_PROP_POS_AVI_RATIO,ratio);
   break;
}

if(pFrame = cvQueryFrame(pCapture))
{
   //
保存当前图像
   CString strSaveImageName;
   CString strTmp;
   strTmp.Format("SaveImage_%d.bmp",cap_prop_value);
   strSaveImageName = strSaveImagePath + strTmp;
   cvSaveImage(strSaveImageName,pFrame);

   cvShowImage("FrameIndex_i",pFrame);
   cvWaitKey(-1);
}

cvDestroyWindow("FrameIndex_i");
cvReleaseCapture(&pCapture);
/****************************************/

ret = 1;
return ret;
}

posted on 2009-08-21 09:45 Hali 阅读(7180) 评论(0)  编辑 收藏 引用 所属分类: OpenCV
只有注册用户登录后才能发表评论。

<2009年11月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

常用链接

留言簿

随笔分类

随笔档案

休闲链接

学习链接

牛人博客

搜索

  •  

最新评论

阅读排行榜

评论排行榜