一个简单的实现代码:

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

//设置全局变量,一个为滚动条的位置。回调函数需要用到的变量cvCapture也是全局变量,所以前面有g_,代表global

CvCapture*g_capture = NULL;//用来保存图像捕获的信息的结构体
int g_slider_pos = 0;
int frame_count = 0;//记录播放的帧数


//当鼠标滑动滑块的时候 调用该回调函数
void onTrackbarSlider(int pos)//这个参数由cvCreateTrackbar传入  它反映了当前滑块被滑到的位置
{
	//设置当前视频文件的属性
	cvSetCaptureProperty(
		g_capture,
		CV_CAP_PROP_POS_FRAMES,//单位为帧数的位置(只对视频文件有效)
		pos                    //设置指定视频获取的属性
		);
	frame_count = pos;
}

int main()
{
	cvNamedWindow("show");//创建窗口
	g_capture = cvCreateFileCapture("E:\\Linux基础知识与系统管理\\01 运维基础\\01_01_面授班开场.avi");//获取视频文件
	//获取视频的全部帧数frames
	int frames = (int)cvGetCaptureProperty(
		g_capture,
		CV_CAP_PROP_FRAME_COUNT//视频文件中帧的总数
		);
	if (frames > 0)
	{
		//创建进度条
		//当你滑动滑块的时候 会触发一个事件执行cvCreateTrackbar 然后cvCreateTrackbar调用onTrackbarSlider 然后返回while接着以前继续循环
		//cvCreateTrackbar这个函数系统调用    onTrackbarSlider我们自己填写代码实现
		cvCreateTrackbar(
			"Pos", //进度条名称
			"show",//所在窗口
			&g_slider_pos,//滑块的位置
			frames,//滑块位置的最大值。最小值一直是0
			onTrackbarSlider//回调函数   这里面回调函数的声明参数必须是×××的  返回值为void
			//当你用鼠标拉动滑块的时候 就会产生一个消息  来执行这个回调函数
			);
	}
	IplImage*frame;
	while (true)
	{
		frame = cvQueryFrame(g_capture);//从摄像头或者文件中抓取并返回一帧
		//cvQueryFrame的参数为CvCapture结构的指针。用来将下一帧视频文件载入内存,返回一个对应当前帧的指针
		if (!frame)
		{
			break;
		}
		cvShowImage("show",frame);

		char c = cvWaitKey(33);//控制频率
		if (c == 27)//ESC键
		{
			break;
		}
		//设置滑块的位置   实现滑块随视频的播放而移动
		cvSetTrackbarPos(
			"pos",
			"show",
			frame_count//滑块的位置
			);
		frame_count++;//每播放一帧的时候  加一
	}
	//释放资源
	cvReleaseCapture(&g_capture);
	cvDestroyWindow("show");
	return 0;
}


函数解释:


获取视频文件和摄像头属性的函数

/* retrieve or set capture properties */
CVAPI(double) cvGetCaptureProperty( CvCapture* capture,                                   int property_id );
capture     要获取的视频文件指针
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:

 有时候cvGetCapturePropetry在cvQueryFrame被调用一次后在调用cvGetCapturePropetry才会返回正确的数值


创建一个滚动条

* create trackbar and display it on top of given window, set callback */
CVAPI(int) cvCreateTrackbar( const char* trackbar_name, //滚动条的名字
              const char* window_name,   //所在窗口的名字 
        int* value,                //指定创建时的滑块位置
     int count,                 //滑块位置的最大值。最小值一直是0
     CvTrackbarCallback on_change CV_DEFAULT(NULL));
     //每次滑块位置改变时,调用该回调函数
 
 //typedef void (CV_CDECL *CvTrackbarCallback)(int pos);
 //on_change 每次滑块位置被改变的时候,被调用函数的指针。
 //这个函数应该被声明为void Foo(int); 如果没有回调函数,这个值可以设为NULL


回调函数:


 回调函数就是一个通过函数指针调用的函数

 如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数

    回调函数不是由该函数的实现方法直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应

编辑

机制:

⑴定义一个回调函数;

⑵提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者;

⑶当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理



设置摄像头属性的函数

CVAPI(int)    cvSetCaptureProperty( 
                   CvCapture* capture, //视频获取结构
                   nt property_id,    // 属性标识符
                   double value );
                                    
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的四个字符(只对摄像头有效)