博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
opencv学习笔记(二)——播放AVI视频(上)
阅读量:2255 次
发布时间:2019-05-09

本文共 2262 字,大约阅读时间需要 7 分钟。

使用opencv播放视频,几乎与使用它来显示图像一样容易。我们知道视频是由一些列图像构成的。我们用一个专业点儿的词汇来称呼这些构成视频的图像:“帧”(frame)。此外在视频文件里还有个参数叫做“帧率”(frame rate)的,用来表示两帧之间的间隔时间,帧率的单位是(帧/秒)。这个参数只和视频的播放速度有关,对于单独的一帧图像来说没有任何用途。

下面我直接上代码,通过代码分析问题。

#include
#include
using namespace std;using namespace cv;int main(void){ //打开视频文件 VideoCapture capture("海贼王.avi"); //isOpen判断视频是否打开成功 if(!capture.isOpened()) { cout<<"Movie open Error"<

运行结果如下:

这里写图片描述
这里写图片描述

看了结果,很有意思的吧,那我们就对代码刨根问底吧。

NO.1我是焦点一 || 打开和读取视频流 VideoCapture

视频捕获需要的所有函数都集成在 VideoCapture C++ 类里面。虽然它底层依赖另一个FFmpeg开源库,但是它已经被集成在OpenCV里。既然VideoCapture是一个类,那么我们在使用时候需要先定义一个 VideoCapture 类的对象来打开和读取视频流。有两种方法,一种是如我的代码所示的,另一种可通过 open 函数来完成。如下所示:

VideoCapture capture;capture.open("海贼王.avi");

在代码中我们可以点击右键选择查看VideoCapture的定义,他的构造函数中如果使用整型数当参数的话,就可以将这个对象绑定到一个摄像机,将系统指派的ID号当作参数传入即可。例如你可以传入0来打开第一个摄像机,传入1打开第二个摄像机,以此类推。如果使用字符串当参数,就会打开一个由这个字符串(文件名)指定的视频文件。例如在上面的例子里传入如下参数:“海贼王.avi”,因为我是用的是相对路径,该视频文件就在我的工程目录下。

NO.2我是焦点二 || 是否成功打开视频isopen(),视频关闭release以及视频解码read()

isopen()的函数原型如下:

bool VideoCapture::isOpened()

isOpened 函数来检查视频是否成功打开与否,知道这个函数就行。

当析构函数调用时,会自动关闭视频。如果你希望提前关闭的话,你可以调用 release 函数,例如capture.release()即可. 视频的每一帧都是一幅普通的图像。因为我们仅仅需要从 VideoCapture 对象里释放出每一帧图像并保存成 Mat 格式。因为视频流是连续的,所以你需要在每次调用 read 函数后及时保存图像或者直接使用重载的>>操作符。
视频解码函数使用read(),因为每一帧都是一张图片,所直接用Mat保存。read函数原型如下:

bool VideoCapture::read(Mat& image)

读取视频帧的时候也会自动进行解码操作,其实这个方法包含了VideoCapture::grab() 和VideoCapture::retrieve()两个操作,read()方法很方便,当获取不到视频帧的时候,就返回false。

NO.3我是焦点三 || 获取视频属性get和设置属性set

get函数是返回特定的视频属性。其原型如下:

double VideoCapture::get(int propId)

get 函数返回一个double(8个字节)类型的数据来表示这些属性。然后你可以使用位操作符来操作这个返回值从而得到想要的整型数据等。这个函数有一个参数propId,代表着试图查询的属性ID。参数的值可以有很多种,在我的代码里面我只用到了两种,他们分别是:CV_CAP_PROP_FPS以及CV_CAP_PROP_FRAME_COUNT,他们分别表示要返回的值为帧速率和视频文件的总帧数。还有其他的数值可以查看highgui_c.h。

当你需要设置这些值的时候你可以调用 set 函数。其原型如下:

bool VideoCapture::set(int propId, double value)

函数的第一个参数是需要设置的属性ID,第二个参数是需要设定的值,如果返回true的话就表示成功设定,否则就是false。在我的代码中我用set设置了视频播放的位置。这个只是个举例而已,其实不用设置也可以,opencv会默认从开始0位置开始执行。当然关于set的函数参数的多种用法,我也不多多举例了,有兴趣的自己可以去highgui_c.h中查看。

再看下面两句代码:

char c=waitKey(33);    if(c==27)        break;

这是当帧被显示后,系统会等待33秒,如果用户这时候触发了一个按键,c就会被设置成这个按键的ASCII码,否则c会被设置成-1;如果触发了ESC键(ASCII=27),循环被退出。读入视频被停止,否则33秒后继续执行。

这个整个解说就到此结束,如有问题可以私下找我讨论,这是一个比较简单的视频播放程序,因为没有对视频帧进行任何的控制。后面我们会对程序多加一些人性化的功能,大家拭目以待吧。

你可能感兴趣的文章
代号Europa----我所感兴趣的Eclipse3.3新特性
查看>>
Eclipse常用快捷键(转帖)
查看>>
Swing程序中关于监听器代码的简化
查看>>
验证日期的正确性
查看>>
常见Swing事件处理方法
查看>>
给一个窗体增加快捷键
查看>>
婚前婚后经典对白
查看>>
JAVA事件处理机制小议
查看>>
史上最牛叉的程序员招聘信息
查看>>
JAVA中的字符与代码点
查看>>
JFormattedTextField使用心得
查看>>
1~N中求出1的个数
查看>>
Java实用经验总结--Swing篇
查看>>
Java实用经验总结--日期、数字篇
查看>>
JList用法小结
查看>>
在n张扑克牌中找出顺子
查看>>
将一个单向链表反向链接
查看>>
重载与桥接函数
查看>>
Java范型浅析
查看>>
String.format函数使用方法介绍
查看>>