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

本文介绍了如何使用OpenCV库通过文件和摄像头读取视频文件,包括视频文件的打开、帧率获取、帧读取及显示过程,并提供了代码示例。同时,解释了如何通过摄像头获取实时视频流。


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

通过文件读取视频

在这节,握住想主要介绍一下如何通过文件读取视频,其实很简单的,只需要和读取图片一样类似的过程,通过对视频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::VideoCapture(const string& filename)
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定义的.在代码中通过视频流获得相对应的属性值。在我的代码里, 通过CV_CAP_PROP_FPS 输出了帧率。 


  • bool VideoCapture::read(Mat& image);
这个函数是从视频中抓取下一帧,并对其进行解码存储在' image'的变量里。函数内部,VideoCapture::grap() 以及 VideoCapture::retrieve() 被调用。如果运行成功返回true,否则返回false。
  • waitKey(30)
这个函数是等待30ms。如果在30ms内按键,将返回对应键盘键的ASCII值。如果值是27, (ASCII 'esc' 值是 27),如果,在30ms内没有键盘响应,函数将返回-1.

  • VideoCapture::~VideoCapture()
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 函数详解
  • VideoCapture::VideoCapture(int device)
这个构造函数通过指定的摄像头(摄像头可能不止一个,所以要通过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)


其他的函数与上面一部分的函数一致
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值