OpenCV3 视频读写 cv::VideoCapture和cv::VideoWriter详解

OpenCV3和OpenCV2类似,视频的读、写操作,分别通过cv::VideoCapture和cv::VideoWriter两个类来实现。

1、视频的读取操作cv::VideoCapture

cv::VideoCapture既支持视频文件的读取,也支持从摄像机中视频的读取。cv::VideoCapture对象的创建方式有以下三种:

1     cv::VideoCapture capture(
2     const string& filename, // 输入文件名
3     );
4     cv::VideoCapture capture(
5     int device // 视频捕捉设备 id
6     );
7     cv::VideoCapture capture();

第一种方式是从文件(.MPG或.AVI格式)中读取视频,对象创建以后,OpenCV将会打开文件并做好准备读取它,如果打开成功,我们将可以开始读取视频的帧,并且cv::VideoCapture的成员函数isOpened()将会返回true(建议在打开视频或摄像头时都使用该成员函数判断是否打开成功)。
第二种方式是从摄像机中读取视频,这种情况下,我们会给出一个标识符,用于表示我们想要访问的摄像机,及其与操作系统的握手方式。对于摄像机而言,这个标志符就是一个标志数字——如果只有1个摄像机,那么就是0,如果系统中有多个摄像机,那么只要将其向上增加即可。标识符另外一部分是摄像机域(camera domain),用于表示摄像机的类型,这个域值可以是下面任一预定义常量。

以这种方式创建视频捕获对象时,我们所传递的标识符是域索引和摄像机索引的和。例如:

cv::VideoCapture capture(cv::CAP_IEEE1394 + 1);

这个例子中cv::VideoCapture将尝试打开第2个(编号从0开始)1394摄像机。多数情况下,由于我们只有一个摄像机,因此没必要指定摄像机的域,此时使用cv::CAP_ANY是一种高效的方式(也即是0,所以不用特意指定)。
第三种方式仅仅创建一个捕获对象,而不提供任何关于打开的信息。创建以后通过成员函数open()来设定打开的信息。open()操作也有以上两种方式。

1     cv::VideoCapture cap;
2     cap.open( "my_video.avi" );

将视频帧读取到cv::Mat矩阵中,有两种方式:一种是read()操作;另一种是 “>>”操作。

1     cv::Mat frame;
2     cap.read(frame); //读取方式一
3     cap >> frame; //读取方式二

下面是读取视频并显示的示例代码:

 1 #include <opencv2/opencv.hpp>
 2 #include <iostream>
 3  
 4 void video_capture_test()
 5 {
 6     cv::VideoCapture capture("test.mp4");
 7  
 8     if (!capture.isOpened())
 9     {
10         std::cout << "Read video Failed !" << std::endl;
11         return;
12     }
13  
14     cv::Mat frame;
15     cv::namedWindow("video test");
16  
17     int frame_num = capture.get(cv::CAP_PROP_FRAME_COUNT);
18     std::cout << "total frame number is: " << frame_num << std::endl;
19  
20     for (int i = 0; i < frame_num - 1; ++i)
21     {
22         capture >> frame;
23         //capture.read(frame); 第二种方式
24         imshow("video test", frame);
25         if (cv::waitKey(30) == 'q')
26         {
27             break;
28         }
29     }
30  
31     cv::destroyWindow("video test");
32     capture.release();
33     return;
34 }

上面的代码,我们使用了cv::VideoCapture的成员函数get()并设定标识cv::CAP_PROP_FRAME_COUNT获取了读取视频的帧总数。同样,我们可以指定其他标识,来获取读取视频或摄像头的其他属性。另外,我们也可以使用成员函数set(),设定相应属性的值。cv::VideoCapture中提供的属性标识如下图所示。

2、视频的写操作cv::VideoWriter

cv::VideoWriter对象的创建有两种方式,第一种是使用构造函数的形式,第二种使用open()的方式,具体如下:

 1     cv::VideoWriter out(
 2         const string& filename, // 输入文件名
 3         int fourcc, // 编码形式,使用 CV_FOURCC()宏
 4         double fps, // 输出视频帧率
 5         cv::Size frame_size, // 单帧图片的大小
 6         bool is_color = true // 如果是false,可传入灰度图像 
 7     );
 8     
 9     cv::VideoWriter out;
10     out.open(
11         "my_video.mpg", //输出文件名
12         CV_FOURCC('D','I','V','X'), // MPEG-4 编码
13         30.0, // 帧率 (FPS)
14         cv::Size( 640, 480 ), // 单帧图片分辨率为 640x480
15         true // 只输入彩色图
16     );

同样,向创建后的cv::VideoWriter对象写入图像也有两种方式,即write()操作和“<<”操作:

1     cv::VideoWriter::write(
2         const Mat& image // 写入图像作为下一帧
3     );
4     
5     my_video_writer << my_frame;
原文地址:https://www.cnblogs.com/ybqjymy/p/14633250.html