【#文档大全网# 导语】以下是®文档大全网的小编为您整理的《将视频文件按帧保存成图片》,欢迎阅读!
将视频文件按帧保存成图片
//利用OpenCV进行"视频的读取"与"保存视频文件或者图像"源码
#include #include #include #include #include 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 = 1; //0 – 不保存视频文件;1 – 保存视频文件
CaptureCase cap_case = CAP_FROM_VIDEO; //设置成从视频文件中获取图像 PlayVideoCase play_case = FRAME_BY_INDEX; //设置成一帧一帧的播放视频文件
int nWaitKeyTime = 40; //显示图像所间隔的时间,以"毫秒"为单位 ////////////////////////////////////// //变量声明
CvCapture * pCapture = NULL; //用于在视频中捕获图像
char szVideoFileName[] = "G:\\opencv实例\\1.avi"; //!将打开的视频文件名设置成"C:\\1.mpg"
char szVideoSaveName[] = "G:\\2.avi"; //!将保存视频文件的名字设置成"C:\\VideoSave.avi"
CString strSaveImagePath = "G:\\"; //!保存图片的目录名 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: 摄像头读取失败!"< bErr = 1; }
break;
case CAP_FROM_VIDEO: //打开视频文件
pCapture = cvCaptureFromFile(szVideoFileName); //和函数cvCreateFileCapture()有什么区别??? if(NULL==pCapture) {
cout<<"ERROR: 视频文件读取失败!"< bErr = 1; }
break; }
if(!bErr) {
switch(play_case) {
case FRAME_BY_FRAME:
FrameByFrame(pVideoWriter,pFrame,bSave,pCapture,szVideoSaveName,nWaitKeyTime); break;
case FRAME_BY_INDEX:
//在窗口上显示视频的61%部分的那一帧图像 int cap_prop_value = 0;
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(bSave==1) {
pVideoWriter =
cvCreateVideoWriter( "2.avi",CV_FOURCC('M','P','4','3'),15,cvSize(320,240),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(400); //如果选择保存视频时,好像不能够正常显示图
像??? } }
if(1==bSave) {
//释放视频写入器
cvReleaseVideoWriter(&pVideoWriter); }
cvDestroyWindow("Frame_By_Frame"); cvReleaseCapture(&pCapture); } else {
cout<<"ERROR:创建CvVideoWriter * 失败!"<}
/****************************************/ 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; }
for(int i=0;;i++) {
if(pFrame = cvQueryFrame(pCapture)) {
//保存当前图像
CString strSaveImageName; CString strTmp;
strTmp.Format("SaveImage_%d.bmp",i);
strSaveImageName = strSaveImagePath + strTmp; cvSaveImage(strSaveImageName,pFrame); cvShowImage("FrameIndex_i",pFrame); cvWaitKey(10); } }
cvDestroyWindow("FrameIndex_i"); cvReleaseCapture(&pCapture);
/****************************************/ ret = 1; return ret; }
本文来源:https://www.wddqxz.cn/8853e51fedfdc8d376eeaeaad1f34693daef10f1.html