opencv学习笔记(2)视频文件的读取与保存

main 函数输入参数 argc、argv 的意义(参见[1])

在学习笔记(1)中最后写到:“在Debug完成后,应该把原始图像放到项目文件夹的 debug 文件夹中,使图像与exe程序在同一文件夹内,才能在运行程序时正确读入并显示图像。”其实是有误的,图像不一定要与exe程序在同一文件夹内,在 cvLoadImage( argv[1] ) 中,可以把 argv[1] 改成项目文件夹里的图片的具体地址,若图片与程序同一文件夹,直接写图片的文件名即可。 
但是,这种在程序代码中写文件名的方式很不方便,每次更改图片文件后都要重新编译,实际上应该在跑程序时不改argv[1],而是在调用时输入具体的文件名。要解决这个问题,就要理解好main 函数输入参数 argc、argv 的意义。

     int main(int argc, char** argv) 
     int main(int argc, char* argv[])

argc 是指命令行输入参数的个数,argv 则存储了所有的命令行参数。假如我的一个程序是video_test.exe,如果在命令行运行该程序(首先应该在命令行下用 cd 命令进入到 video_test.exe 文件所在目录),要处理的文件有 v1.avi、v2.mpg,运行命令为:

      video_test.exe v1.avi v2.mpg

那么,argc的值是 3,argv[0]是"video_test.exe",argv[1]是"v1.avi",argv[2]是"v2.mpg"。

视频文件的读取与基本处理

这里主要是依照《Learning OpenCV》一书的例程修改实现的,其功能是读取2个视频文件,分别在两个窗口中播放,每个窗口都加入一个进度条,可以自行用鼠标控制播放进度。代码如下:

建立一个Win32 Console项目 

#include <iostream>
#include <cv.h>
//#include <cvaux.h>
#include <cxcore.h>
#include <highgui.h>

// 使用标准命名空间
using namespace std;

// 初始化进度条的位置
int g_slider_position1 = 0;
int g_slider_position2 = 0;

CvCapture* g_capture1 = NULL;
CvCapture* g_capture2 = NULL;

// 定义回调函数用于播放进度的控制 
void onTrackbarSlide1( int pos1 )
{
 cvSetCaptureProperty( g_capture1, CV_CAP_PROP_POS_FRAMES, pos1 );
}
void onTrackbarSlide2( int pos2 )
{
 cvSetCaptureProperty( g_capture2, CV_CAP_PROP_POS_FRAMES, pos2 );
}


int main(int argc, char** argv )
{
 // 建立播放窗口
 cvNamedWindow( "Video Test 1", CV_WINDOW_AUTOSIZE );
 cvNamedWindow( "Video Test 2", CV_WINDOW_AUTOSIZE );

 // 捕捉视频文件
 g_capture1 = cvCreateFileCapture( "C:\\Users\\Administrator.PC-20131206COUD\\Desktop\\video\\1.mp4");
 g_capture2 = cvCreateFileCapture( "C:\\Users\\Administrator.PC-20131206COUD\\Desktop\\video\\2.mp4" );

 // 读取、显示视频文件的帧数
 int frames1 = (int) cvGetCaptureProperty( g_capture1, CV_CAP_PROP_FRAME_COUNT );
 cout << "frames1 = " << frames1 << endl;
 // 建立进度条
 if( frames1 != 0 )
  cvCreateTrackbar( 
   "Position", 
   "Video Test 1", 
   &g_slider_position1, 
   frames1, 
   onTrackbarSlide1
  );

 int frames2 = (int) cvGetCaptureProperty( g_capture2, CV_CAP_PROP_FRAME_COUNT );
 cout << "frames2 = " << frames2 << endl;
 if( frames2 != 0 )
  cvCreateTrackbar( 
   "Position", 
   "Video Test 2", 
   &g_slider_position2, 
   frames2, 
   onTrackbarSlide2 
  );

// 读取视频文件信息
 double fps1 = (int) cvGetCaptureProperty( g_capture1, CV_CAP_PROP_FPS );
 double fps2 = (int) cvGetCaptureProperty( g_capture2, CV_CAP_PROP_FPS );
 CvSize size1 = cvSize( 
  (int)cvGetCaptureProperty(g_capture1, CV_CAP_PROP_FRAME_WIDTH),
  (int)cvGetCaptureProperty(g_capture1, CV_CAP_PROP_FRAME_HEIGHT));
 CvSize size2 = cvSize( 
  (int)cvGetCaptureProperty(g_capture2, CV_CAP_PROP_FRAME_WIDTH),
  (int)cvGetCaptureProperty(g_capture2, CV_CAP_PROP_FRAME_HEIGHT));

// 创建 VideoWriter 
 CvVideoWriter* wrVideo1 = cvCreateVideoWriter("3.mp4", CV_FOURCC('M','J','P','G'), fps1, size1);
 CvVideoWriter* wrVideo2 = cvCreateVideoWriter("4.mp4", CV_FOURCC('M','J','P','G'), fps2, size2);

 int frs = 0;

 // 开始播放并保存视频
 IplImage* frame1;
 IplImage* frame2;
 
 while( frs < frames1 && frs < frames2 )
 {

  // 获取、显示源文件的帧画面
  frame1 = cvQueryFrame( g_capture1 );
  if( !frame1 ) break;
  cvShowImage( "Video Test 1", frame1 );

  frame2 = cvQueryFrame( g_capture2 );
  if( !frame2 ) break;
  cvShowImage( "Video Test 2", frame2 );

  // 保存:将当前帧写入到目标视频文件

  cvWriteFrame( wrVideo1, frame1 );
  cvWriteFrame( wrVideo2, frame2 );
  
  // 若按下 ESC 键,则退出程序
  char c = cvWaitKey(33);
  if( c==27 ) break;
 }
 // 释放内存,关闭窗口
 cvReleaseCapture( &g_capture1 );
 cvReleaseCapture( &g_capture2 );
 cvReleaseVideoWriter( &wrVideo1 );
 cvReleaseVideoWriter( &wrVideo2 );
 cvDestroyWindow( "Video Test 1" );
 cvDestroyWindow( "Video Test 2" );

 return 0;
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值