"眼睛成长记"(三)—火眼金睛
- 2020 年 4 月 10 日
- 筆記
read方法(读帧解码转换一起做)
(1)方法原型: CV_WRAP virtual bool read(OutputArray image);
(2)说明:
参数: 输出图像的存放结构
说明: VideoCapture类的read方法进行了读取帧,解码帧并进行颜色空间转换的过程。


02
grab和retrieve方法(读帧解码和转换分开做)
(1)原型:
CV_WRAP virtual bool grab();
CV_WRAP virtual bool retrieve(OutputArray image, int flag = 0);
(2)说明:
grab接口实现了对代开的视频进行读取帧和解码的操作;
retrieve接口实现了对解码后的数据进行颜色空间转换的操作;
grab接口不需要传递参数;
retrieve接口的第一个参数image与read函数参数的意义相同,第二个参数flag用来指定帧索引或者驱动指定的标志。


03
为什么会有两种方式
在实际的视频项目当中,我们可能存在这样的需求,需要对读取的所有视频帧进行解码,但是显示的时候并不需要全部显示,也就是说颜色空间转换的部分有些情况下我们可以选择不做,因为这个过程本身也是相当耗费资源的一个过程。

代码演示
#include <opencv2/core.hpp> #include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; int main(int argc, char *argv[]) { VideoCapture video; video.open("test.avi"); //video.open(0); if (!video.isOpened()) { cout << "open video failed!" << endl; getchar(); return -1; } cout << "open video success" << endl; namedWindow("video"); Mat frame; for (;;) { if (!video.read(frame)){ break; } //读帧解码 //if (!video.grab()) { // break; //} ////颜色空间转换 //if (!video.retrieve(frame)) { // break; //} if (frame.empty()) break; imshow("video", frame); waitKey(30); } return 0; }

代码说明
(1)例子中打开一个测试视频,使用的是read的方式,读取后将读出的内容存放到一个Mat类中;
(2)使用waitKey函数类实现界面的刷新,并通过设置参数为30来实现简单的播放控制,一帧播放时间为30 ms;
(3)打开摄像头的代码以及分开使用grab和retrieve的代码均在示例中已被注释,感兴趣的童鞋可以打开尝试一下。