opencv视频读写和视频等间隔采样

今天学习了opencv的HighGUI的内容

总结了两个视频读写demo以备以后进行视频处理和识别用


demo1 视频的读取和写入

按顺序读取视频的每一帧。对于读取的每一帧图像,显示在窗口中,然后转化为灰度图像输出到指定的文件中。

运行期间可以按ESC键退出。

还可以用鼠标调整滚动条来动态改变视频的播放位置。滚动条的位置≈想要播放的帧在整个视频中的位置

比如将滚动条调整到如下图所示位置,直接将视频跳转到视频总长度一半的位置开始播放

滚动条的位置想要播放的帧在整个视频中的位置  这里之所以是“约等于”,是因为opencv采用的帧定位的函数默认使用的是关键帧的定位方式,导致视频跳转的位置并不准确。

具体可以参见SetCaptureProperty定位不准的原因

另外有个容易出错的地方,创建视频写入器的命令:CvVideoWriter* wrVideo1 = cvCreateVideoWriter(out1, CV_FOURCC('X','V','I','D'), fps1, size1,0);

最后有个参数是0,表示输出的视频文件是灰度的。如果不设置,默认的参数取值为1,代表输出的视频文件是彩色的。如果此时将图像转换成灰度图后输出。运行视频文件是系统会提示错误。

对于这一点的描述可以参见opencv彩色图像转灰度图像失败的原因


demo1的源代码如下:

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

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

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

//初始化视频捕获器
CvCapture* g_capture1 = NULL;

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

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

	// 捕捉视频文件
	char video1[] = "yssh.avi";

	//创建指定视频文件的捕获器
	g_capture1 = cvCreateFileCapture( video1 );

	// 读取视频文件的总帧数并显示
	int frames1 = (int) cvGetCaptureProperty( g_capture1, CV_CAP_PROP_FRAME_COUNT );
	cout << "总帧数 = " << frames1 << endl;
	
	// 读取视频文件每秒显示帧数信息
	double fps1 = cvGetCaptureProperty( g_capture1, CV_CAP_PROP_FPS );
	cout << "fps1 = " << fps1 << endl;

	//读取视频文件每帧图像大小信息
	CvSize size1 = cvSize( 
		(int)cvGetCaptureProperty(g_capture1, CV_CAP_PROP_FRAME_WIDTH),
		(int)cvGetCaptureProperty(g_capture1, CV_CAP_PROP_FRAME_HEIGHT));

	// 建立进度条
	if( frames1 != 0 )
		cvCreateTrackbar( 
		"Position", 
		"Video Test 1", 
		&g_slider_position1, 
		frames1, 
		onTrackbarSlide1
		);

	// 创建 VideoWriter 
	char out1[] = "out1.avi";

	//CvVideoWriter* wrVideo1 = cvCreateVideoWriter(out1, CV_FOURCC('M','J','P','G'), fps1, size1,0);
	//创建视频写入器
	CvVideoWriter* wrVideo1 = cvCreateVideoWriter(out1, CV_FOURCC('X','V','I','D'), fps1, size1,0);

	// 记录视频的某一帧
	IplImage* frame1;

	//记录视频某一帧转换后的灰度图像
	IplImage* gray1 = cvCreateImage(size1, 8, 1);

	//读取并播放视频,直至播放结束/主动退出
	while( true  )
	{
		// 获取源文件的一帧画面
		frame1 = cvQueryFrame( g_capture1 );
		if( !frame1 ) break;
		//显示这一帧
		cvShowImage( "Video Test 1", frame1 );

		// 将当前帧转换为灰度图像
		cvCvtColor(frame1 ,gray1, CV_RGB2GRAY);

		// 保存:将当前帧(灰度图)写入到目标视频文件
		cvWriteFrame( wrVideo1, gray1 );

		// 若按下 ESC 键,则退出程序
		char c = cvWaitKey(33);
		if( c == 27 ) break;	
	}

	// 释放内存,关闭窗口
	cvReleaseCapture( &g_capture1 );
	cvReleaseVideoWriter( &wrVideo1 );
	cvDestroyWindow( "Video Test 1" );

	return 0;
}



demo2 视频等间隔采样

程序按顺序读取视频的每一帧,对于满足固定间隔的帧图像,显示并输入,不满足的直接跳过。

这个demo可以用于等间隔的从视频中抽取图像,以备以后进行视频处理和识别用


demo2的源代码如下:

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

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

//初始化视频捕获器
CvCapture* g_capture1 = NULL;


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

	// 捕捉视频文件
	char video1[] = "yssh.avi";

	//创建指定视频文件的捕获器
	g_capture1 = cvCreateFileCapture( video1 );

	// 读取视频文件的总帧数并显示
	int TotalFrames = (int) cvGetCaptureProperty( g_capture1, CV_CAP_PROP_FRAME_COUNT );
	cout << "总帧数 = " << TotalFrames << endl;
	
	// 读取视频文件每秒显示帧数信息
	double fps1 = cvGetCaptureProperty( g_capture1, CV_CAP_PROP_FPS );
	cout << "fps1 = " << fps1 << endl;

	//读取视频文件每帧图像大小信息
	CvSize size1 = cvSize( 
		(int)cvGetCaptureProperty(g_capture1, CV_CAP_PROP_FRAME_WIDTH),
		(int)cvGetCaptureProperty(g_capture1, CV_CAP_PROP_FRAME_HEIGHT));

	//CvVideoWriter* wrVideo1 = cvCreateVideoWriter(out1, CV_FOURCC('M','J','P','G'), fps1, size1,0);
	//创建视频写入器VideoWriter
	char out1[] = "IntervalOutput.avi";
	CvVideoWriter* wrVideo1 = cvCreateVideoWriter(out1, CV_FOURCC('X','V','I','D'), fps1, size1,0);

	// 记录视频的某一帧
	IplImage* frame1;

	//记录视频某一帧转换后的灰度图像
	IplImage* gray1 = cvCreateImage(size1, 8, 1);

	int position=0;
	int interval=10;  //这里指定一个抽取视频间隔

	//读取并播放视频,直至播放结束/主动退出
	while( true  )
	{
		// 先获取源文件的一帧画面
		frame1 = cvQueryFrame( g_capture1 );

		if( !frame1 ) //视频读取完毕
			break; 

		position=(int)cvGetCaptureProperty( g_capture1, CV_CAP_PROP_POS_FRAMES);

		if(position%interval!=0) 
			continue;

		//显示这一帧
		cvShowImage( "Video Test 1", frame1 );

		// 将当前帧转换为灰度图像
		cvCvtColor(frame1 ,gray1, CV_RGB2GRAY);

		// 保存:将当前帧(灰度图)写入到目标视频文件
		cvWriteFrame( wrVideo1, gray1 );

		// 若按下 ESC 键,则退出程序
		char c = cvWaitKey(33);
		if( c == 27 ) break;	
	}

	// 释放内存,关闭窗口
	cvReleaseCapture( &g_capture1 );
	cvReleaseVideoWriter( &wrVideo1 );
	cvDestroyWindow( "Video Test 1" );

	return 0;
}
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值