# 1. 基础类型与图像视频读取
## 1.  基础类型
### 1. 接口类
OpenCV是一个极其庞大的库,有不可估量的函数数目。受限于类的重载函数数目和种类,内部函数互相调用之间,通常会使用接口类去做隐式类型转换,然后再去进行统一的运算处理这些类通过调用 `InputArray` 来进行隐式转换,方便使用 ,如:
`Mat`  `Mat_<T>`  `Matx<T m n>` `std::vector<T>` `std::vector<std::vector<T>` `std::vector<Mat>` `std::vector<Mat_<T>>` `UMat` `std::vector<UMat>`; 
> :-- 讲解接口类的概念,只是为了大家可以学习OpenCV的编写思想,从而更方便去学好这个库,1.1.1小节内容不要求会编写
| 类型                       | 说明                                                         |
| :------------------------- | :----------------------------------------------------------- |
| `InputArray`               | 只读输入数组传递到 OpenCV 函数的代理类                       |
| `OutputArray`              | 这种类型与 `InputArray` 非常相似,只是它用于输入/输出和输出函数参数 |
| `InputOutputArray`         | 继承了OutputArray,作为输入输出接口,增加了一些功能     |
| `InputArrayOfArrays`       | typedef `InputArray` `InputArrayOfArrays`                    |
| `OutputArrayOfArrays`      | typedef  `OutputArray` `OutputArrayOfArrays`                 |
| `InputOutputArrayOfArrays` | typedef  `OutputArray` `InputOutputArrayOfArrays`            |
> *经验分享*
> Array 是数组的意思,更直观的理解方式是一个排列,是有线性储存方式的数据的集合。
> Input 和 Output 在解读代码时是为了标注输入输出使用,如果查看源码[^source],可发现InputArray是首先编写的基本接口,而OutputArray是对InputArray的继承,增加了一些作为输出类所应有的成员;在此之上,又有InputOutputArray继承了OutputArray,作为输入输出接口,它的功能比前两者更多,也能起到更多的作用。
> 因此我们可以理解了`输入排列:InputArray` `输出排列:OutputArray`  `输入输出排列:InputOutputArray`三个类。
> 之后三者是ArraysOfArrays,是前三者的排列,即排列的排列,定义使用了typedef。
#### 2.  Mat  图像类
   `Mat`本质是一个n维密集运算数组,是Matrix的简写。相似的有`UMat`,表示GPU Mat,`GMat`,表示G-API的Mat接口。
#### 3.  运算类
   OpenCV的运算内核原型类,详情见 `<opencv2/core/matx.hpp>`
   | 类型   | 说明   |
   | ------ | ------ |
   | `Matx` | 定阶矩阵类,即确定规模大小的矩阵类 |
   | `Vec`  | 向量类 |
#### 4.  定义类
   这是OpenCV官方定义的一些常用的类型,详情见`<opencv2/core/types.hpp>`
   | 类型          | 说明       |
   | ------------- | ---------- |
   | `Point`       | 二维点类   |
   | `Point3`      | 三维点类   |
   | `Rect`        | 矩形类     |
   | `RotatedRect` | 旋转矩形类 |
   | `Range`       | 范围类     |
   | `Scalar`      | 通道类     |
   | `Size`        | 规格类     |
## 2.  图像视频IO
   1. 函数
      1. imread
         ```C++
         Mat cv::imread	(	const String &	filename, 
         					int				flags = IMREAD_COLOR
         				)	
         /*
         @brief Loads an image from a file.
         简介 从文件加载图像。
         The function imread loads an image from the specified file and returns it. If the image cannot be read (because of missing file, improper permissions, unsupported or invalid format), the function returns an empty matrix ( Mat::data==NULL ).
         函数imread从指定文件加载图像并返回。如果无法读取图像(由于缺少文件、权限不正确、格式不受支持或无效),函数将返回一个空矩阵(Mat::data==NULL)。
         @param filename Name of file to be loaded.
         @param flags Flag that can take values of cv::ImreadModes
         */
         ```
        2. imwrite
           ```C++
           bool cv::imwrite	(	const String &				filename,
           						InputArray 					img,
           						const std::vector<int>> & 	params = std::vector< int >() 
           					)	
           /*
           @brief Saves an image to a specified file.
           简介 将图像保存到指定文件。
     
           The function imwrite saves the image to the specified file. The image format is chosen based on the filename extension (see cv::imread for the list of extensions). In general, only 8-bit single-channel or 3-channel (with 'BGR' channel order) images can be saved using this function
           imwrite函数将图像保存到指定的文件中。根据文件扩展名选择图像格式(有关扩展名列表,请参阅cv::imread)。通常,使用此功能只能保存8位单通道或3通道(具有“BGR”通道顺序)图像
     
           @param filename Name of the file.
           @param img (Mat or vector of Mat) Image or Images to be saved.
           @param params Format-specific parameters encoded as pairs (paramId_1, paramValue_1, paramId_2, paramValue_2, ... .) see cv::ImwriteFlags
           */
           ```
   2. 类
       1. `VideoCapture`
          ```C++
          // 常用函数
           				VideoCapture (const String &filename, int apiPreference=CAP_ANY) 
           				VideoCapture (int index, int apiPreference=CAP_ANY)
          virtual bool 	open (const String &filename, int apiPreference=CAP_ANY)
          virtual bool 	open (int index, int apiPreference=CAP_ANY)
          virtual bool 	isOpened () const
          virtual double 	get (int propId) const
          virtual bool 	set (int propId, double value)
          virtual void 	read ()
          virtual void 	release ()
          virtual VideoCapture & 	operator>> (const Mat &image)
          ```
          ```C++
          #include <opencv2/core.hpp>
          #include <opencv2/videoio.hpp>
          #include <opencv2/highgui.hpp>
          #include <iostream>
          #include <stdio.h>
          using namespace cv;
          using namespace std;
          int main(int, char**)
          {
              Mat frame;
              //--- INITIALIZE VIDEOCAPTURE
              VideoCapture cap;
              // open the default camera using default API
              // cap.open(0);
              // OR advance usage: select any API backend
              int deviceID = 0;             // 0 = open default camera
              int apiID = cv::CAP_ANY;      // 0 = autodetect default API
              // open selected camera using selected API
              cap.open(deviceID, apiID);
              // check if we succeeded
              if (!cap.isOpened()) {
                  cerr << "ERROR! Unable to open camera\n";
                  return -1;
              }
              //--- GRAB AND WRITE LOOP
              cout << "Start grabbing" << endl
                  << "Press any key to terminate" << endl;
              for (;;)
              {
                  // wait for a new frame from camera and store it into 'frame'
                  cap.read(frame);
                  // check if we succeeded
                  if (frame.empty()) {
                      cerr << "ERROR! blank frame grabbed\n";
                      break;
                  }
                  // show live and wait for a key with timeout long enough to show images
                  imshow("Live", frame);
                  if (waitKey(5) >= 0)
                      break;
              }
              // the camera will be deinitialized automatically in VideoCapture destructor
              return 0;
          }
          ```
         2. `VideoWriter`
            ```C++
            //常用函数 
             				VideoWriter (const String &filename, int apiPreference, int fourcc, double fps, Size frameSize, bool isColor=true)
            				//VideoWriter进行了四次有参重载,一次无参重载
            
            virtual bool 	isOpened () const
            virtual bool 	open (const String &filename, int fourcc, double fps, Size frameSize, bool isColor=true)
            				//open进行了四次重载
            
            virtual double 	get (int propId) const
            virtual bool 	set (int propId, double value)
            
            virtual VideoWriter & 	operator<< (const Mat &image)   
            ```
            ```C++
            #include <opencv2/core.hpp>
            #include <opencv2/videoio.hpp>
            #include <opencv2/highgui.hpp>
            #include <iostream>
            #include <stdio.h>
            using namespace cv;
            using namespace std;
            int main(int, char**)
            {
                Mat src;
                // use default camera as video source
                VideoCapture cap(0);
                // check if we succeeded
                if (!cap.isOpened()) {
                    cerr << "ERROR! Unable to open camera\n";
                    return -1;
                }
                // get one frame from camera to know frame size and type
                cap >src;
                // check if we succeeded
                if (src.empty()) {
                    cerr << "ERROR! blank frame grabbed\n";
                    return -1;
                }
                bool isColor = (src.type() == CV_8UC3);
                //--- INITIALIZE VIDEOWRITER
                VideoWriter writer;
                int codec = VideoWriter::fourcc('M', 'J', 'P', 'G');  // select desired codec (must be available at runtime)
                double fps = 25.0;                          // framerate of the created video stream
                string filename = "./live.avi";             // name of the output video file
                writer.open(filename, codec, fps, src.size(), isColor);
                // check if we succeeded
                if (!writer.isOpened()) {
                    cerr << "Could not open the output video file for write\n";
                    return -1;
                }
                //--- GRAB AND WRITE LOOP
                cout << "Writing videofile: " << filename << endl
                     << "Press any key to terminate" << endl;
                for (;;)
                {
                    // check if we succeeded
                    if (!cap.read(src)) {
                        cerr << "ERROR! blank frame grabbed\n";
                        break;
                    }
                    // encode the frame into the videofile stream
                    writer.write(src);
                    // show live and wait for a key with timeout long enough to show images
                    imshow("Live", src);
                    if (waitKey(5) >= 0)
                        break;
                }
                // the videofile will be closed and released automatically in VideoWriter destructor
                return 0;
            }  
            ```
[^source]: *见 [`<opencv2/core/mat.hpp>`*](https://gitee.com/c12h22o11/opencv/blob/4.x/modules/core/include/opencv2/core/mat.hpp) : Start with Line 73
                    
        
    