摘 要:近些年来,数字技术发展迅猛,数字影视随之快速发展。其中,视频播放设备的播放控制系统的作用十分关键。本文将以OpenCV设备播放视频的控制系统为例,主要就视频播放设备播放控制系统展开研究。
关键词:OpenCV设备;视频播放;控制;系统
1 使用OpenCV设备播放视频的控制系统
使用OpenCV播放视频,几乎与使用它来显示图像一样容易。播放视频时只需要处理的新问题就是如何循环地顺序读取视频中的每一帧,以及如何从枯燥的电影视频的读取中退出该循环操作。具体如例1所示。
例1:下列简单的OpenCV程序,用于播放硬盘中的视频文件。
#include “highgui.h”int main ( int argc, char** argv ) { cvNamedWindow ( “Example2”, CV_WINDOW_AUTOSIZE );CvCapture* capture = cvCreateFileCapture ( argv[1] );IplImage* frame;while ( 1 ) { frame = cvQueryFrame ( capture );if ( !frame ) break;cvShowImage ( “Example2”, frame );char c = cvWaitKey ( 33 );if ( c == 27 ) break; } cvReleaseCapture ( &capture ); cvDestroyWindow ( “Example2” ); }
这里我们还是通过前面的方法创建一个命名窗口,在"例2"中,事情变得更加有趣了。
CvCapture* capture = cvCreateFileCapture ( argv[1] );
函数cvCreateFileCapture ( )通过参数设置确定要读入的AVI文件,返回一个指向CvCapture结构的指针。这个结构包括了所有关于要读入AVI文件的信息,其中包含状态信息。在调用这个函数后,返回指针所指向的CvCapture结构被初始化到所对应AVI文件的开头。
frame = cvQueryFrame ( capture );
一旦进入while ( 1 )循环,我们便开始读入AVI文件,cvQueryFrame的参数为CvCapture结构的指针。用来将下一帧视频文件载入内存 ( 实际是填充或更新CvCapture结构中 )。返回一个对应当前帧的指针。与cvLoadImage不同的是,cvLoadImage为图像分配内存空间,而cvQueryFrame使用已经在cvCapture结构中分配好的内存。这样的话,就没有必要通过cvReleaseImage ( )对这个返回的图像指针进行释放,当CvCapture结构被释放后,每一帧图像所对应的内存空间即会被释放。
c = cvWaitKey ( 33 ); if ( c == 27 ) break;
当前帧被显示后,我们会等待33 ms。 [11]如果其间用户触发了一个按键,c会被设置成这个按键的ASCII码,否则,c会被设置成-1。如果用户触发了ESC键 ( ASCII 27 ),循环被退出,读入视频停止。否则33 ms以后继续执行循环。
需要指出的是,在这个简单的例子程序中,我们没有使用任何准确的方法来控制视频帧率。我们只是简单的通过cvWaitKey来以固定时间间隔载入帧图像,,在一个精度要求更高的程序中,通过从CvCapture结构体中读取实际帧率是一个更好的方法!
cvReleaseCapture ( &capture );
例1所实现的AVI播放器无法在视频播放时进行快速拖动。我们的下一个任务就是通过加入一个滚动条来实现这个功能。
我们通过调用cvCreateTrackbar ( )来创建一个滚动条,并且通过设置参数确定滚动条所属于的窗口。为了获得所需的功能,只需要提供一个回调函数。具体如例2所示.
例2:用来添加滚动条到基本浏览窗口的程序:拖动滚动条,函数onTrackSlide ( )便被调用并被传入滚动条新的状态值
#include “cv.h”#include “highgui.h”int g_slider_position = 0;CvCapture*g_capture= NULL;void onTrackbarSlide ( int pos ) { cvSetCaptureProperty ( g_capture,CV_CAP_PROP_POS_FRAMES,pos ); } int main ( int argc, char** argv ) { cvNamedWindow ( “Example3”, CV_WINDOW_AUTOSIZE );g_capture = cvCreateFileCapture ( argv[1] );int frames = ( int ) cvGetCaptureProperty ( g_capture,CV_CAP_PROP_FRAME_COUNT );if ( frames!= 0 ) { cvCreateTrackbar ( “Position”,”Example3”,&g_slider_position,frames,onTrackbarSlide ); } IplImage* frame;// While loop ( as in Example 2 ) capture & show video ... // Release memory and destroy window...return ( 0 ); }
从本质上说,这种方法是通过添加一个全局变量来表示滚动条位置并且添加一个回调函数更新变量以及重新设置视频读入位置。我们通过一个调用来创建滚动条和确定回调函数 。下面让我们看看细节。
int gslider_position = 0; CvCapture* g_capture = NULL;
首先为滚动条位置定义一个全局变量。由于回调函数需要使用CvCapture对象,因此我们将它定义为全局变量。为了使我们的程序可读性更强,我们在所有全局变量名称前面加上g_。
void on Trackbar Slide ( int pos ) { cvSetCaptureProperty ( g_capture, CV_CAP_PROP_POS_FRAMES,pos );
现在我们定义一个回调函数,使其在滚动条被拖动时调用。滚动条的位置会被作为一个32位整数以参数形式传入。
值得注意的是,通过HighGUI创建的滚动条不像其他工具提供的滚动条功能这么全面。当然,也可以使用自己喜欢的其他窗口开发工具包来代替HighGUI,但是HighGUI可以较快地实现一些基本功能。
2 结束语
本文研究使用OpenCV设备播放视频的控制系统,旨在阐述视频播放控制系统的设计与实现,重在参考。
参考文献
[1]朱国华;数字放映设备常见故障处理[J];现代电影技术;2010,(01).
[2] 王建华;视频播放设备中的K系数指标的测量及应用[J];中国有线电视;2014, ( 19 ).
[3] 李相军;腾讯QLV视频如何移动播放[J];电脑爱好者;2013, ( 07 ).