OpenCV 播放视频时如何使滚动条跟着视频流移动
学习OpenCV一书中,有一个给视频播放加滚动条的例子。例子中在播放视频的过程中,给视频播放控制增加了一个进度条控制的功能。但是这个控制却是单向的,即只能通过进度条对当前播放的帧进行修改,却不能让当前帧显示在滚动条上。
利用setTrackbar函数,我们通过一个全局变量跟踪当前播放的帧数。例程本身隐藏了highgui为回调函数和trackbar控制相互影响的背后机制。在onTrackbarSlide函数中,变量pos记录下了当前trackbar的输入,即滑块的位置。通过一个全局变量g_trackbar_pos将输入(如果有)的滑块位置传递到主程序的循环中,再通过无输入时,帧顺序播放的帧递加关系来控制参数的递增。进而实现这一功能。
程序中的
#pragma comment( lib, "vfw32.lib" )
#pragma comment( lib, "comctl32.lib" )
是用来对视频播放相关的库进行预编译,没有库链接问题的筒子可以把这两句注释掉。
// videoslider.cpp -- open a video
#include <iostream>
#include <opencv2\opencv.hpp>
#include "highgui.h"
#pragma comment( lib, "vfw32.lib" )
#pragma comment( lib, "comctl32.lib" )
using namespace std;
using namespace cv;
int g_slider_position = 0;
CvCapture* g_capture = NULL;
int g_trackbar_pos = 0; // global trackbar position recorder
void onTrackbarSlide(int pos)
{
cvSetCaptureProperty(
g_capture,
CV_CAP_PROP_POS_FRAMES,
pos
);
g_trackbar_pos = pos;
}
int main()
{
cvNamedWindow("VideoSlider", CV_WINDOW_AUTOSIZE);
g_capture = cvCreateFileCapture("C:\\Users\\dm\\Desktop\\18_02.avi");
int frames = (int)cvGetCaptureProperty(
g_capture,
CV_CAP_PROP_FRAME_COUNT);
if (frames != 0)
{
cvCreateTrackbar(
"Position",
"VideoSlider",
&g_slider_position,
frames,
onTrackbarSlide);
}
IplImage* frame;
while (1)
{
frame = cvQueryFrame(g_capture);
if (!frame) break;
cvShowImage("VideoSlider", frame);
setTrackbarPos("Position", "VideoSlider", g_trackbar_pos); // set trackbar position
char c = waitKey(33);
g_trackbar_pos++; // let trackbar moving
if (c == 27) break;
}
cvReleaseCapture(&g_capture);
cvDestroyWindow("VideoSlider");
return 0;
}