您的位置:首页 > 运维架构

【OpenCV_04】从文件以及摄像头读取视频

2016-05-25 15:48 666 查看



通过文件或者摄像头读取视频文件

通过文件读取视频

在这节,握住想主要介绍一下如何通过文件读取视频,其实很简单的,只需要和读取图片一样类似的过程,通过对视频frame by frame的读取。下面就是读取的视频文件的OpenCV代码

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "opencv2/highgui/highgui.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{
VideoCapture cap("C:/Video.avi"); // 打开视频文件

if ( !cap.isOpened() )  // if not success, exit program
{
cout << "Cannot open the video file" << endl;
return -1;
}

//cap.set(CV_CAP_PROP_POS_MSEC, 300); //start the video at 300ms

double fps = cap.get(CV_CAP_PROP_FPS); //get the frames per seconds of the video

cout << "Frame per seconds : " << fps << endl;

namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"

while(1)
{
Mat frame;

bool bSuccess = cap.read(frame); // read a new frame from video

if (!bSuccess) //if not success, break loop
{
cout << "Cannot read the frame from video file" << endl;
break;
}

imshow("MyVideo", frame); //show the frame in "MyVideo" window

if(waitKey(30) == 27) //wait for 'esc' key press for 30 ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}

return 0;

}
////////////////////////////////////////////////////////////////////////////////////////////////////////////


下面是demo

OpenCV 函数详解

VideoCapture::[b]VideoCapture(const string& filename)[/b]

VideoCapture类其中的一个构造函数,这个构造函数是用来打开从特定文件视频流来视频文件以及初始化 VideoCapture对象。

bool VideoCapture::IsOpened()
如果上面的VideoCapture构造函数成功的打开视频文件,返回true,否则就返回false. 这个函数从根本上检测VideoCapture初始化成功与否。如果失败,程序退出。如果继续通过VideoCapture对象读入视频帧,程序将崩溃。

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

通过这个函数可以改变VideoCapture对象的部分特性,如果成功,返回值为true.否则返回false。在我的代码里,通过调用CV_CAP_PROP_POS_MSEC改变了视频播放初始位置。

参数设置 :
int propID - 该参数指定要更改的属性。很多选择。在这里列出。
CV_CAP_PROP_POS_MSEC - 视频当前位置(以毫秒记 ms)
CV_CAP_PROP_POS_FRAMES - 视频当前位置(以帧记 frames)
CV_CAP_PROP_FRAME_WIDTH - 视频流帧宽度
CV_CAP_PROP_FRAME_HEIGHT - 视频流帧高度
CV_CAP_PROP_FPS - 帧率 (帧每秒)
CV_CAP_PROP_FOURCC - four character code  of codec 四字解码器?

double value - 对欲改变的属性新设定的值 propID

doubleVideoCapture::get(int propId)

这个函数的返回值是propId定义的.在代码中通过视频流获得相对应的属性值。在我的代码里, 通过[b]CV_CAP_PROP_FPS 输出了帧率。 [/b]

bool VideoCapture::read(Mat& image);
这个函数是从视频中抓取下一帧,并对其进行解码存储在'image'的变量里。函数内部,VideoCapture::grap() 以及 VideoCapture::retrieve() 被调用。如果运行成功返回true,否则返回false。

waitKey([b]30)[/b]
这个函数是等待30ms。如果在30ms内按键,将返回对应键盘键的ASCII值。如果值是27, (ASCII 'esc' 值是 27),如果,在30ms内没有键盘响应,函数将返回-1.

VideoCapture::~[b]VideoCapture()[/b]
VideoCapture对象的析构函数

总结

首先,这个程序主要是从文件读取视频,然后程序进入无限循环,那么程序进入到一个无限循环。在该循环中,程序从所读取的视频文件中加载帧,对其进行解码,通过一个窗口显示,并等待30毫秒。如果视频文件没有更多的帧,或者如果用户按下“ESC”键,打破无限循环退出程序。

注意:
采用waitKey(int) 非常重要,因为 imshow(string&, MAT)函数需要时间在窗口里绘图,通过waitKey(int)来给必要的时间。

通过摄像头获取视频

首先电脑上,需要接入一个普通摄像头,点开QQ视频测试一下是否可以正常工作,这个和之前的功能上的主要区别是VideoCapture的构造函数的参数,这里需要吧摄像头的序号赋予VideoCapture的对象,代替上面例子程序的中文件名。 下面是OpenCV的代码

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "opencv2/highgui/highgui.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{
VideoCapture cap(0); // open the video camera no. 0

if (!cap.isOpened())  // if not success, exit program
{
cout << "Cannot open the video cam" << endl;
return -1;
}

double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video

cout << "Frame size : " << dWidth << " x " << dHeight << endl;

namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"

while (1)
{
Mat frame;

bool bSuccess = cap.read(frame); // read a new frame from video

if (!bSuccess) //if not success, break loop
{
cout << "Cannot read a frame from video stream" << endl;
break;
}

imshow("MyVideo", frame); //show the frame in "MyVideo" window

if (waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;

}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////


下面视频是我自己通过摄像头捕获的视频

OpenCV 函数详解
[b]VideoCapture::VideoCapture(int device)[/b]

这个构造函数通过指定的摄像头(摄像头可能不止一个,所以要通过index指定)打开摄像头来初始化VideoCapture对象来读取视频流。 这里的 '0' 代表当前使用的摄像头,也可以使用 1,2,3.. 如果你的计算机接入不只一个摄像头。

if (!cap.isOpened())
如果 VideoCapture对象初始化失败与否进行check

double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH)
这个函数是获得摄像头输出结果帧的宽度(in pixels)

 double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT)

这个函数是获得摄像头输出结果帧的高度(in pixels)

其他的函数与上面一部分的函数一致
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: