一个简单的实现代码:
#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的四个字符(只对摄像头有效)
转载于:https://blog.51cto.com/insiston/1715546