Opencv实现视频播放与进度控制

 更新时间:2018年01月22日 16:52:03   作者:-牧野-  
这篇文章主要为大家详细介绍了Opencv实现视频播放与进度控制,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

视频画面本质上是由一帧一帧的连续图像组成的,播放视频其实就是在播放窗口把一系列连续图像按一定的时间间隔一幅幅贴上去实现的。

人眼在连续图像的刷新最少达到每秒24帧的时候,就分辨不出来图像间的闪动了,使人感觉呈现出来的是连续的画面,视频的播放就是利用了这一点。我们知道,电影被称为“24帧的艺术”,意思就是电影画面每秒刷新24帧,即每秒显示24副图像,它的帧率(Frames per Second,简称:FPS)为24。

一般情况下帧率要大于等于24,以下先测试一下两个视频文件的帧率,一个是网络上下载的“”friends“”,一个是用手机拍摄的视频。

#include "core/core.hpp" 
#include "highgui/highgui.hpp" 
#include "imgproc/imgproc.hpp" 
#include <iostream> 
 
using namespace cv; 
 
int main(int argc,char *argv[]) 
{ 
  VideoCapture videoFriends(argv[1]); 
  VideoCapture videoPhone(argv[2]); 
  double fpsFriends=videoFriends.get(CV_CAP_PROP_FPS); 
  double fpsPhone=videoFriends.get(CV_CAP_PROP_FPS); 
  std::cout<<"FPS of Friends is: "<<fpsFriends<<std::endl; 
  std::cout<<"FPS of MyPhone is: "<<fpsPhone<<std::endl; 
  system("pause"); 
  return 0; 
} 

经测试,两个视频文件的帧率都是23.976

播放与进度控制里主要用到 VideoCapture类里的get()函数,和创建控制条的createTrackbar()函数,get()函数用于获取视频的帧数、帧率等信息,了解get函数的参数含义即可,像get(CV_CAP_PROP_FRAME_COUNT)用于获取总帧数,get(CV_CAP_PROP_FPS)用于获取帧率等。

控制条作为Opencv中一个重要的用户和图像传参、交互的工具,伴随了整个opencv图像处理的过程,之前有提到过,这里有必要再说一说createTrackbar()这个函数。

函数原型

int createTrackbar(const string& trackbarname, const string& winname, 
               int* value, int count, 
               TrackbarCallback onChange = 0, 
               void* userdata = 0); 

该函数作用是在指定图像窗口上创建一个控制条,这个控制条具有指定的参数控制范围,可以通过回调函数,执行对应的操作。
第一个参数:const修饰的string类型的引用trackbarname,表示控制条的名称
第二个参数:const修饰的string类型的引用winname,表示控制条所在的图像窗口的名称
第三个参数:int型的指针value,表示滑块的控制位置,拖动控制条滑块的位置,相应的会改变*value的值
第四个参数:int型的count,表示控制条上滑块的最大位置处对应的值
第五个参数:TrackbarCallback类型的onChange,表示一个指向回调函数的指针,每当滑块的位置发生变化,都会触发该回调函数
第六个参数:void型的userdata,一般使用其默认值0

Opencv通过VideoCapture类播放视频与通过createTrackbar创建进度条控制视频播放Code:

#include "core/core.hpp" 
#include "highgui/highgui.hpp" 
#include "imgproc/imgproc.hpp" 
#include <iostream> 
 
using namespace cv; 
 
Mat image;  //读入视频帧的Mat 
char* windowName="Video Control"; //播放窗口名称 
char* trackBarName="播放进度";  //trackbar控制条名称 
double totalFrame=1.0;   //视频总帧数 
double currentFrame=1.0;  //当前播放帧 
int trackbarValue=1;  //trackbar控制量 
int trackbarMax=255;  //trackbar控制条最大值 
double frameRate=1.0; //视频帧率 
VideoCapture video;  //声明视频对象 
double controlRate=0.1; 
 
//控制条回调函数 
void TrackBarFunc(int ,void(*)); 
int main(int argc,char *argv[]) 
{ 
  //打开视频文件 
  video.open(argv[1]); 
  if(!video.isOpened()) 
  { 
    std::cout<<"Failed to open video"<<std::endl; 
  } 
  totalFrame=video.get(CV_CAP_PROP_FRAME_COUNT); //获取总帧数 
  frameRate=video.get(CV_CAP_PROP_FPS);  //获取帧率 
  double pauseTime=1000/frameRate; // 由帧率计算两幅图像间隔时间 
  namedWindow(windowName); 
  //在图像窗口上创建控制条 
  createTrackbar(trackBarName,windowName,&trackbarValue,trackbarMax,TrackBarFunc); 
  TrackBarFunc(0,0); 
  while (true) 
  { 
    video.read(image); 
    resize(image,image,Size(500,400)); //调整图像大小,视频在我的显示器上显示不全 
    imshow(windowName,image); //显示图像 
    waitKey(pauseTime);  //图像间隔 
    controlRate++;   
    if(controlRate>totalFrame) //播放完成退出 
    { 
      break; 
    } 
 
  } 
  video.release(); //释放视频,C++中不写也无碍,可以自动释放 
  waitKey(); 
  return 0; 
} 
void TrackBarFunc(int ,void(*)) 
{ 
  controlRate=(double)trackbarValue/trackbarMax*totalFrame; //trackbar控制条对视频播放进度的控制 
  video.set(CV_CAP_PROP_POS_FRAMES,controlRate);  //设置当前播放帧 
}
 


拖动控制条的滑块,实现播放进度控制:


每次拖动滑块位置发生,就会触发定义的“TrackBarFunc”回调函数,这个函数做了两件事,一是

controlRate=(double)trackbarValue/trackbarMax*totalFrame; 
//trackbar控制条对视频播放进度的控制 

通过滑块的位置确定视频当前应该播放的帧数;二是

video.set(CV_CAP_PROP_POS_FRAMES,controlRate);  //设置当前播放帧 

通过set函数,设置当前播放帧。

在while循环里不断累加当前播放帧变量,当当前播放帧大于总的帧数时,表示视频已经播放到结尾,退出播放。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C与C++中结构体的区别

    C与C++中结构体的区别

    C中的结构体只涉及到数据结构,而不涉及到算法,也就是说在C中数据结构和算法是分离的,而到C++中一类或者一个结构体可以包含函数(这个函数在C++我们通常中称为成员函数),C++中的结构体和类体现了数据结构和算法的结合
    2013-10-10
  • C语言数据结构之双向循环链表的实例

    C语言数据结构之双向循环链表的实例

    这篇文章主要介绍了C语言数据结构之双向循环链表的实例的相关资料,需要的朋友可以参考下
    2017-06-06
  • 《C++ primer plus》读书笔记(三)

    《C++ primer plus》读书笔记(三)

    本文是C++读书笔记系列的第三篇,是读完《C++ primer plus》一书第九、十两章记录下来的笔记,学习C++的同学可以看看参考下。
    2014-10-10
  • 基于C++的拼多多算法在线笔试题示例

    基于C++的拼多多算法在线笔试题示例

    这篇文章主要介绍了基于C++的拼多多算法在线笔试题,列举了四个拼多多的算法笔试题,包括分治法、大数相乘、贪心算法以及迷宫问题,需要的朋友可以参考下
    2017-08-08
  • C语言小游戏之小熊跳板功能的实现

    C语言小游戏之小熊跳板功能的实现

    这篇文章主要介绍了C语言小游戏之小熊跳板功能的实现,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • C语言实现基于最大堆和最小堆的堆排序算法示例

    C语言实现基于最大堆和最小堆的堆排序算法示例

    这篇文章主要介绍了C语言实现基于最大堆和最小堆的堆排序算法示例,分别是基于最大堆的升序排序和基于最小堆的降序排序实例,需要的朋友可以参考下
    2016-06-06
  • C/C++实现快速排序的方法

    C/C++实现快速排序的方法

    这篇文章主要介绍了C/C++实现快速排序的方法,这几天在找工作,被问到快速排序,结果想不出来快速排序怎么弄的;回来搜索了一下,现在记录下来,方便以后查看。
    2014-12-12
  • C语言指针入门学习面面观

    C语言指针入门学习面面观

    这篇文章主要介绍了C语言指针的一些基础知识,指针可以说是C语言入门学习中的头等大事,文中从数组和函数等多方面剖析C中指针的作用,需要的朋友可以参考下
    2016-02-02
  • C语言实现顺序表基本操作汇总

    C语言实现顺序表基本操作汇总

    这篇文章主要介绍了C语言实现顺序表基本操作汇总,对学习数据结构的朋友有一定的借鉴价值,需要的朋友可以参考下
    2014-07-07
  • c++下使用windows api遍历指定文件夹及其子文件夹中的文件

    c++下使用windows api遍历指定文件夹及其子文件夹中的文件

    这篇文章主要介绍了c++下使用windows api遍历指定文件夹及其子文件夹中的文件实现代码,一般都是通过c++自带的函数实现
    2021-07-07

最新评论