OpenCV读写视频文件解析
阅读原文时间:2023年07月09日阅读:2

OpenCV读写视频文件解析

一.视频读写类

视频处理的是运动图像,而不是静止图像。视频资源可以是一个专用摄像机、网络摄像头、视频文件或图像文件序列。


OpenCV 中,VideoCapture 类和 VideoWriter 类为视频处理中所涉及的捕获和记录任务提供了一个易用的
C++API。

cv::VideoCapture

1、对象的构造函数,如下面的例子:

cv::VideoCapture capture("D:\\Camera Road 01.avi");

参数为const string&,即读入彩色图像,若设置为0则读取摄像头。

2、验证视频读入是否成功,如下:

if (!capture.isOpened())

    {

        std::cout << "Vidoe open failed!" << std::endl;

        return -1;

    }

3、验证完成后,就可以开始读取视频啦!

cv::Mat frame;

capture >> frame;

VideoCapture对象的操作可以像流一样读入到Mat类型的对象(即图像)中。

cv::VideoWriter

这个类是用来写入一个视频的,使用起来比capture麻烦一些。

构造函数 cv::VideoCapture(const string& path,int fourcc,double fps, Size framesize, bool isColor=true)

需要注意的是fourcc,cv::VideoWriter::fourcc(char c1,char c2,char c3,char c4)

常用的格式有

  • CV_FOURCC('P','I','M','1') = MPEG-1 codec
  • CV_FOURCC('M','J','P','G') = motion-jpeg codec
  • CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 codec
  • CV_FOURCC('D', 'I', 'V', '3') = MPEG-4.3 codec
  • CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec
  • CV_FOURCC('U', '2', '6', '3') = H263 codec
  • CV_FOURCC('I', '2', '6', '3') = H263I codec
  • CV_FOURCC('F', 'L', 'V', '1') = FLV1 codec

二.视频读写示例

剩下的就与VideoCapture差不多了,不过是输出流的操作。

下方的 recVideo 示例是一个简短的代码片段,可以让你了解如何使用一个默认摄像机作为一个捕捉设备来抓取帧,对它们进行边缘检测,并且将新的转换视频帧作为一个文件保存。而且,创建两个窗口同时显示原始帧和处理过的帧。

recVideo 示例的代码为:

1.  #include

2.  #include

3.  using namespace std;

4.  using namespace cv;

5.   

6.  int main(int, char **)

7.  {

8.      Mat in_frame, out_frame;

9.      const char win1[]="Grabbing…", win2[]="Recording…";

10.    double fps=30;//每秒的帧数

11.    char file_out[]="recorded.avi";

12.  

13.    VideoCapture inVid(O) ; //打开默认摄像机

14.    if ( !inVid.isOpened () ) { //检查错误

15.        cout << "Error! Camera not ready…\n";

16.        return -1;

17.    }

18.    //获取输入视频的宽度和高度

19.    int width = (int)inVid.get(CAP_PROP_FRAME_WIDTH);

20.    int height = (int)inVid.get(CAP_PR〇P_FRAME_HEIGHT);

21.    VideoWriter recVid(file out,VideoWriter::fourcc('M','S','V','C'), fps, Size(width, height));

22.    if (!recVid.isOpened()) {

23.        cout << "Error! Video file not opened…\n";

24.        return -1;

25.    }

26.    //为原始视频和最终视频创建两个窗口

27.    namedWindow(win1);

28.    namedWindow(win2);

29.    while (true) {

30.        //从摄像机读取帧(抓取并解码)

31.        inVid >> in frame;

32.        //将帧转换为灰度

33.        cvtColor(in_frame, out_frame, C0L0R_BGR2GRAY);

34.        //将幀写入视频文件(编码并保存)

35.        recVid << out_frame ?

36.        imshow (win1, in_frame);// 在窗口中显示帧

37.        imshow(win2, out_frame); // 在窗口中显示帧

38.        if (waitKey(1000/fps) >= 0)

39.            break;

40.    }

41.    inVid.release(); // 关闭摄像机

42.    return 0;

43.}

在本示例中,应该快速浏览以下这些函数:

  • double VideoCapture::get(int propId):这个函数为一个 VideoCapture 对象返回指定的属性值。在 videoio.hpp 头文件中包含了基于 DC1394(IEEE 1394 数码相机规范)属性的一个完整列表。

  • static int VideoWriter::fourcc(char c1,char c2,char c3,char c4):这个函数把四个字符连接起来形成一个 fourcc 码。在示例中,MSVC 代表微软视频(仅在 Windows 上可用)。

  • bool VideoWriter::isOpened():如果写入视频的对象被成功初始化,这个函数返回 true。例如,使用一个不正确的编解码器会产生一个错误。

  • VideoCapture&VideoCapture::operator>>(Mat&image):这个函数抓取、解码并返回下一帧。这个方法和布尔函数 VideoCapture::read(OutputArray image)等价。可以使用这个函数而不使用函数 VideoCapture::grab(),然后使用 VideoCapture::retrieve()。

  • VideoWriter&VideoWriter::operator<<(const Mat&image):这个函数写入下一帧。这个方法和布尔函数 VideoWriter::write(const Mat&image)等价。

    在本示例中,有一个读取/写入循环,可同时地获取并处理窗口事件。waitKey(1000/fps)函数调用负责执行这个任务。在这个示例中,1000/fps 表示返回外部循环之前等待的毫秒数。尽管不精确,但对于录制的视频仍能获取每秒帧数的一个近似度量。

  • void VideoCapture::release():这个函数释放视频文件或采集设备。尽管在本示例中没有必要显式地包含,但为了说明它的使用,示例中仍包含了这个函数。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章