3、OpenCV播放视频、保存、暂停视频,打开摄像头

您所在的位置:网站首页 黄鼠狼怎么捕捉的视频播放 3、OpenCV播放视频、保存、暂停视频,打开摄像头

3、OpenCV播放视频、保存、暂停视频,打开摄像头

2024-06-11 16:42| 来源: 网络整理| 查看: 265

OpenCV播放视频、保存、暂停视频,打开摄像头 一、加载视频或摄像头二、获取视频帧或摄像头的帧三、循环逻辑控制视频显示四、暂停视频播放和中断视频播放五、视频保存六、完整代码示例七、致谢

一、加载视频或摄像头

1、原理理解 所谓的视频播放,无非就是将一堆有序的图片序列,按照顺序,以一定的间隔显示出来。这个间隔的多少与我们所听到的帧率相关。有了这个意识后,我们其实按照自己的思想都可以实现视频的播放:视频文件是由一帧帧具有先后顺序的图片组成,我们只需要将视频的每一帧按照原有的顺序显示出来即可。为此OpenCV提供了专用的对象和API以供加载视频并按顺序提取视频的每一帧。

2、视频管理类 cv::VideoCapture加载视频或摄像头 Opencv提供了用于获取视频文件的类 cv::VideoCapture,这个类提供了c++ API,用于从摄像机捕捉视频,或者读取视频文件和图像序列。实例化该类的对象后,便可以通过该类提供的方法获取视频帧和获得视频文件的相关信息。

通常使用如下两种方法构造 cv::VideoCapture对象。 方法一:先声明 cv::VideoCapture的对象,再调用该对象的open方法打开指定的视频文件

VideoCapture vc1; vc1.open("O:\\image\\1.mp4");

注意:cv::VideoCapture对象的open方法的函数原型为:

virtual bool cv::VideoCapture::open (const String & filename, int apiPreference = CAP_ANY)

open方法的第一个参数指定视频文件,第二个参数可忽略。open方法的另一个常用的重载为:

virtual bool cv::VideoCapture::open (int index, int apiPreference = CAP_ANY)

此时,第一个参数用于绑定使用摄像头的编号,从0开始计数。

方法二:声明 cv::VideoCapture对象的时候,调用有参构造函数直接绑定视频文件

VideoCapture vc1("O:\\image\\1.mp4");

该构造函数的原型为:

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

其中,第一个参数指定视频文件,第二个参数可忽略。其对应的打开摄像头的重载为:

cv::VideoCapture::VideoCapture (int index, int apiPreference = CAP_ANY)

此时,第一个参数还是指定摄像头编号,从0开始计数。

二、获取视频帧或摄像头的帧

1、在获取视频帧之前,通常我们需要判断一下视频或者摄像头有无打开(初始化):

if (!vc1.isOpened()) { fprintf(stderr, "failed to open %s\n", "O:\\image\\1.mp4"); return EXIT_FAILURE; }

如果视频或者摄像头初始化成功,该方法会返回 true。

2、获取视频帧或者摄像头的帧内容有两种方式 方法一:

Mat frame; vc1.read(frame);

该函数将VideoCapture::grab() 和 VideoCapture::retrieve() 组合在一个调用中。这是最方便的读取视频文件或捕获数据解码和返回方法。如果没有捕获帧(相机已断开连接,或没有更多帧),方法返回false,函数返回空图像。

方法二:

Mat frame; vc1 >> frame;

这主要是基于cv::VideoCapture类重载了 >> 操作符。

三、循环逻辑控制视频显示

结合原理理解,现在已经有方法获取视频的每一帧内容了,接下来要做的就是写好循环逻辑来逐帧显示图像即可。

Mat frame; vc1 >> frame; while (!frame.empty()) { imshow("demo", frame); vc1 >> frame; waitKey(30); } destroyAllWindows(); 四、暂停视频播放和中断视频播放

前面已经实现了视频的连续播放,接下来要做的就是实现按下空格键(space,其ASCII值为32)时视频暂停播放,再次按下的时候继续播放。按下退出键(ESC,ASCII值为27)时中断视频播放。这儿会使用到一点简单的编程技巧,直接看代码:

Mat frame; vc1 >> frame; while (!frame.empty()) { imshow("demo", frame); vc1 >> frame; int k = waitKey(30); if (k == 27) break; else if (k == 32) { while (waitKey(0) != 32) waitKey(0); } } destroyAllWindows();

在每隔30ms显示一帧图像后会等待用户按键,如果在30ms内用户没按键,则waitKey(30) 的返回值为-1,程序继续显示下一帧,循环继续。如果用户按下了ESC键,则直接break退出循环,视频播放结束,如果按下空格后,则程序会一直等待用户再次按下空格后才继续。

五、视频保存

Opencv实现视频的保存需要定义编解码器并创建cv::VideoWriter对象。 1、实例化视频写对象cv::VideoWriter

VideoWriter writer;

cv::VideoWriter类有很多个重载的构造方法,可以在声明对象的同时定义编解码器,也可以在后面调用该对象的fourcc 方法指定编解码器。

int code = writer.fourcc('M', 'J', 'P', 'G'); writer.open("O:\\image\\result.avi", code, 40, Size(1280, 720), true);

声明对象的同时绑定文件和编解码器,其函数原型为:

CV_WRAP VideoWriter(const String& filename, int fourcc, double fps, Size frameSize, bool isColor = true); 参数 filename:指定保存视频的文件名(路径+名称)参数 fourcc:指定编解码器参数 fps:指定保存视频的帧率参数 frameSize:指定保存视频的尺寸,为Size对象参数 isColor:指定保存视频是否为彩色,默认为true

调用实例为:

string fileName = "O:\\image\\result.avi"; VideoWriter writer = VideoWriter(fileName, VideoWriter::fourcc('M', 'J', 'P', 'G'), 30, Size(1280, 720), true);

其它构造函数基本一致,感兴趣的小伙伴自行查阅资料。

2、在视频显示的循环帧中,将每一帧保存即可 调用 cv::VideoWriter对象的write函数:

writer.write(frame);

在写完视频后,记得释放资源:

writer.release(); 六、完整代码示例 #include using namespace std; using namespace cv; int main(int argc, char** argv) { // 初始化视频管理对象,直接指定视频文件的路径 VideoCapture vc1("O:\\image\\1.mp4"); // 判断视频是否初始化成功 if (!vc1.isOpened()) { fprintf(stderr, "failed to open %s\n", "O:\\image\\1.mp4"); return EXIT_FAILURE; } // 声明视频写入对象 string fileName = "O:\\image\\result.avi"; VideoWriter writer = VideoWriter(fileName, VideoWriter::fourcc('M', 'J', 'P', 'G'), 30, Size(1280, 720), true); // 循环处理视频的每一帧,先显示,再写入 Mat frame; vc1 >> frame; while (!frame.empty()) { imshow("demo", frame); // 写入视频帧 writer.write(frame); vc1 >> frame; int k = waitKey(30); // 实现按键暂停和退出视频播放功能 if (k == 27) break; else if (k == 32) { while (waitKey(0) != 32) waitKey(0); } } // 释放资源,清空缓存 destroyAllWindows(); writer.release(); system("pause"); return EXIT_SUCCESS; } 七、致谢

1、常规的谢天谢地谢父母,谢朋友 2、感兴趣的小伙伴欢迎入群一起探讨学习 :725027506。 去群飞机票



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3