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;