OpenCV设计了许多种数据类型,让计算机视觉和机器学习任务变得更加简单、直观。OpenCV中的数据类型可分为三大类:

  • 基本数据类型。该类型直接由C++的数据类型(int或float等)组装而来,包括简单的向量和矩阵,以及简单的几何表示,如点、矩形和尺寸等。
  • 辅助对象。这些对象表示更抽象的概念,如垃圾收集指针类等,用于表示切片的范围对象,以及对某些算法终止条件的抽象等。
  • 大型数组类型。该类型包含数组和其他常见的基本数据类型,典型代表是cv::Mat类,用于表示包括任意基本元素的任意维度的数组。cv::Mat类的一个专门用途就是表示及存储图像数据。

1.基本数据类型

1.1基本数据类型之cv::Vec类

cv::Vec类可用来表示固定长度的向量,是一个模板类,常使用[]来访问Vec向量成员,主要用来存储数值向量。值得注意的是,cv::Vec类在编译时都需要知道变量的长度。

(1)使用cv::Vec类可以定义任意类型的向量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
cv::Vec<double,3> myVector; //自定义一个存放3个double 型变量的向量
cv::Vec3d v3d(x0, x1, x2); //使用预定义创建一个存放3个double 型变量的向量

/*Shorter aliases for the most popular specializations of Vec<T,n>
typedef Vec<uchar, 2> Vec2b;
typedef Vec<uchar, 3> Vec3b;
typedef Vec<uchar, 4> Vec4b;

typedef Vec<short, 2> Vec2s;
typedef Vec<short, 3> Vec3s;
typedef Vec<short, 4> Vec4s;

typedef Vec<ushort, 2> Vec2w;
typedef Vec<ushort, 3> Vec3w;
typedef Vec<ushort, 4> Vec4w;

typedef Vec<int, 2> Vec2i;
typedef Vec<int, 3> Vec3i;
typedef Vec<int, 4> Vec4i;
typedef Vec<int, 6> Vec6i;
typedef Vec<int, 8> Vec8i;

typedef Vec<float, 2> Vec2f;
typedef Vec<float, 3> Vec3f;
typedef Vec<float, 4> Vec4f;
typedef Vec<float, 6> Vec6f;

typedef Vec<double, 2> Vec2d;
typedef Vec<double, 3> Vec3d;
typedef Vec<double, 4> Vec4d;
typedef Vec<double, 6> Vec6d;
*/

(2)cv::Vec类支持的基本运算

1
2
3
4
5
6
7
8
9
10
vl=v2+v3      //加
vl=v2-v3 //减
vl=v2*scale //乘标量
vl=-v2
vl+=v2
vl==v2 //相等
vl!=v2 //不相等
vl.dot(v2) //点积
vl.cross(v2) //叉积
norm(v1) //范数

1.2基本数据类型之cv::Point类

cv::Point类(点类)是一个用来存放2个或3个int或float等基本类型值的容器。cv::Point类是从自己的模板中派生的,并非来自固定向量类。点类和固定向量类之间的主要区别在于点类的成员可以通过命名变量( myPoint.x 、myPoint.y等访问,而不是通过向量索引(myVec [0],myVec [1])
访问。与cv::Vec类一样,cv::Point类通常通过定义别名实例化预定义模板 ,其包 括cv::Point2i 、 cv::Point2f 和 cv::Point2d , 或cv::Point3i、cv::Point3f和cv ::Point3d。 cv::Point类基本使用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//默认构造方式
cv::Point2i p;
cv::Point3f p;
//通过拷贝构造
cv::Point3f p2(p1);
//赋值构造
cv::Point2i p(x0,x1);
cv::Point3d p(x0,x1,x2);
//转换到固定向量类
(cv::Vec3f) p;
//成员访问
p.x; p.y; //对三维 point 类还可以访间: p.z
//加减法运算
p+=p1;p-=p2;
//与常数相乘
p*2;
//点积
float x = pl.dot( p2);
//双精度点积
double x = p1.ddot( p2)
//叉积
p1.cross(p2); //仅对三维 point 类可用
//查询点p是否在知形r内部
p.inside(r) //仅对二维poit类可用

1.3基本数据类型之cv::Scalar类

cv::Scalar类(标量类)实际上是一个四维双精度向量类,其有一些特殊的成员函数与计算机视觉中使用的4分量向量相关。cv::Scalar类支持的构造方式及基本使用方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
//默认构造方式
cv::Scalar s;
//通过拷贝构造
cv:: Scalar s2(s1);
//赋值构造
cv:: Scalar s(x0);
cv:: Scalar s(x0,x1,x2,x3);
//元素乘法
s1.mul( s2 );
//(四元数)共钜
s.conj(); //returns cv::Scalans0,-s1,-s2,-s2))
//(四元数)真正实部检验
s.isReal(); //returns true if s1== s2==s3==0)

1.4基本数据类型之cv::Size类

cv::Size类(尺寸类)可以与cv::Point类相互转换, 两者的主要区别是cv::Point类的成员变量名
是x和y,而cv:Size类的成员变量名是width和height。cv:Size类的三个别名是cv::Size、cv::Size2i和cv::Size2f。上述别名的前两个是等效的,成员为整型变量,而cv::Size2f的成员是32位浮点型变量。
cv::Size类构造方式及基本使用方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
//默认构造方式
cv::Size sz;
cv::Size2i sz;
cv::Size2f sz;
//通过拷贝构造
cv::Size sz2( sz1);
//赋值构造
cv::Size2f sz( w, h);
//成员访问
sz.width; sz.height;
//计算面积
sz.area();

1.5基本数据类型之cv::Rect类

cv::Rect类(矩形类)包括cv::Point类的成员x和y(表示矩形的左上角)以及cv::Size类的成员width和height(表示矩形的大小)。cv::Rect类构造方式及基本使用方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//默认构造方式
cv::Rect r;
//通过拷贝构造
cv::Rect r2( r1);
//赋值构造
cv::Rect(x,y,w,h);
//通过原点与尺寸构造
cv::Rect( p,sz);
//通过左上角点和右下角点构造
cv::Rect( pl,p2);
//成员访问
r.x;ry;r.width;r.height:
//计算面积
r.area();
//提取左上角点
r.tl();
//提取右下角点
r.br();
//检测p点是否在矩形内部
r.contains(p);
//矩形r1和2的交集
cv::Rect r3 = r1 & r2;
r1 &= r2;
//包含矩形r1和r2的最小矩形
cv::Rect r3 = r1 | r2;
rl |= r2;
//将矩形r平移x,x为cv:Point 类变量
cv::Rect rx = r+x;
r += x;
//在宽、高方向改变矩形r的大小,s为cv:Size类变量
cv::Rect rs = r+ s;
//比较矩形r和r2是否完全相等
bool iseq=(r1 == r2);
//比较矩形r1和r2是否不相等
bool isne= (r1 != r2);

1.6基本数据类型之cv::RotatedRect类

cv::RotatedRect类(有向矩形类)包含一个名为center(中点)的cv::Point2f变量、一个名为size(矩形大小)的cv::Size2f变量,以及一个名为angle的浮点数变量,表示矩形围绕中心的旋转。
cv::RotatedRect类和cv::Rect类之间存在一个非常重要的区别——cv::RotatedRect类的位置相对于其center,而cv::Rect类的位置相对于其左上角。cv::RotatedRect类支持的构造方式及基本使用方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//默认构造方式
cv::RotatedRect rr;
//通过拷贝构造
cv::RotatedRect rr2(rr1);
//通过按顺序的三个角点构造
cv::RotatedRect(p1,p2,p3);
//赋值构造,需要一个中点,一个尺寸和一个角度
cv::RotatedRect rr(p, sz, theta);
//成员访问
rr.center; rrsize;rrangle;
//返回四个角点的列表
rr.points(pts[4]);
//绘制最小外接矩形
cv::RotatedRect rRect(center, size, angle);
cv::Point2f vertices[4];
rRect.points(vertices); //获取 4个角点
for (inti=0;i<4; i++) //逐条边绘制旋转矩形
line(I,vertices[i],vertices[(i+1)%4],cv::Scalar(25500),2);
//获取最小外接矩形的外接矩形
cv::Rect boundingRect = rRect.boundingRect(); //外接矩形
cv::rectangle(I,boundingRect,Scalar(00255),1);

3.大型数组类型

3.1 大型数组类型之cv::Mat类

cv::Mat 类( 数组类 )用于表示任意维度的稠密数组( NDimensional Dense Arrays其元素可以是任意类型的变量。在OpenCV中图像就是使用cv::Mat类来表示的。稠密数组指的是数组中每个元素都需要存储特定的值,例如图像。与稠密数组相对应的是稀疏数组cv::SparseMat类,在稀疏数组中,大多数元素都为0,因此只有非零元素才需要被存储,这样可以节约大量的存储空间,例如常见的直方图。

可以通过实例化一个cv::Mat类的变量来创建数组。数组的类型type决定了数组元素的类型。一个有
效的类型包含类型和通道数,例如,对于CV_{8U, 16S, 16U, 32S, 32F, 64F}C{1, 2, 3}的组合,CV_8UC3表示一个三通道的8位无符号整型数据,CV_32FC1表示一个单通道的328位浮点数。在cv::Mat类中,有非常多的构造函数,包括未复制数据的构造函数与复制了数据的构造函数两种,其构造方式及基本使用方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//默认构造方式
cv::Mat m;
//指定类型的二维数组
cv::Mat( int rows, int cols, int type );
//指定类型的二维数组,并指定初值
cv::Mat(int rows,int cols, int type,const cv::Scalar& s);
//指定类型的二维数组,并指定预先存储的数据
cv::Mat(int rows, int cols, int type,void* data, size_t step=AUTO_STEP);
//指定类型的二维数组,数组大小由sz指定
cv::Mat( cv::Size sz, int type );
//指定类型的二维数组,数组大小由sz指定,并指定初值
cv::Mat(cv::Size sz, int type, const Scalar& s);
//指定类型的二维数组,数组大小由sz指定,并指定预先存储的数据
cv::Mat(cv::Size sz, int type, void* data, size_tstepAUTO_STEP);
//指定类型的多维数组
cv::Mat(int ndims, constint* sizes,int type);
//指定类型的多维数组,并指定初值
cv::Mat(int ndims, constint* sizes,int type, const Scalar& s);
//指定类型的多维数组,并指定预先存储的数据
cv::Mat(int ndims, constint* sizes,int type void* data, size_t step=AUTO_STEP);
//指定类型的二维数组,并按要求初始化为全0全1或对角线为1的矩阵
cv::Mat::zeros(cv::Size sz,int type);
cv::Mat::ones(cv::Size sz,int type);
cv::Mat::eye(cv::Size sz,int type);
//复制构造方式
cv::Mat( const Mat& mat);
//从指定的行列中复制数据
cv::Mat(const Mat& mat, const cv::Range& rows,const cv::Range& cols);
//从感兴趣区域(ROI)指定的行列中复制数据
cv::Mat(const Mat& mat,const cv::Rect& roi);
//用于多维数组,从泛化,感兴趣区域中复制数据
cv::Mat(const Mat& mat,const cv::Range*ranges);
//从其他矩阵的线性代数表示中生成新矩阵
cv::Mat(const cv::MatExpr& expr);
//矩阵加减法
m0+m1;m0-m1;
//矩阵与数的加减法
m0+s;m0-s;s+m0;s-m1;
//矩阵求反
-m0;
//矩阵与数相乘实现缩放
s*m0;m0*s;
//矩阵对应元素相乘或相除
m0.mul(m1); mo/m1;
//矩阵相乘
m0*ml;
//矩阵求逆(默认ECOMP_LU方法)
m0.inv(method);
//矩阵转置(未发生值拷贝)
m0.t();
//逐个元素比较,为真返回255,为假返回0
m0>m1;m0>=ml;m0==ml;m0<=m1;m0<m1;
//矩阵与矩阵,或者矩阵与实数逐位逻辑运算
m0&m1;m0m1;m0Am1;~m0;
m0& s; s&m0;m0|s; s|m0; m0^s; s^m0;
//矩阵与矩阵,或者矩阵与实数逐位比较最大值或最小值
min(m0,m1);max(m0,m1);min(m0,s);
min(s,m0);max(m0,s); max(s,m0);
//逐位取绝对值
cv::abs(m0);
//向量叉积与点积(向量叉积只用于 3x1矩)
m0.cross(m1); modot(m1);