OpenCV(五): Opencv视频播放控制

【例1】创建一个滚动条

 【代码】

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"

int g_slider_pos=0;
void on_changed(int pos)
{
	printf("The g_slider_pos is %d\n",g_slider_pos);
}

int main(int argc, char* argv[])
{
	cvNamedWindow("win");
	cvCreateTrackbar(
		"Position",
		"win",
		&g_slider_pos,
		400,
		on_changed
		);
	cvShowImage("win",NULL);
    cvWaitKey(0);
	cvDestroyWindow("win");
	return 0;
}
【运行结果】
OpenCV(五): Opencv视频播放控制_第1张图片

【代码分析】

1、创建滚动条  

      (1)定义:CV_EXTERN_C_FUNCPTR( void (*CvTrackbarCallback)(int pos) );
                该函数为开放计算机视觉(OpenCV)库库函数,创建trackbar并将它添加到指定的窗口
            int cvCreateTrackbar( const char* trackbar_name, const char* window_name, int* value, int count, CvTrackbarCallback on_change ); 

     (2)参数:
       trackbar_name 被创建的trackbar名字。
       window_name 窗口名字,这个窗口将为被创建trackbar的父对象。
      
value 整数指针,它的值将反映滑块的位置。这个变量指定创建时的滑块位置。
       count 滑块位置的最大值。最小值一直是0。
      on_change 每次滑块位置被改变的时候,被调用函数的指针。这个函数应该被声明为void Foo(int); 如果没有回调函数,这个值可以设为NULL。
 (3)作用:

      函数cvCreateTrackbar用指定的名字和范围来创建trackbar(滑块或者范围控制),指定与trackbar位置同步的变量,并且指定当trackbar位置被改变的时候调用的回调函数。
  被创建的trackbar
默认显示在指定窗口的顶端可以通过函数cvGetTrackbarPos来获取trackbar显示的位置信息,以及通过函数cvSetTrackbarPos来重新设置trackbar的显示位置。

2、回调函数

      回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

=============================================================================


2、 视频播放控制(视频的拖动:快进,倒退等)

【代码1】在例1的基础上进行改变,程序实现了在视频播放窗口添加滚动条,并且拖动滚动条来拖动视频的播放。(存在问题:拖动后视频继续播放,但滚动条不再移动)

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"

CvCapture* g_capture=NULL;//声明一个CvCapture类型指针,用于接收cvCreateFileCapture的返回值
int g_slider_pos=0;//记录滚动条的当前位置

//滚动条的回调函数  参数int pos 是指当前滚动条所在位置
void on_changed(int pos)
{
	//设置g_capture的属性,使得从位置pos开始播放视频
	cvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos);
}

int main(int argc, char* argv[])
{
	cvNamedWindow("win");
	g_capture=cvCreateFileCapture("f:\\1.avi"); //打开有一个视频文件

	//获取视频的总帧数
	int framecount=(int)cvGetCaptureProperty(g_capture,CV_CAP_PROP_FRAME_COUNT);
	
	//在窗口show上创建名字为Position的滚动条
	if(framecount>0)
	{
		cvCreateTrackbar(
		                 "Position",
		                 "win",
		                 &g_slider_pos,
		                 framecount,
		                 on_changed
	                	);
	}
	while(1)
	{
		IplImage* frame=cvQueryFrame(g_capture);
		if(!frame) break;
        cvShowImage("win",frame);
		char c=cvWaitKey(33);
		if(c==27) break;
	}

	cvReleaseCapture(&g_capture);
	cvDestroyWindow("win");
	return 0;
}
【运行结果】

OpenCV(五): Opencv视频播放控制_第2张图片

【代码1的分析】

1、cvSetCaptureProperty :设置视频获取属性
      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

2、cvGetCaptureProperty
      double cvGetCaptureProperty( CvCapture* capture, int property_id ) //返回值为double类型
       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 - 视频文件中帧的总数 

      【注】:有时候这个函数在cvQueryFrame被调用一次后,再调用cvGetCaptureProperty才会返回正确的数值。这是一个bug,建议在调用此函数前先调用cvQueryFrame。

============================================================================================

【代码2】在代码1的基础上再进行改动,实现拖动和视频播放同步。

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"

CvCapture* g_capture=NULL;//声明一个CvCapture类型指针,用于接收cvCreateFileCapture的返回值
int g_slider_pos=0;//记录滚动条的当前位置
int frame_count=0;//对视频帧进行计数的变量

//滚动条的回调函数  参数int pos 是指当前滚动条所在位置
void on_changed(int pos)
{
	//设置g_capture的属性,使得从位置pos开始播放视频
	cvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos);
	//在拉动滚动条后  保持变量frame_count与滚动条的位置是同步的
        frame_count = pos ;
}

int main(int argc, char* argv[])
{
	cvNamedWindow("win");
	g_capture=cvCreateFileCapture("f:\\1.avi"); //打开有一个视频文件

	//获取视频的总帧数
	int framecount=(int)cvGetCaptureProperty(g_capture,CV_CAP_PROP_FRAME_COUNT);
	
	//在窗口show上创建名字为Position的滚动条
	if(framecount>0)
	{
		cvCreateTrackbar(
		                 "Position",
		                 "win",
		                 &g_slider_pos,
		                 framecount,
		                 on_changed
	                	);
	}
	while(1)
	{
		IplImage* frame=cvQueryFrame(g_capture);
		if(!frame) break;
        cvShowImage("win",frame);
		char c=cvWaitKey(33);
		if(c==27) break;
		 
		//滚动条 随着视频的播放 进行移动
        cvSetTrackbarPos("Position","win", frame_count);
        frame_count++;
	}

	cvReleaseCapture(&g_capture);
	cvDestroyWindow("win");
	return 0;
}
【运行结果】

OpenCV(五): Opencv视频播放控制_第3张图片

【代码2的分析】

1、第7行代码:int frame_count=0;//对视频帧进行计数的变量

2、第15行代码: frame_count = pos ;//在拉动滚动条后  保持变量frame_count与滚动条的位置是同步的

3、第46、47行代码://滚动条 随着视频的播放 进行移动

        cvSetTrackbarPos("Position","win", frame_count);
        frame_count++;

你可能感兴趣的:(滚动条,opencv,控制,视频播放)