opencv 视频播放控制

转载地址:http://blog.sina.com.cn/s/blog_68ed8b21010166ho.html

  •      double cvGetCaptureProperty( CvCapture* capture, int 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

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

设置 摄像头/视频 属性的函数

  •       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 

创建滚动条

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

  •    参数:
  •    trackbar_name  被创建的trackbar名字。
  •    window_name  窗口名字,这个窗口将为被创建 trackbar的父对象。
  •    value 整数指针,它的值将反映滑块的位置。这个变量指定创建时的滑块位置。
  •    count 滑块位置的最大值。最小值一直是 0
  •    on_change 每次滑块位置被改变的时候,被调用函数的指针。这个函数应该被声明为 void Foo(int); 如果没有回调函数,这个值可以设为 NULL
  •   函数 cvCreateTrackbar用指定的名字和范围来创建 trackbar(滑块或者范围控制),指定与 trackbar位置同步的变量,并且指定当 trackbar位置被改变的时候调用的回调函数。
  •   被创建的 trackbar默认显示在指定窗口的顶端,可以通过函数 cvGetTrackbarPos来获取 trackbar显  示的位置信息,以及通过函数 cvSetTrackbarPos来重新设置 trackbar的显示位置。

回调函数

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

 
①创建一个滚动条

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

//记录滚动条的当前位置
int g_slider_pos = 0 ;

//滚动条的回调函数 参数 pos 是指当前滚动条所在位置
void on_changed(int pos)
{
                printf( "g_slider_pos is %d \n",g_slider_pos);
}

int main(int argc,char* argv[])
{
                cvNamedWindow( "show");

                 //在窗口show上创建名字为Position的滚动条
                cvCreateTrackbar( "Position","show" ,&g_slider_pos,400,on_changed);
                 //显示滚动条
                cvShowImage( "show",NULL);
                 //等待用户按键
                cvWaitKey(0);
                
                 return 0;
}
 
 
② 视频播放控制

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

//声明一个CvCapture类型指针 用于接收cvCreateFileCapture的返回值
CvCapture* g_capture = NULL;
//记录滚动条的当前位置
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( "show");
      //打开有一个视频文件
                g_capture=cvCreateFileCapture( "D:\\sample.avi");
      //获取视频的总帧数
                 int frames=(int )cvGetCaptureProperty(g_capture,CV_CAP_PROP_FRAME_COUNT);
   
                 if(frames>0)
                {
            //在窗口show上创建名字为Position的滚动条
                                cvCreateTrackbar( "Position","show" ,&g_slider_pos,frames,on_changed);
                }   
     
      //图像指针变量
                IplImage* frame;

                 while(1)
                {
            //从g_capture获取一帧图像 填充到相应的内存缓冲区
                                frame=cvQueryFrame(g_capture);
            //如果到视频结尾 则退出循环
                                 if(!frame) break ;
            //显示图像
                                cvShowImage( "show",frame);
            //接收用户按键
                                char c = cvWaitKey(33);
            //如果接收到 按键'Esc' 则退出循环
                                 if(c==27)
                                                 break;
            //滚动条 随着视频的播放 进行移动
                                cvSetTrackbarPos( "Position","show" ,frame_count);
                                frame_count++;
                }
      //释放资源
                cvReleaseCapture(&g_capture);
                cvDestroyWindow( "show");
               
    return 0;
}

对于第二个程序,我使用了两个视频都是avi的,不过一个容量只有几十兆,一个1.2G,这个大的视频不知道为什么不能拖动滚动条。原因可能是:
1,帧数太大,滚动条无法分辨;
2,这个avi是经过别的格式转过来的,读取的帧数不对,针对这点我在调用int frames=(int )cvGetCaptureProperty(g_capture,CV_CAP_PROP_FRAME_COUNT);之前调用   cvQueryFrame(g_capture);还是没能解决问题;

另外一个问题是拖动条默认是位于窗口顶部,能否让他显示在底部或其他位置,这要修改cvCreateTrackbar的源代码吗?
还望各位大侠给我拨开乌云。

 

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