opencv学习笔记(三)基本数据类型
类:DataType
将C++数据类型转换为对应的opencv数据类型
OpenCV原始数据类型的特征模版。OpenCV的原始数据类型包括unsigned char、bool、signed char、unsigned short、signed short、int、float、double以及由这些基础类型组成的元组,这些元组中的所有值都属于相同的类型。这个原始数据类型列表中的所有类型都可以使用一个标示符进行表示CV_<bit-depth>{U|S|F}C(<number_of_channels>),例如,uchar ~ CV_8UC1,3元素的浮点元组~ CV_32FC3,等等。一个一般的OpenCV结构体能够被存储到一个单独的实例中,例如一个原始数据类型Vec。多个实例可以被存储在std::vector、Mat、Mat_、SparseMat、OparseMat_或其他可以保存Vec实例的容器中。
DataType类主要用来为原始数据类型提供描述,同时它不会给对应的类加入字段和方法(实际上不可能修改C/C++的原始数据类型)。这个技术依赖于C++的类特性。DataType本身并不会被使用,但是他的特殊版本会被使用,例如:
1 template<> class DataType<uchar> 2 { 3 typedef uchar value_type; 4 typedef int work_type; 5 typedef uchar channel_type; 6 enum { channel_type = CV_8U, channels = 1, fmt=’u’, type = CV_8U }; 7 }; 8 ... 9 template<typename _Tp> DataType<std::complex<_Tp> > 10 { 11 typedef std::complex<_Tp> value_type; 12 typedef std::complex<_Tp> work_type; 13 typedef _Tp channel_type; 14 // DataDepth is another helper trait class 15 enum { depth = DataDepth<_Tp>::value, channels=2, 16 fmt=(channels-1)*256+DataDepth<_Tp>::fmt, 17 type=CV_MAKETYPE(depth, channels) }; 18 }; 19 ...
这个类的主要的目的是为为OpenCV的兼容数据类型标示符转换编译类型信息,例如:
1 // 申请一个 30x40 浮点矩阵 2 Mat A(30, 40, DataType<float>::type); 3 Mat B = Mat_<std::complex<double> >(3, 3); 4 // 下边将会打印出6,2,意思是depth == CV_64F,channels == 2 5 cout << B.depth() << ", " << B.channels() << endl;
所以这个特性用来告诉OpenCV你当前在使用什么数据类型,即使这个类型并非源自于OpenCV。例如,矩阵B将会被编译,因为OpenCV定义了专门的模版类DataType<complex<_Tp> >。这个机制也用于泛型机制。
Point_
类:Point_
2D点的模板类,用来描述它的x和y坐标。这个类的实例可以与C结构体CvPoint和CvPoint2D32f之间进行互相转换。其中有类型转换运算符将点的坐标转换成指定的类型。将浮点型坐标转换成整形坐标要通过舍入来完成。通常,转换工作会对每一个坐标执行这个操作。除了上边提到的类成员,以下列出的其它对点的使用操作:
1 pt1 = pt2 + pt3; 2 pt1 = pt2 - pt3; 3 pt1 = pt2 * a; 4 pt1 = a * pt2; 5 pt1 += pt2; 6 pt1 -= pt2; 7 pt1 *= a; 8 double value = norm(pt); // L2 norm 9 pt1 == pt2; 10 pt1 != pt2;
为了使用方便,还定义了下边的类别名:
1 typedef Point_<int> Point2i; 2 typedef Point2i Point; 3 typedef Point_<float> Point2f; 4 typedef Point_<double> Point2d;
例如:
1 Point2f a(0.3f, 0.f), b(0.f, 0.4f); 2 Point pt = (a + b)*10.f; 3 cout << pt.x << ", " << pt.y << endl;
Point3_
类:Point3_
3D点的模板类,用来描述它的x、y和z坐标。这个类的实例可以与C结构体CvPoint2D32f之间进行互相转换。与Point_相似,3D坐标可以被转换成其他类型。同时这个类也支持vector和比较操作。
Point3_<>有以下可用的别名:
1 typedef Point3_<int> Point3i; 2 typedef Point3_<float> Point3f; 3 typedef Point3_<double> Point3d;
Size_
类:Size_
用于指定图像和矩形尺寸的类模板。这个类包含两个成员变量width和height。这个结构体可以与老版OpenCV中的CvSize和CvSizeD32f之间进行转换。能够应用于Point_类的算法和比较操作对Size_也是有效的。
OpenCV定义了以下Size_<>的别名:
1 typedef Size_<int> Size2i; 2 typedef Size2i Size; 3 typedef Size_<float> Size2f;
Rect_
类:Rect_
2D矩形的模板类,用以下参数进行描述:
- 左上角的坐标。这是一个OpenCV中的内定的值Rect_::x和Rect_::y。(左上角为(0,0))但是在你的算法中可能会从左下角计算x和y。
- 矩形的宽和高。
OpenCV假设矩形的上边沿和左边沿是包含的,而右边沿和下边沿是不包含的。例如,如果符合以下情况,则方法Rect_::contains将返回true:
1 x <pt:x < x + width; y<pt:y < y + height
实际上在OpenCV中循环浏览一个图像的ROI(ROI被通过Rect_<int>指定)是这样实现的:
1 for(int y = roi.y; y < roi.y + rect.height; y++) 2 for(int x = roi.x; x < roi.x + rect.width; x++) 3 { 4 // ... 5 }
除了成员变量,以下对于矩形的操作也得到了实现:
- rect = rect +/- point (通过某一偏移值移动矩形)
- rect = rect +/-size (通过某一数量扩大或缩小矩形)
- rect += point, rect -= point, rect += size, rect -= size (扩张操作)
- rect = rect1 & rect2 (矩形相交)
- rect = rect1 | rect2 (包含rect2和rect3的最小区域 )
- rect &= rect1, rect |= rect1 (and the corresponding augmenting operations)
- rect == rect1, rect != rect1 (矩形比较)
为了便利,Rect_<>有以下别名:
1 typedef Rect_<int> Rect;