1.分类

  基本数据结构(basic data types)

  辅助数据结构(Helper object)

  大型数据结构(Large array object):mat

  STL数据结构:vector,pair

2.基础数据结构:Point、Scalar、Size、cv::Rect、RotatedRect、Matx

3.点Point

  3.1Point构造

    cv::Point2i p;  //定义点p为2位的整形,例如(x,y) x和y取整形数据

    cv::Point3f p;  //定义点p为3位的浮点型,例如(a,b,c),abc取float数据

    cv::Point3f p2(p1);  //拷贝构造,将p1拷贝给p2

    cv::Point2i p(x0,x1);   //赋值构造,x0和x1直接取int型数据

    cv::Point3d p(x0,x1,x2);  //赋值构造,x0,x1,x2直接取double类型数据

  3.2Point取值

    int i=p.x;  //取Point2i的x坐标

    float f=p.y;  //Point2f的y坐标

  3.3Point函数

     p.inside(r);  //判断p是否在r中

    cv::Point2i p=Point2i(10,10);

    cv::Point2i p1=Point2i(200,200);

    cv::Recti2i r=Rect2i(0,0,100,100);

    bool b=p.inside(r);

    bool b1=p1.inside(r);

4.  4位double类型Scalar:n.数量,标量

    cv::Scalar是四位双浮点数的点集合  4位double

    Scalar(255)表示全白,Scalar(g,b,r)表示一个GBR色彩只是它功能的一种

    4.1Scalar构造

      cv::Scalar s;  //空构造

      cv::Scalar s2(s1);  //拷贝构造 将s1赋值给s2

      cv::Scalar s(x0);  //赋值构造

      cv::Scalar s(x0,x1,x2,x3);  //赋值构造

    4.2Scalar函数

      s1.mul(s2);  //乘法 每一位分别相乘

      Scalar s(255,255,255);

      Scalar s2(10,100,255);

      Scalar ss=s.mul(s2);

5.尺寸Size

  5.1Size构造

    cv::Size sz;  //空构造

    cv::Size2i sz;  //2位int型

    cv::Size2f sz;  //2位float型

    cv::Size sz2(sz1);  //将sz1拷贝给sz2

    cv::Size2f sz(w,h);  //赋值构造,w和h分别对应属性width和height

  5.2取值

    sz.width;  //取宽度  

    sz.height;  //取高度

  size不能够和老的数据结构相互转换。

6.平行矩形Rect

  6.1Rect构造

    cv::Rect r;  //空构造

    cv::Rect r2(r1);  //拷贝构造,将r1赋值给r2

    cv::Rect(x,y,w,h);  //x,y左上角的点坐标 w,h矩形的宽高

    cv::Rect(p,sz);  //p指矩形左上角的点,sz的width和height就是矩形的宽高

    cv::Rect(p1,p2);  //p1指矩形左上角的点,p2指矩形右下角的点

    

    Size size=Size(10,10);

    cv::Rect r1(0,0,100,100);

    cv::Rect r2(p,size);

    cv::Rect r3(p,p2);

  6.2Rect取值

    r.x;  //取左上角x坐标

    r.y;  //取左上角y坐标

    r.width;  //取矩形的宽度

    r.height;  //取矩形的高度

  6.3Rect函数

    r.area();  //面积

    r.tl();  //左上点,top left

    r.br();  //右下点,bottom right

    r.contain(p);  //r是否包含点p       <==>   p.inside(r);  //p点是否存在于r内

  6.4Rect几何运算

    cv::Rect r3=r1&r2;  //交运算

    cv::Rect r3=r1|r2;  //并运算

    cv::Rect rs=r+s;  //r偏移一个size

    bool eq=(r1==r2);  //判断r1、r2是否严格相等

7.旋转矩形RotatedRect

  7.1RotatedRect构造

    cv::RotatedRect rr();  //空构造

    cv::RotatedRect rr2(rr1);  //拷贝构造,将rr1赋值给rr2

    cv::RotatedRect(p1,p2,p3);  //赋值构造,p1,p2,p3必须是矩形的三个点,否则报错

    cv::RotatedRect(p,sz,theta);  //p为中心点,sz为sz,theta为角度 角度是0~360

 

    cv::RotatedRect rr1=cv::RotatedRect(p,size,45);

  7.2RotatedRect取值

    rr.center;  rr.size;  rr.angle;

    rr.points(pts(4));  //获得4个角点的值

    

    Point2i p_rr=rr.center;

    Size p_size=rr1.size;

    float p_angle=rr1.rangle;

    Point2f pts[4];  //点的数组,长度是4,数据类型为float

    rr.points(pts);  //执行完之后,pts内四个点就是矩形rr1的四个角点

8.矩阵Matrax

  Mat可以任意维的,Matx是确定维数的。 特点:quick

  8.1Matx构造  

    cv::Matx33f m33f;  cv::Matx43d m43d;  //空构造

    cv::Matx22d m22d(n22d);  //拷贝构造

    Matx33f m(1,2,3

         4,5,6

         7,8,9);  //赋值构造

    cv::Matx m33f=cv::Matx33f::all(x);  //eg:x=6,三行三列全部都是6

    cv:Matx m23d=cv::Matx23d::zeros();  //6个0

    cv::Matx m16f=cv::Matx16f::ones();  //ones是全是1的意思

    cv::Matx m33f=cv::Matx33f::eye();  //单位矩阵的意思。(1,0,0

                              0,1,0

                              0,0,1)

  8.2Matx取值

    m(i,j);  m(i);  //取值

    double d23=m23d(1,2);  //第2行第3列

    float f16=m16f(0,0);  //第1行第1列

    Matx13f m13f=m33f.row(2);  //第3行

    Matx31f m31f=m33f.col(2);  //第3列

  8.3Matx基本计算

    m1=m0;  //赋值

    m0*m1;  //相乘

    m0+m1;  //相加

    m0-m1;  //相见

    m*a;  //矩阵乘以一个常数

    a*m;  //一个常数乘以一个矩阵

    m/a;  //矩阵除以一个常数,a不等于0

  8.4Matx操作计算

    n44f=m44f.t();  //转置

    标量乘与点乘要求相乘的两个矩阵结构必须是一样的,标量乘必须是一维的。

    m1.mul(m2);  //点乘

    标量乘 (a1,a2,a3,a4)*(b1,b2,b3,b4)=a1*b1+a2*b2+a3*b3+a4*b4;

    向量乘可以3*3与3*1.  向量乘用的符号*

    向量乘 (a00,a01  (b00,b01,b02  (a00*b00+a01*b10,a00*b01+a01*b11,a00*b02+a01*b12

         a10,a11    *    b10,b11,b12)  =   a10*b00+a11*b10,a10*b01+a11*b11,a10*b02+a11*b12

         a20,a21)          a20*b00+a21*b10,a20*b01+a21*b11,a20*b02+a21*b12)

 1 #include <opencv2/opencv.hpp>
 2 #include <iostream>
 3 
 4 using namespace cv; //opencv引用
 5 using namespace std; //C++标准库函数
 6 
 7 int main(int argc, char** argv[])
 8 {
 9     //图片数据
10     Mat src = imread("F:/OpenCV/模拟图像/002.jpg"); //不加读取参数,默认彩色图像
11     imshow("src", src);
12     //points
13     cv::Point2i p = Point2i(10, 10);
14     cv::Point2i p2 = Point2i(200, 200);
15     cv::Point2f p1 = Point2f(0, 0);
16     cv::Point2f p3 = Point2f(10, 10);
17     cv::Point2f p4 = Point2f(200, 200);
18     cv::Rect2i r = Rect2i(0, 0, 100, 100);
19     bool b = p.inside(r); //判断点是否在矩形中
20     bool b2 = p2.inside(r);
21     //scalar
22     Scalar s(255, 255, 255);
23     Scalar s2(10, 100, 255);
24     Scalar ss;
25     ss = s.mul(s2);
26     //rect
27     Size size = Size(100, 100);
28     cv::Rect r1(0, 0, 100, 100); //赋值构造
29     cv::Rect r2(p, size);
30     cv::Rect r3(p, p2);
31     Size sos(10, 10);
32     cv::Rect r4 = r1 & r2;
33     bool eq = (r1 == r2);     //这里的是否相等是严格的相等,不仅仅是面积
34     //rotatedrect
35     Point2f pf1 = Point2f(0, 0);
36     Point2f pf2 = Point2f(10, 0);
37     Point2f pf3 = Point2f(6, 10);
38     //cv::RotatedRect rr2 = cv::RotatedRect(pf1, pf2, pf3);
39     cv::RotatedRect rr1 = cv::RotatedRect(p, size, 45); // 创建数据结构
40     Point2i p_rr = rr1.center;
41     Size p_size = rr1.size;
42     float p_angle = rr1.angle;
43     Point2f pts[4];
44     rr1.points(pts);
45     //matx
46     Matx33f m(1, 2, 3,
47         4, 5, 6,
48         7, 8, 9);
49     cv::Matx23d m23d = cv::Matx23d::zeros();
50     cv::Matx16f m16f = cv::Matx16f::ones();
51     cv::Matx33f m33f = cv::Matx33f::eye();
52     cv::Matx33f randu33f = cv::Matx33f::randu(0, 1);
53     double d23 = m23d(1, 2);
54     float f16 = m16f(0, 0);
55     Matx13f m13f = m33f.row(2);
56     Matx31f m31f = m33f.col(2);
57     waitKey();
58     return 0;
59 }
OpenCV基本数据结构

9.辅助数据结构:cv::Range  cv::ptr  cv::inputarray与cv::outputarray

 标准类库数据结构:Std::vector  Std::pairs

10.区域Rangle:一个连续的区域

  11.1Rangle构造

    cv::Rangle(int start,int end);  //赋值构造

  12.Rangle函数

    size();  //大小  end-start

    empty();  //是否为空  

    Mat src_half_down=src(Range(src.rows/2,src.rows),Rangle(0,src.cols));

    Mat src_half_down2=src(Rect(0,src.row/2,src.cols,src.cols/2));

11.智能指针ptr

  cv::ptr smart point:能够自动销毁(垃圾回收)

  除了能能够在适当的时间自动删除指向的对象外,其工作机制类似于C++的内置指针

  11.1ptr构造

    cv::Ptr<Matx33f> p(new cv::Matx33f);  //空构造  <>里放的是指针指向的数据结构  p为指针的实体  cv::Matx33f为内容的实体 p指向cv::Matx33f这个数据结构

    cv::Ptr<Matx33f> p=makePtr<cv::Matx33f>();  //同上

  11.2Ptr函数

    empty();  //是否为空

    release();  //释放,销毁

    

    cv::Ptr<Matx33f> p(new cv::Matx33f);

    bool b=p.empty();  //b=false

    p.release();

    b=p.empty();  //b=true

12.InputArray与OutputArray

  包括cv::Scalar、cv::Vec、cv::Matx

  一种通用模式

  两者不同:InputArray一般被认为是const(readonly)常量

13.向量Vector

  vector是一个十分有用的容器,可以理解成数组,数组里面可以放Mat,也可以嵌套

  13.1Vector向量

    Vector<类型> 变量名

    std::vector<Mat> myVector;

    std::vector<std::vector<cv::Point>> contours;   //嵌套

  13.2Vector函数

    myVector.push_back(src);  //尾部插入

    Mat tmp=myVector[0];  //下标访问

    vector<Mat>::iterator it;  //使用迭代器访问

    for(it=myVector.begin();it!=myVector.end();it++)

    {

      imshow("it",it);

    }

    myVector,insert(myVector.begin()+0,src_half_down);   //在第i个元素前面添加

    myVector.erase(myVector().begin()+1);  //删除第i个元素

    reverse(myVector.begin(),myVector.end());  //反转

    sort(myVector.begin(),myVector.end(),comp);  //排序

    bool Comp(const Mat &a, const Mat &b)
    {//重写了排序方法,按图片的高度从小打到排序
          return a.rows < b.rows;
    }

    myVector.clear();  //清空

14.模板类型pair

  哥俩好的意思,其中包含两个数据值(可以相同可以不同)

  类似于键值对

  14.1pair构造

    pair<string,string> a;  //空构造

    pair<string,string> a("James","Joy");  //赋值构造

    vector<pair<Mat,string>>

  14.2取值

    pair<string,string> a("Lily","Poly");

    string name;

    name=a.first;

    name=a.second;

 1 #include <opencv2/opencv.hpp>
 2 #include <iostream>
 3 
 4 using namespace std;
 5 using namespace cv;
 6 
 7 bool Comp(const Mat &a, const Mat &b)
 8 {
 9     return a.rows < b.rows;
10 }
11 
12 int main(int argc, char** argv[])
13 {
14     //图片数据
15     Mat src = imread("F:/OpenCV/模拟图像/002.jpg");
16     imshow("src", src);
17     //range
18     cv::Range range = cv::Range(0, 4);
19     Mat src_half_down = src(Range(src.rows / 2, src.rows), Range(0, src.cols));
20     //Mat src_half_down2 = src(Rect(0, src.rows / 2, src.cols, src.cols / 2));
21     //ptr
22     cv::Ptr<Matx33f> p(new cv::Matx33f); //将声明的对象分配给指针
23     bool b = p.empty();    //b = false
24     p.release();    //释放销毁
25     b = p.empty();         //b = true
26     //vector
27     std::vector<Mat> myVector;
28     std::vector<std::vector<cv::Point>>contours;
29     myVector.push_back(src);   //尾部插入
30     myVector.push_back(src_half_down);
31     Mat tmp = myVector[0];     //下标访问
32     vector<Mat>::iterator it;  //使用迭代器访问
33     for (it = myVector.begin(); it != myVector.end(); it++)
34     {
35         imshow("it", *it);
36     }
37     myVector.insert(myVector.begin() + 0, src_half_down);  //在第i个元素前面添加
38 
39     reverse(myVector.begin(), myVector.end());           //翻转
40     sort(myVector.begin(), myVector.end(), Comp);         //排序
41 
42     myVector.erase(myVector.begin() + 1);                 //删除第i个元素
43     myVector.clear();//清空
44     //pair
45     pair<string, string> a("Lily", "Poly");
46     string name;
47     name = a.first;
48     name = a.second;
49 
50     waitKey();
51     return 0;
52 }
辅助数据结构与标准类库数据结构

15.大型数据结构:Mat(dense arrays)、SparseMat(sparse array)

16.Mat——OpenCV中最常用的数据结构

  多维稠密数据结构 N-Dimensional Dense Arrays

  稠密数据(从0、0到n、n每个位置都有数据)

  稀疏数据(从0、0到n、n有的位置有数据,有的位置没数据)

  Mat不仅仅用来表示图片

  Mat本身是一个带有垃圾清理机制的数据结构(类),它指向了一块数据存储的区域,同时它的定义中还包括了其他一些信息。这些消息包括

    类型type:UINT8

    通道数channels:3

    宽度width、高度height

    数据data:像素数

    步长stride

  16.1Mat构造

    cv::Mat;  //空构造

    cv::Mat(cv::Size sz,int type);  //赋值构造

    cv::Mat(cv::Size sz,int type,const Scalar&s);  //赋值构造

    cv::Mat mat=imread("path");  //图片从磁盘中读入内存,最常用

    cv::Mat(const Mat& mat);  //拷贝构造,由老结构中生生成

    cv::Mat(const CvMat* old,bool copyData=false);

    cv::Mat(consot IplImage* old,bool copyData=false);

    三种特殊构造:

    cv::Mat::zeros(rows,cols,type);   //数据全0

    cv::Mat::ones(rows,cols,type);  //数据全1

    cv::Mat::eye(rows,cols,type);  //单位正,对角为1

    如果是8位的,0代表全黑,255代表全白;如果是32位的,0代表全黑,1代表全白。

17.Mat图像遍历

  遍历时要先初始化,指定结果图像Mat的尺寸和通道数

  Mat可表示图像、数据和多维数组

  17.1 at

    at遍历图像的格式:M.at<float>(i,j,k);   如果是CV_8U类型,应该是<uchar>

 1     //对色彩图像强度减半
 2     for (int i = 0; i < src.rows; i++) 
 3     {
 4         for (int j = 0; j < src.cols; j++) 
 5         {
 6             //三通道图像[0][1][2]
 7             //Vec3b:Vec<uchar, 3> Vec3b;
 8             src.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0] / 2;
 9             src.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[1] / 2;
10             src.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j)[2] / 2;
11         }
12     }
图像遍历的第一种方式 at

  17.2 指针

    opencv中图像Mat每一行数据元素之间在内存里是连续存储的额,但行与行之间可能有空白单元

    指针遍历比at遍历速度要快

 1     //图像遍历的第二种方式 指针方式
 2     Mat outImage;
 3     outImage.create(src.size(), src.type());
 4     int nr = src.rows;    // 将3通道转换为1通道  
 5     int nl = src.cols*src.channels();
 6     for (int k = 0; k < nr; k++)
 7     {
 8         for (int i = 0; i < nl; i++)
 9         {
10             outImage.ptr<uchar>(k)[i] = src.ptr<uchar>(k)[i] * 2;
11         }
12     }
图像遍历的第二种方式 指针方式

  17.3连续指针

    连续指针比指针速度要快,但要求是图像每行在内存中必须是连续的

 1     //图像便利的第三种方式 连续指针
 2     nr = src.rows;
 3     int nc = src.cols;
 4     outImage.create(src.size(), src.type());
 5     if (src.isContinuous() && outImage.isContinuous())
 6     {//能否可以用连续指针,要事先判断图像存储是否是连续的
 7      //类似于把n*n的图像拉成一行,拉成一长条
 8         nr = 1;
 9         nc = nc * src.rows*src.channels();//高*宽*通道
10     }
11     for (int i = 0; i < nr; i++)
12     {
13         const uchar* inData = src.ptr<uchar>(i);
14         uchar* outData = outImage.ptr<uchar>(i);
15         for (int j = 0; j < nc; j++)
16         {
17             *outData++ = *inData * 2;
18         }
19     }
图像便利的第三种方式 连续指针

  17.4迭代器

     也很常用

 1     //图像遍历的第四种方式 迭代器
 2     outImage.create(src.size(), src.type());
 3     //源数据都是用不可修改的迭代器变量
 4     MatConstIterator_<Vec3b> it_in = src.begin<Vec3b>();
 5     MatConstIterator_<Vec3b> itend_in = src.end<Vec3b>();
 6     //输出使用可修改的迭代器变量
 7     MatIterator_<Vec3b> it_out = outImage.begin<Vec3b>();
 8     MatIterator_<Vec3b> itend_out = outImage.end<Vec3b>();
 9     while (it_in != itend_in)
10     {
11         (*it_out)[0] = (*it_in)[0] * 2;
12         (*it_out)[1] = (*it_in)[1] * 2;
13         (*it_out)[2] = (*it_in)[2] * 2;
14         it_in++;
15         it_out++;
16     }
图像遍历的第四种方式 迭代器

  17.5 block方式

    一次选择一行或一列

1     //图像遍历的第五种方式 BLOCK
2     Mat matRow = src.row(0);
3     Mat matCols = src.col(0);
4     Mat matRowRange = src.rowRange(0, 10);
5     Mat matSrcRange = src.colRange(0, 10);
6     Mat matDiag = src.diag();              //求特征矩阵
7     Mat roi = src(cv::Rect(0, 0, 10, 10)); //取ROI
图像遍历的第五种方式 BLOCK

 18.Mat函数

  m1=m0.clone();  //m0拷贝给m1

  m0.copyTo(m1);  //同上

  m0.copyTo(m1,mask);  //带有模板的拷贝

  m0.convertTo(m1,type,scale,offset);  //格式转换

  Mat src32f;  //注意量纲的变化

  src.convertTo(src32,CV_32F,1.0/255);  //8位转32,8位全白为255,32位全白为1,由255到1,量纲为1.0/255,注意不能是1/155,一个是浮点型,一个是整形

  src32f.convertTo(src,CV_8U,255);   //32位转8位,乘255

  m0.setTo(s,mask);  //带模板的设置

 19.稀疏矩阵SparseMat

  使用SparseMat,一方面是使用SparseMat带来的复杂和便利图像性能影响,一方面是由于减少了空运算而带来的性能提升。

  19.1 SparseMat构造

    cv::SparseMat sm;  //空构造

    cv::SparseMat sm(3,sz,CV_32F);  //赋值构造,分别是维度、大小和类型

    SparseMat sm(sm0);  //拷贝构造,sm0可以是sparseMat,或者是Mat

   19.2 SparseMat访问

    智能指针:uchar* cv::SparseMat::ptr(int i0,bool createMissing,size_t* hashval=0);

         i0,序号;  createMissing,当创建对象为空的时候是否创建;  Hashval,是否重新计算hash值

    ref:  SparseMat::ref<>()用来访问稀疏矩阵中的一个值

    value:  cv::SparseMat::value<>()的作用和用法与ref类似,但其返回的是const值,不能修改只能获得

     find:  cv::SparseMat::find<>()返回hash的值,而不是索引

 1     //稀疏矩阵
 2     int size[] = { 10,10 };
 3     cv::SparseMat sm(2, size, CV_32F);
 4     for (int i = 0; i < 10; i++) {           // Fill the array
 5         int idx[2];
 6         idx[0] = size[0] * rand();
 7         idx[1] = size[1] * rand();
 8         sm.ref<float>(idx) += 1.0f;
 9     }
10     // Print out the nonzero elements
11     cv::SparseMatConstIterator_<float> it = sm.begin<float>();
12     cv::SparseMatConstIterator_<float> it_end = sm.end<float>();
13     for (; it != it_end; ++it) {
14         const cv::SparseMat::Node* node = it.node();
15         printf(" (%3d,%3d) %f\n", node->idx[0], node->idx[1], *it);
16     }
稀疏矩阵

20.Mat基本函数

  20.1取绝对值cv::abs()  

    cv::MatExpr cv::abs(cv::InputArray src);

    cv::MatExpr cv::abs(const cv::MatExpr&src);

  20.2得到两值差值的绝对值cv::absdiff

    void cv::absdiff(cv::InputArray src1,cv::InputArray src2,cv::OutputArray dst);

    dst=saturate(|src1-src2|);

  20.3添加,将第2个图像添加到第一个图像中,并保存到输出结果中cv::add()

    void cv::add(cv::InputArray src1,cv::InputArray src2,cv::OutputArray dst,cv::InputArray mask=cv::noArray(),int dtype=-1);

    dst=saturate(src1+src2);

    eg:cv::add(src,star,temp);

  20.4弱化叠加操作cv::addWeighted()

    void cv::addWeighted(cv::InputArray src1,double alpha,cv::InputArray src2,double beta,double gamma,cv::OutputArray dst,int dtype=-1);

    dst=saturate(src1*α+src2*β+γ)

    eg:cv::addWeighted(src,0.5,srcR,1,0,temp);

  20.5取交集cv::bitwise_and()

    void cv::bitwise_and(cv::InputArray src1,cv::InputArray src2,cv::OutputArray dst,cv::InputArray mask=cv::noArray);

    dst=src1&src2;

  20.6取并集cv::bitwise_or()

    void cv::bitwise_or(cv::InputArray src1,cv::InputArray src2,cv::OutputArray dst,cv::InputArray mask=cv::noArray);

    dst=src1|src2;

  20.7取异或cv::bitwise_xor()

    void cv::bitwise_and(cv::InputArray src1,cv::InputArray src2,cv::OutputArray dst,cv::InputArray mask=cv::noArray);

    dst=src1^src2;

  20.8取反cv::bitwise_not()

    cv::bitwise_not(star,temp);  //取反,黑的变白,白的变黑

  20.9比较cv::compare()

    bool cv::compare(cv::InputArray src1,cv::InputArray src2,cv::OutputArray dst,int cmpop);

    flag:   cv::CMP_EQ(src1==src2)

         cv::CMP_GT(src1>src2)

        cv::CMP_GE(src1>=src2)

        cv::CMP_LT(src1<src2)

        cv::CMP_LE(src1<=src2)

        cv::CMP_NE(src1!=src2)

   20.10极坐标cv::cartToPolar()

    void cv::cartToPolar(cv::InputArray x,cv::InputArray y,cv::OutputArray magnitude,cv::OutputArray angle,bool angleIeInDegrees=false);

  20.11cv::convertScaleAbs()

    void cv::convertScaleAbs(cv::InputArray src,cv::OutputArray dst,double alpha=1.0.double beta=1.0);

    dst=saturate|src*α+β|;

    防止过曝

  20.12非零值cv::countNonZero()

    int cv::countNonZero(cv::InputArray mtx);

    计算非零值

   20.13颜色转换cv::cvtColor()

    void cv::cvtColor(cv::InputArray src,cv::OutputArray dst,int code,int dstCn=0);

    code:eg:RGB2GRAY、BGR2RGB

  20.14图像转装cv::flip()

    void cv::filp(cv::InputArray src,cv::OutputArray dst,int flipCode=0);

    Code  >0,y-filp  =0,x-flip  <0,both

  20.15查表运算

    void cv::LUT(cv::InputArray src,cv::InputArray lut,cv::OutputArray dst);

    dst=lut(src);

    查表运算是最快的运算方式

    查表对于图像转换,可以直接使用