opencv视频学习第五课(视频播放控制)笔记整理

这次是学习怎么创建一个控制台的滚动条,并且使用它控制视频的播放。为了测试一些东西,改编了视频教程中的代码。

#include "stdafx.h"
#include "highgui.h"
#include "cv.h"
CvCapture* g_capture = NULL;
//记录滚动条的当前位置
int g_slider_pos = 0;
//对视频帧进行计数的变量
int frame_count = 0;

void onTrackbarSlider(int pos)//回调函数
{
	//设置g_capture的属性,从位置pos开始播放视频
	cvSetCaptureProperty(
		g_capture,
		CV_CAP_PROP_POS_FRAMES,//单位为帧数的位置
		pos//当前滚动条的位置
		);
	frame_count =pos;
	//printf("frame_count is %dpos is %d\n-------\n",frame_count,pos);
}

int main(int argc, char* argv[])
{
	IplImage* frame;
	cvNamedWindow("show");
	CvCapture* tmp = cvCreateFileCapture("E:\\狸窝转换结果\\oldfriends.avi");
	printf("使用代码1.2,屏蔽代码1.1和代码2.1\n");
	/*-----------------1、获取总帧数---------*/
	frame = cvQueryFrame(tmp);
	//获取视频的总帧数
	int frames = 0;

	/*-----------------代码1.1---------*/
	/*frames =(int)cvGetCaptureProperty(
		            tmp,
					CV_CAP_PROP_FRAME_COUNT
					);
	*/
	/*-----------------代码1.1end---------*/
	/*-----------------代码1.2---------*/
	while(frame != NULL ){
		frame = cvQueryFrame(tmp);
		frames++;
	}
	cvReleaseCapture(&tmp);
	/*-----------------代码1.2end---------*/
	printf("总帧数 is %3d\n",frames);

	/*-----------------获取总帧数-----------*/
	g_capture = cvCreateFileCapture("E:\\狸窝转换结果\\oldfriends.avi");

	if(frames>0)
	{
		cvCreateTrackbar(
			"Position",//创建的名字
			"show",//窗口名字
			&g_slider_pos,//整数指针,它的值将反应滑块位置
			frames,//滑块位置的最大值
			onTrackbarSlider//每次滑块位置被改变的时候,被调用的指针
			);
	}

	int count = 0;
	while(1)
	{
		frame = cvQueryFrame(g_capture);//返回视频文件的下一帧

		if(!frame){
			printf("NULL\n");
			break;
		}
		cvShowImage("show",frame);
		char c = cvWaitKey(33);
		if(c==27)//Esc按键
		{
			cvWaitKey(0);//break;
		 }

		/*-----------------2、设置滚动条位置---------*/
		/*-----------------代码2.1---------*/
		//cvSetTrackbarPos("Position","show",frame_count);//通过单步调试,发现执行这一步时会调用到onTrackbarSlider()函数
		/*-----------------代码2.1end---------*/
		/*-----------------设置滚动条位置-----------*/
		frame_count++;
		count++;
	}
	printf("累加值:frame_count is %3d,count is %3d\n",frame_count,count);
	cvReleaseCapture(&g_capture);
	cvDestroyWindow("show");

	return 0;
}

上述代码中有几个函数值得深入研究

1、double cvGetCaptureProperty(CvCapture* capture, int property_id)//获取摄像头属性的函数

capture:源文件指针

property_id: 控制返回的属性,其中

CV_CAP_PROP_POS_MSEC - 影片目前位置,为毫秒数或者视频获取时间戳

CV_CAP_PROP_POS_FRAMES - 将被下一步解压/获取的帧索引,以0为起点

CV_CAP_PROP_POS_AVI_RATIO - 视频文件的相对位置(0 - 影片的开始,1 - 影片的结尾)

CV_CAP_PROP_FRAME_WIDTH - 视频流中的帧宽度

CV_CAP_PROP_FRAME_HEIGHT - 视频流中的帧高度

CV_CAP_PROP_FPS - 帧率

CV_CAP_PROP_FOURCC - 表示codec的四个字符

CV_CAP_PROP_FRAME_COUNT视频文件中帧的总数(本课时需要使用的属性)

注:1.有时调用函数cvGetCaptureProperty需要调用cvQueruFrame一次后才返回正确的值。这是软件存在的一个bug.

2.cvGetCaptureProperty函数实际是通过读取视频文件头信息返回数据,不是真正读取视频文件。因此不同格式视频文件转换成opencv所支持的avi格式后,使用该函数去读取时,会造成信息的不准确。(主要参考http://blog.sina.com.cn/s/blog_4b0020f301012dbz.html)

2、cvCreateTrackbar()创建滚动条

定义:

CV_EXTERN_C_FUNCPTR(void(*CvTrackbarCallback)(int pos));//回调函数的格式,返回值是void,参数是int。不能随意定义

int cvCreateTrackbar(const char* trackbar_name,//创建的名字

const char* window_name,//窗口名字

int* value,//整数指针,它的值将反应滑块位置

int count,//滑块位置的最大值

CvTrackbarCallback on_change//每次滑块位置被改变的时候,被调用的指针,回调函数

);

回调函数就是一个通过函数指针调用的函数。

如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。

3、int cvSetCaptureProperty( CvCapture* capture, int property_id, double value );//设置视频获取属性

4、cvSetTrackbarPos设置滚动条的值

根据cvGetCaptureProperty函数中提到的获取值不正确问题,我做了一个实验。

使用狸窝工具,将一个rmvb视频转成avi然后进行测试。测试数据如下:

对于这样的结果,我表示深深的疑惑。

首先图1图3和图2图4的对比可以看出,之前说到的cvGetCaptureProperty函数获取的值不正确这个问题是存在的。

其次,看到图3,为什么获取的总帧数是734,后来运行的时候帧数却可以达到879?对比了图1图2和图3图4之后,可以发现这个问题和cvSetTrackbarPos()、cvSetCaptureProperty()这两个函数有关。

是不是在使用函数的时候修改了什么东西,具体的还需要找到这两个函数的源代码看看才知道。

时间: 10-05

opencv视频学习第五课(视频播放控制)笔记整理的相关文章

Web前端学习-第五课JavaScript篇

Q9:什么是跨域?什么是JSON?什么是JSONP?解决跨域问题有哪些方法?请结合代码和文字说明. 跨域:因为JavaScript同源策略(一段脚本只能读取来自同一来源的窗口和文档的属性,同一来源指主机名,协议和端口号的组合)的限制,a.com域名下的js无法操作b.com域名下的对象,只要是协议,域名,端口有任何一个不同都被当做是不同的域: Json(JavaScript Object Notation):一种轻量级的数据交换格式.基于ECMAScript的一个子集.采用完全独立于语言的文本格

英语学习第五课总结

1.logic 逻辑,logical 逻辑的(音译词) 2.urban 城市的 urba+n = 谐音“欧巴+嗯~” = 城里人 3.suburban 郊区的,suburb 郊区 subway 地下铁,前缀sub- = 下 4.rural  = 谐音“卤肉” = 乡下的 5.Engine 引擎(音译词) Motor 马达(音译词) 6.camel 骆驼 camel = 谐音“楷模” = 骆驼 7.System 系统(音译词);身体 8.shock 休克(音译词):使震惊 9.scan 细看(谐音

javascript学习第五课this、call、apply

this 对象是在运行中基于函数的执行环境绑定的,在全局函数中,this等于window,而当函数被 作为某个对象的方法调用时,this等于那个对象 也就是说this关键字就是指代调用者. call.apply示例: 1.简单用法:绑定一些函数,用于传递参数.调用 2.用于扩展用于函数运行的作用域: js没有块级作用域的概念: 模拟高级语言实现块级作用域的功能示例: 通过运用匿名函数自执行实现: 闭包: 闭包示例:

Web前端学习-第五课HTML篇

Q12:HTML5有哪些新颖? 1.用于绘画的canvas元素: 2.用于媒介回放的video和audio元素: 3.对本地离线存储的更好的支持: 4.新的特殊内容元素,比如article,footer,header,nav,section: 5.新的表单控件,比如calender,date,time,Email,URL,search: 6.新特性基于HTML,css,DOM,以及JavaScript: 7.减少对外部插件的需求: 8.更优秀的错误处理: 9.更多取代脚本的标记: 10.HTML

黑 马 程 序 员_视频学习总结<c语言>----02 printf和scanf函数、基本语句和运算、流程控制、函数、数组、字符串

---------------------- ASP.Net+Unity开发..Net培训.期待与您交流! ---------------------- 一.printf函数 1.在使用peintf函数前必须加入#include <stdio.h>,使用它可以向标准输出设备(比如屏幕)输出数据,其中使用格式是 printf(“字符串”) :或者 printf(“字符串”, 格式符参数): 2.常用的格式符及其含义如图所示 3.格式符还可以添加输出宽度 二.scanf函数 1.在使用scanf函

BeagleBone Black板第五课:Shell脚本编程实验

BBB板第五课:Shell脚本编程实验 在一上课我们通过简单的echo命令测试并控制GPIO端口的高低电平输出,实现对一个LED指示灯的点亮和关闭控制,本节将通过Shell脚本编程,来完成两个LED指示灯的交替闪亮的实验. 实验器材:准备两个二极管指示灯,面包板等 使用GPIO端口P8.12和P8.11两个引脚 我们暂时不借助其他工具软件,直接远程登陆到BBB板的图形桌面,使用内置的Ledfpad编辑器来完成Shell脚本的编程. 远程登陆BBB板图形桌面还记得吧,不记得话参考前面的课程,这里就

秦涛:深度学习的五个挑战和其解决方案

深度学习的五个挑战和其解决方案 编者按:日前,微软亚洲研究院主管研究员秦涛博士受邀作客钛媒体,分享他对深度学习挑战和解决方案的思考 ,本文为秦涛博士在此次分享的实录整理. 大家好,我是微软亚洲研究院的秦涛,今天我将分享我们组对深度学习这个领域的一些思考,以及我们最近的一些研究工作.欢迎大家一起交流讨论. 先介绍一下我所在的机器学习组.微软亚洲研究院机器学习组研究的重点是机器学习,包含机器学习的各个主要方向,从底层的深度学习分布式机器学习平台(AI的Infrastructure)到中层的深度学习.

【Linux探索之旅】第一部分第五课:Unity桌面,人生若只如初见

内容简介 1.第一部分第五课:Unity桌面,人生若只如初见 2.第一部分第六课预告:Linux如何安装在虚拟机中 Unity桌面,人生若只如初见 不容易啊,经过了前几课的学习,我们认识了Linux是什么,以及如何安装Linux系统(我们以Ubuntu这个Linux发行版为以后的演示系统),我们也在上一课终于把Ubuntu安装好了. "很不错,掌声给自己". 安装Ubuntu遇到什么问题,可以在我们的QQ群和微信群提问,也可以私信小编,QQ.微信.邮件都行.联系方式在下面. Linux

NeHe OpenGL教程 第三十五课:播放AVI

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第三十五课:播放AVI 在OpenGL中播放AVI: 在OpenGL中如何播放AVI呢?利用Windows的API把每一帧作为纹理绑定到OpenGL中,虽然很慢,但它的效果不错.你可以试试. 首先我得说我非常喜欢这一章节.Jonat