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;
}

【运行结果】
 

【代码分析】

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;
}

【运行结果】


 

【代码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;
}

【运行结果】

【代码2的分析】

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

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

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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jackson61

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值