一、视频播放控制
任务:通过加入一个滚动条来实现视频播放时进行快速拖动;并且实现滚动条随着视频的播放自由移动。
思路:通过添加一个全局变量来表示滚动条位置并且添加一个回调函数更新变量以及重新设置视频读入的位置;同时我们通过一个调用来创建滚动条和确定回调函数。
二、具体代码
// test_video_control.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
CvCapture* g_capture =NULL;//声明一个CvCapture类型指针 用于接收cvCreateFileCapture的返回值;通知这里注意全局变量都加上g_,便于阅读;由于回调函数中需要用到CvCapture对象所以要设置为全局变量
int g_slider_pos = 0;//记录当前滚动条的值,全局变量
int frame_count = 0;//计视频的帧数
void onTrackbarSlider(int pos) //滚动条回调函数;滚动条被拖动时调用 参数int pos 为当前滚动条所在的位置,作为参数传入
{
cvSetCaptureProperty(
g_capture,
CV_CAP_PROP_POS_FRAMES, //表示我们以帧数来设置读入位置
pos
); //设置g_capture的属性 使得从pos位置开始播放
frame_count = pos; //为了保证在拉动滚动条之后 保持帧的值与滚动条位置一致,如果不要这个语句,这拖动滚动条则没有用
}
int _tmain(int argc, _TCHAR* argv[])
{
cvNamedWindow("show"); //创建一个窗口
g_capture = cvCreateFileCapture("F:\\电影\\聚美优品广告 陈欧 我为自己代言 高清合江李波.avi");
int frames = (int)cvGetCaptureProperty(
g_capture,
CV_CAP_PROP_FRAME_COUNT
); //获取视频的总帧数
if(frames > 0)
{
cvCreateTrackbar(
"Position",
"show",
&g_slider_pos,
frames,
onTrackbarSlider
); //在窗口show上创建名字为Position的滚动条
}
IplImage* frame;
while(1)
{
frame = cvQueryFrame(g_capture);//从g_capture获取一帧图像
if(!frame)
{
break;
}
cvShowImage("show",frame);//显示图像
char c = cvWaitKey(33);//接收用户按键
if(c==27) //如果接收到 按‘Esc’退出循环
{
break;
}
cvSetTrackbarPos(
"Position",
"show",
frame_count
); //滚动条 随着视频的播放 进行同步移动
frame_count ++; //帧数+1
}
cvReleaseCapture(&g_capture);
cvDestroyWindow("show");
return 0;
}
三、代码中函数解析
(1)获取摄像头属性的函数
double cvGetCaptureProperty( CvCapture* capture, int 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 - 视频文件中帧的总数
(这里要注意一个bug:有时候函数cvGetCaptureProperty在cvQueryFrame被调用一次后,再调用cvGetCaptureProperty才会返回正确的数值。所以建议在调用此函数前先调用cvQueryFrame)
(2)设置摄像头属性的函数
int cvSetCaptureProperty( CvCapture* capture, int property_id, double value );
capture 视频获取结构。
property_id 属性标识符。可以是下面之一:
CV_CAP_PROP_POS_MSEC - 从文件开始的位置,单位为毫秒
CV_CAP_PROP_POS_FRAMES - 单位为帧数的位置(只对视频文件有效)
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的四个字符(只对摄像头有效)value 属性的值。
函数cvSetCaptureProperty设置指定视频获取的属性。目前这个函数对视频文件只支持: CV_CAP_PROP_POS_MSEC, CV_CAP_PROP_POS_FRAMES, CV_CAP_PROP_POS_AVI_RATIO
(3)创建滚动条
该函数为开放计算机视觉(OpenCV)库库函数,创建trackbar并将它添加到指定的窗口。
定义:
CV_EXTERN_C_FUNCPTR( void (*CvTrackbarCallback)(int pos) );
int cvCreateTrackbar( const char* trackbar_name, const char* window_name, int* value, int count, CvTrackbarCallback on_change );
trackbar_name 被创建的trackbar名字。
window_name 窗口名字,这个窗口将为被创建trackbar的父对象。
value 整数指针,它的值将反映滑块的位置。这个变量指定创建时的滑块位置。
count 滑块位置的最大值。最小值一直是0。
on_change 每次滑块位置被改变的时候,被调用函数的指针。这个函数应该被声明为void Foo(int); 如果没有回调函数,这个值可以设为NULL。
函数cvCreateTrackbar用指定的名字和范围来创建trackbar(滑块或者范围控制),指定与trackbar位置同步的变量,并且指定当trackbar位置被改变的时候调用的回调函数。
被创建的trackbar默认显示在指定窗口的顶端,可以通过函数cvGetTrackbarPos来获取trackbar显示的位置信息,以及通过函数cvSetTrackbarPos来重新设置trackbar的显示位置。
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
四、实验结果
本文尚不成熟,希望大家提出宝贵意见。
敬请关注本博客和新浪微博To_捭阖_youth.