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循环里不断累加当前播放帧变量,当当前播放帧大于总的帧数时,表示视频已经播放到结尾,退出播放。

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340