当前位置: 首页 > news >正文

使用OpenCV的VideoCapture播放视频文件示例

OpenCV计算机视觉开发实践:基于Qt C++ - 商品搜索 - 京东

构造VideoCapture对象

类VideoCapture既支持从视频文件(.avi 、*.mp4、.mpg等格式)读取,也支持直接从摄像机(比如计算机自带的摄像头)中读取。要想获取视频,需要先创建一个VideoCapture对象。VideoCapture对象的创建方式有以下3种:

(1)从视频文件中读取视频。如果是从文件(.mpg或.avi格式)中读取视频,则在定义对象的时候,可以把视频文件的路径作为参数传给构造函数。对象创建以后,OpenCV将会打开该视频文件并做好准备读取它,并且VideoCapture提供了成员函数isOpened来判断文件是否打开成功,如果成功将返回true(建议在打开视频或摄像头时都使用该成员函数判断是否打开成功)。用于读取视频文件的构造函数如下:

VideoCapture (const String &filename, int apiPreference=CAP_ANY);

其中参数filename是视频文件的文件名(可以包含路径),如果不包含路径,则在当前路径下打开文件; apiPreference表示首选使用的后端捕获API,默认是使用任意捕获API,用宏CAP_ANY来表示。比如我们定义一个VideoCapture对象并打开D盘上的test.avi文件:

cv::VideoCapture capture("D:/test.avi");  // 从视频文件读取

(2)从摄像机中读取视频。如果是从摄像机中读取视频,这种情况下,构造函数会给出一个整型索引参数,用于表示想要访问的摄像机。对于摄像机而言,这个索引参数就是一个标志数字,如果只有1个摄像机,那么索引参数就是0;如果系统中有多个摄像机,那么只要将其值向上增加即可。读取摄像头中的视频的构造函数如下:

VideoCapture (int index, int apiPreference=CAP_ANY);

其中参数index表示要打开的视频捕获设备(摄像头)的ID,如果使用默认后端的默认摄像头,只需传递0;apiPreference表示首选使用的后端捕获API,默认是使用任意捕获API,用宏CAP_ANY来表示,多数情况下,由于我们只有一个摄像机,因此没必要指定摄像机的域,此时使用cv::CAP_ANY是一种高效的方式。参数apiPreference表示摄像机的类型,这个域值可以是下面任意一个预定义常量:

CAP_ANY:自动选择APICAP_DSHOW:通过视频输入,例如,摄像头输入CAP_FFMPEG:使用FFMPEG库CAP_IMAGES:打开一个图像序列(例如,img_%02d.jpg)

(3)不带参数构造一个VideoCapture对象。使用类VideoCapture的不带参数的构造函数来创建一个VideoCapture对象,然后用成员函数open打开一个视频文件或摄像头。open函数声明如下:

virtual bool open (const String &filename, int apiPreference=CAP_ANY);virtual bool open (int index, int apiPreference=CAP_ANY);

两个open函数的参数和前面两个构造函数的参数含义一样,这里不再赘述。

判断视频是否打开成功

当我们打开一个视频文件或摄像头视频后,可以用成员函数isOpened来判断是否打开成功。该函数声明如下:

virtual bool isOpened() const;

若打开成功,则返回true,否则返回false。

比如:

VideoCapture capture;capture.open(0, CAP_DSHOW);    // 打开摄像头if (!capture.isOpened())    // 判断打开是否成功puts("open failed");

12.5  读取视频帧

要播放视频,肯定要把每一帧视频图像都读出来,然后显示出来。读取方式有两种,一种是用运算符>>,直接输出视频帧到Mat对象中。>>是一个重载运算符,定义如下:

virtual VideoCapture& operator >> (CV_OUT Mat& image);

例如:

Mat frame;VideoCapture capture("test.mp4");while (1) {capture >> frame;           // 输出一帧到Mat对象中if (frame.empty()) {       // 播放完就退出printf("播放完成\n");break;}imshow("读取视频", frame);   // 显示帧waitKey(20);}

当输出完一帧后,下次就会输出下一帧。

另外一种方式是通过成员函数read,该函数声明如下:

virtual bool read(OutputArray image);

参数image用来存放读取到的当前视频帧。若读取成功,则返回true,否则返回false。例如:

Mat frame;VideoCapture capture(0, CAP_DSHOW);while (capture.read(frame)){imshow("video-demo", frame);char c = waitKey(66);if (c == 27)  break;}

播放视频文件

播放视频文件的基本步骤就是先构造VideoCapture对象,再打开视频文件,接着用一个循环逐帧读取并显示读取到的视频帧,然后间隔一段时间读取下一个视频帧并显示,依次循环,直到全部视频帧读取完毕。

【例12.1】播放MP4视频文件

   新建一个控制台工程,工程名是conplay。

   打开main.cpp,并输入如下代码:

#include <opencv2/opencv.hpp>
using namespace cv;
#include <QDebug>void play(const char *filename)
{Mat frame;int i=0;VideoCapture capture(filename);if (!capture.isOpened()){printf("open %s failed",filename);return;}// 获取整个视频帧数long  totalFrameNumber = capture.get(CAP_PROP_FRAME_COUNT);qDebug()<<"整个视频帧数:"<<totalFrameNumber;while (i<totalFrameNumber) {capture >> frame;if (frame.empty()) break; 	// 播放结束就跳出循环imshow("read video", frame);	// 显示帧waitKey(1);i++;}qDebug()<<"播放完成\n";
}
int main() {play("/root/hd.mp4");
}

在上述代码中,我们首先定义了一个VideoCapture对象capture,并传入视频文件的文件名;然后利用成员函数get获取视频的帧数,这样在后面的while循环中可以控制播放的帧数。当frame为空时,说明视频帧没有了,也就是播放完毕了,此时跳出循环。每一帧其实就是一幅图片,可以用imshow函数把图片显示出来。当显示速度很快时,多个图片连续显示,看起来就是视频了。这里我们设置每个帧的显示间隔时间是1毫秒。

   保存工程并运行,结果如图12-2所示。

图12-2

播放摄像头视频的主要流程与之类似,只不过在调用open的时候,需要修改一下传入的整型数据。读者可以准备一个USB接口的计算机摄像头,然后把USB口插入计算机的USB插槽中,通常是不需要安装驱动程序的。

相关文章:

  • mysql集成Qwen大模型MCP计算【附实战代码】
  • 安装并运行第一个Spark程序
  • 【工具变量】最新华证ESG评级得分数据-含xlsx及dta格式(2009-2024.12)
  • 认识tomcat(了解)
  • 怎样避免住宅IP被平台识别
  • Search After+PIT 解决ES深度分页问题
  • GoFly企业版框架升级2.6.6版本说明(框架在2025-05-06发布了)
  • 不同大模型对提示词和问题的符号标识
  • 深入解析华为交换机中的VRRP原理
  • Linux 安装交叉编译器后丢失 `<asm/errno.h>` 的问题及解决方案
  • .idea和__pycache__文件夹分别是什么意思
  • Spark-Core(双Value类型)
  • 边缘计算,运维架构从传统的集中式向分布式转变
  • 亿级流量系统架构设计与实战(五)
  • Python 识别图片上标点位置
  • NVM完全指南:安装、配置与最佳实践
  • stm32常见错误
  • 网站网页经常 400 错误,清缓存后就好了的原因剖析
  • Python赋能自动驾驶:如何优化路径规划,让AI驾驶更聪明?
  • AI驱动的Kubernetes管理:kubectl-ai 如何简化你的云原生运维
  • 成就彼此,照亮世界:“中欧建交50周年论坛”在沪成功举行
  • 外交部发言人就印巴局势升级答记者问
  • 兵韬志略|美2026国防预算未达1万亿,但仍寻求“暗度陈仓”
  • 中非民间对话在赞比亚举行
  • 国家发改委:目前有的核电项目民间资本参股比例已经达到20%
  • 多地跟进官宣下调公积金贷款利率,最低降至2.1%