杨青锦
东北财经大学津桥商学院, 大连 116023
OpenCV下按视频帧率(FPS)播放视频
杨青锦
东北财经大学津桥商学院, 大连 116023
本文阐述了如何在OpenCV下按视频帧率(FPS)播放视频。程序使用了Windows系统下的高精度计时器控制视频播放的帧间隔时间。本文给出了高精度计时器的使用方法、实现时间控制功能的主要程序片段,并在文章的最后比较了高精度计时器与一般计时函数的精度。
OpenCV;帧率;高精度计时器;播放视频
OpenCV; fps; high-resolution timer; play video
OpenCV是Intel公司资助的开源计算机视觉库。它提供了几百个C/C++函数,实现了计算机视觉领域中大部分最常用的算法。使用OpenCV开发计算机视觉应用程序,经常要读取从摄像机获得的视频流或视频文件,获得其中的每一帧,再对该帧进行算法处理。如果要满足程序交互性的需要,通常还要将算法处理过的帧按原视频帧率(FPS, frame per second)显示出来。OpenCV提供了视频帧的读取、显示函数以及获得视频帧率属性的函数,而按帧率决定的帧时间间隔显示帧,则需要自己编程来解决。
在程序中,首先要取得视频的帧率属性,并由此计算出帧间隔时间,代码如下:
CvCapture* cvCreateFileCapture( const char* filename )的参数是要读取的文件名,函数返回指向CvCapture结构体的指针,该指针的作用类似于我们用fopen()函数打开文件,返回的指向FILE结构体的指针,之后我们可以通过这个指针操作视频文件。如果程序是从摄像机读取视频,则用cvCreateCameraCapture()代替该函数。
double cvGetCaptureProperty( CvCapture* capture, int property_id )的作用是得到视频的属性信息,参数CV_ CAP_PROP_FPS要求函数返回帧率。用1000除以帧率,就得到了以毫秒为单位的帧间隔时间。
通常一个处理视频的OpenCV程序主循环如下所示:
IplImage* cvQueryFrame( CvCapture* capture )的功能是顺序读取视频的一帧,如果视频结束,则返回的指针为NULL。程序接下来将对帧进行算法处理。在处理结束后,cvShowImage()将帧显示在名为Video的窗口中。cvWaitKey(40)的作用是延时40毫秒。假如我们对每一帧不做任何算法处理,那么该循环体的功能,就是将该视频以40毫秒的帧间隔(即25 fps)播放出来。然而在实际应用中,算法处理部分总会占用不定量的时间,所以延时固定时长的做法是不成立的。要使循环体的执行时间,即每一帧的处理时间,保持在帧率决定的帧间隔时间上,需要在循环体得首尾加入时间检测代码,即在开头获取开始时间,在末尾获取结束时间,两个时间的差值就是循环体执行时间。如果循环体执行时间小于帧间隔时间,则延时以确保循环体执行时间满足应有的帧间隔时间。
在Windows操作系统下,我们用API函数QueryPerformanceFrequency()和QueryPerformanceCounter()进行时间检测。这两个函数的声明如下:
QueryPerformanceFrequency()的输出值lpFrequency指向系统内高精度性能计数器的频率,QueryPerformanceCounter()的输出值lpPerformanceCount指向调用时刻高精度性能计数器的计数。在使用时,两次调用QueryPerformanceCounter(),所得结果的差值,除以QueryPerformanceFrequency()得到的频率,就得到两次调用的间隔时间。举例来说,如QueryPerformanceFrequency()得到的高精度性能计数器的频率是每秒50000次,先后两次调用QueryPerformanceCounter()得到的值分别是1500和3500,那么两次调用的时间间隔为(3500-1500)/50000=0.04秒。
上述两个函数的参数都是 LARGE_ INTEGER* 类型,LARGE_INTEGER的定义如下:
由上可见,LARGE_INTEGER代表了一个64位的整数,在一般程序中,我们只需要使用其低32位,即DWORD LowPart。
实现时间控制功能的完整程序片段如下所示:
在一般的对实时性要求不高的程序中,常使用Windows API函数GetTickCount()获取时间间隔。MSDN关于GetTickCount()的时间精度说明在10~16毫秒之间,这对于一般应用程序中的耗时计算是足够的,但对于帧时间间隔在毫秒级的视频播放来说,就显得精度不足了。MSDN推荐了高精度计时器QueryPerformanceFrequency()和QueryPerformanceCounter()用于更高精度的计时,虽然MSDN没有明确说明高精度计时器的所能达到的精度,因其精度取决于计算机处理器,但在笔者的实际应用中,高精度性能计数器完全可以满足视频播放的毫秒级精度。
最后补充一点,如果处理视频的循环体执行时间大于原视频的帧间隔时间,造成视频不能按原帧率播放,则需要优化每帧的处理算法,使每帧的处理时间保持在限度之内,满足实时性的需求。
[1]刘瑞祯,于仕琪.OpenCV教程 基础篇. 北京北京航空航天大学出版社, 2007.
[2]Intel OpenCV1.0安装包自带帮助文档.http:// opencvlibrary.sourceforge.net/,2007.
[3]Microsoft MSDN. http://msdn.microsoft.com/,4/10/2011.
How to play video at its original fps in OpenCV
Yang Qingjin
Kingbridge College of Dongbei University of Finance & Economics Dalian 116023
This article depicts how to play video at its original fps in OpenCV. The program uses highresolution timer of Windows system to play video at a certain frame interval. This article demonstrates the usage of high-resolution timer and the code segment implementing time control. In the end, this article compares the resolution between high-resolution timer and common timer function.
10.3969/j.issn.1001-8972.2012.21.032
杨青锦,1982,男,硕士,物流系统中的计算机视觉应用。