"眼睛成长记"(三)—火眼金睛

  • 2020 年 4 月 10 日
  • 筆記

01

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的代码均在示例中已被注释,感兴趣的童鞋可以打开尝试一下。