OpenCV中的数据类型
OpenCV有很多数据类型,它们都基于一些重要视觉概念的抽象而设计,来提供相对简单,直观的表示和处理。
从组织结构的角度而言,OpenCV的基础数据类型主要分为三类
第一类,直接从C++原语中继承的基础数据类型(如int和float),这些类型包括简单的数组和矩阵。
第二类,辅助对象,这些对象代表更抽象的概念,比如垃圾收集指针,用于数据切片的范围对象(range objects)
第三类,大型数组类型,典型的代表是cv::Mat类,该类用来代表任意维度的包含任意基础元素的数组。
除了这些,OpenCV还有很多标准模板库(STL)。
基础类型介绍
每一个基础类型实际上都是一个相对复杂的类,支持它自己的接口函数、重载以及类似的操作
1.Point类
这个类是OpenCV的基础类型,Point可能是最简单的,它是一个点模板类。
它们可以成为任何类型的点,如整型和浮点型,还分为二维点模板类Point_和三维点模板类Point3_,源代码中定义为:
typedef Point_<int> Point2i;
typedef Point2i Point;
typedef Point_<float> Point2f;
typedef Point_<double> Point2d;
typedef Point3_<int> Point3i;
typedef Point3_<float> Point3f;
typedef Point3_<double> Point3d;
所以在大多数程序中,Point类是通过类似于cv::Point2i和cv:Point3f这类别名来实例化的,别名的最后一个字母表示构造该点需要的原语:
- b是一个无符号字符
- s是一个短整型
- i是一个32位整型
- f是一个32位浮点数
- d是一个64位浮点数
Point类原生支持的函数列表:
| 操作 | 示例 |
|---|---|
| 默认构造函数 |
cv::Point2i p; cv::Point3i p; |
| 复制构造函数 | cv::Point3f p2(p1); |
| 值构造函数 |
cv::Point2i(x0, x1); cv::Point3d p(x0,x1,x2); |
| 构造成固定向量类 | (cv::Vec3f) p; |
| 成员访问 | p.x, p.y; |
| 点乘 | float x = p1.dot(p2); |
| 双精度点乘 | double y = p1.dot(p2); |
| 叉乘 | p1.cross(p2); |
| 判断一个点p是否在举行r内 | p.inside(r); |
举个例子:
Point point;//创建一个2D点对象
point.x = 10;//初始化x坐标值
point.y = 8;//初始化y坐标值
或者
Point point = Point(10, 8);
2.Scalar类
cv::Scalar类是四维点类。在这个模板中,所有的成员都是双精度浮点数。定义如下:
template<typename _Tp> class Scalar_ : public Vec<_Tp, 4>
{
public:
//! default constructor
Scalar_();
Scalar_(_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0);
Scalar_(_Tp v0);
Scalar_(const Scalar_& s);
Scalar_(Scalar_&& s) CV_NOEXCEPT;
Scalar_& operator=(const Scalar_& s);
Scalar_& operator=(Scalar_&& s) CV_NOEXCEPT;
template<typename _Tp2, int cn>
Scalar_(const Vec<_Tp2, cn>& v);
//! returns a scalar with all elements set to v0
static Scalar_<_Tp> all(_Tp v0);
//! conversion to another data type
template<typename T2> operator Scalar_<T2>() const;
//! per-element product
Scalar_<_Tp> mul(const Scalar_<_Tp>& a, double scale=1 ) const;
//! returns (v0, -v1, -v2, -v3)
Scalar_<_Tp> conj() const;
//! returns true iff v1 == v2 == v3 == 0
bool isReal() const;
};
cv::Scalar类支持的操作
| 操作 | 示例 |
|---|---|
| 默认构造函数 | cv::Scalar s; |
| 复制构造函数 |
cv::Scalar s2(s1); |
| 值构造函数 | cv::Scalar s(x0); cv::Scalar s(x0, x1, x2, x3); |
| 元素相乘 | s1.mul(s2); |
| (四元数)共轭 | s.conj();// return cv::Scalar(s0, -s1, -s2, -s3); |
| (四元数)真值测试 | s.isReal();// return true, if s1==s2==s3==s4 |
Scalar类是四维双精度向量的快速表示,它是直接从固定向量类模板实例中继承而来。
3.Size类
Size类在实际操作时与Point类类似,而且可以与Point类互相转换,两者的主要区别在于Point类的数据成员是x和y,而size类中对应的成员是width和height。
Size类的三个别名分别是cv::Size, cv::Size2i, cv::Size2f. 前两个等价,最后一个表示32位浮点数大小。
Size类可以与对应的旧类型的OpenCV类(CvSize和CvSizeD32f)互相转换
Size类直接支持的操作:
| 操作 | 示例 |
|---|---|
| 默认构造函数 |
cv::Size sz; cv::Size2i sz; cv::SIze2f sz; |
| 复制构造函数 | cv::Size sz2(sz1); |
| 值构造函数 | cv::Size2f sz(w, h); |
| 成员访问 | sz.width, sz.height; |
| 计算面积 | sz.area(); |
Size类不支持转换到固定向量类,但是固定向量类和Point类可以被转换成Size类
4.Rect类
矩形类包含Point类的成员x和y(矩形左上角)和Size类的成员width和height(代表矩形的大小)。
矩形类并不是从Point类或者Size()类继承过来的,所以并没有从它们中继承操作
Rect直接支持的操作:
| 操作 | 例子 |
|---|---|
| 默认构造函数 | cv::Rect r; |
| 拷贝构造函数 | cv::Rect r2(r1); |
| 值构造函数 | cv::Rect(x,y,w,h); |
| 由起始点和大小构造 | cv::Rect(p, sz);// 一个point和size |
| 由两个对角构造 |
cv::Rect(p1, p2); |
| 成员访问 | r.x, r.y, r.width, r.height; |
| 计算面积 | r.area(); |
| 提取左上角 | r.tl(); |
| 提取右下角 | r.br(); |
| 判断点p是否在矩形内 | r.contains(p); |
转换操作符和复制构造函数的目的是让cv::Rect能从旧的类型cv::CvRect转换。cv::Rect实际上是用整数实例化的一个矩形模板的别名。
cv::Rect也支持一些列的操作符(覆写),如下表:
| 操作 | 示例 |
|---|---|
| 矩形r1和举行r2的交集 | cv::Rect r3 = r1 & r2; r1 &= r2; |
| 同时包含矩形的r1和矩形r2的最小面积矩形 | cv::Rect r3 = r1 | r2; r1 |= r2; |
| 平移矩形r x个数量 | cv::Rect rx = r + x; r += x; |
| 扩大矩形r s个数量 | cv::Rect rs = r + s; r += s; |
| 比较矩形r1和矩形r2是否相等 | bool eq = (r1 == r2); |
|
比较矩形r1和r2是否不相等 | bool eq = (r1 != r2); |
5.RotatedRect类
cv::RotatedRect类是OpenCV中少数底层没有使用模板的C++接口类之一,它是包含一个中心点cv::Point2f,一个大小cv::Size2f和一个额外的角度float的容器。
其中浮点型的角度代表图像饶中心点旋转的角度。
RotatedRect和Rect有一个非常重要的不同点事前者是以中心点为原点的。,而Rect则位于左上角为原点。
RotatedRect支持的操作如下:
| 操作 | 示例 |
|---|---|
| 默认构造函数 | cv::RotatedRect rr(); |
| 复制构造函数 | cv::RotatedRect rr2(rr1); |
| 从两个点构造 | cv::RotatedRect(p1, p2); |
| 值构造函数,需要一个点,一个size和一个角度 | cv::RotatedRect(p, sz, theta); |
| 成员访问 | rr.center,rr.size,rr.rangle |
| 返回四个角的列表 | rr.point(pts[4]); |
6.固定矩阵类
固定矩阵类是为编译时就已知维度的矩阵打造的,因为它们内内部的所有数据都是在堆栈上分配的,所以分配和清除都很快。
固定矩阵类同时也是在OpenCV的C++接口中基本类型的核心。
固定向量类继承自固定矩阵类,而其他类的重要操作,要么是继承自固定向量类,要么是依赖于转换成固定向量类。
通常固定矩阵类是一个模板,这个模板是cv::Matx<>,但是独立的矩阵则通常通过别名分配,别名的基础形式是cv::Matx{1,2,...}{1,2...}{f,d},其中的数字可以是1到6之间的任何数。
要表示一个用来处理矩阵代数的矩阵的时候,就会用到矩阵类,如果是图像或者大型点列表这样的大数组,使用固定矩阵类就不是好选择了,应该使用cv::Mat。
固定矩阵类是在编译时就知道矩阵大小的时候用到的,比如相机矩阵
Matx支持的操作如下:
| 操作 | 示例 |
|---|---|
| 默认构造函数 | cv::Matx33f m33f;cv::Matx43d m43d; |
| 复制构造函数 | cv::Matx22d m22d(n22d); |
| 值构造函数 |
cv::Matx21f m(x0, x1); cv::Matx44d m(x0, x1, x2, x3, ..., x15); |
| 含相同元素的矩阵 | m33f = cv::Matx33f::all(x); |
| 全零矩阵 | m23d = cv::Matx23d::zeros(); |
| 全一矩阵 | m16f = cv:;Matx16f::ones(); |
| 创建一个单位矩阵 | m33f = cv::Matx33f::eye(): |
| 创建一个可以容纳另一个矩阵对角线的矩阵 | m31f = cv::Matx33f::diag(); |
| 创建一个均匀分布的矩阵 | m33f = cv::Matx33f::randu(min, max); |
| 创建一个正态分布的矩阵 | m33f = cv::Matx33f:nrandn(mean, variance); |
| 成员访问 | m(i, j), m(i); |
| 矩阵代数运算 | m1 = m0; m0 * m1; m0 + m1; m0 -m1; |
| 单例代数 | m * a, a * m, m / a; |
| 比较 | m1 == m2; m1 != m2; |
| 点积 | m1.dot(m2);m1.ddot(m2); |
| 改变矩阵形状 | m91f = m33f.reshape<9,1>(); |
| 变换操作符 | m44f = (Matx44f) m44d; |
| 提取(i,j)处的2*2子矩阵 | m44f.get_minor<2, 2>(i, j); |
| 提取第i行 | m14f = m44f.row(i); |
| 提取第j列 | m41f = m44.col(j); |
| 提取矩阵对角线 | m41f = m44f.diag(); |
| 计算转置 | n44f = m44f.t(); |
| 逆矩阵 | n44f = m44f.inv(method); |
| 解线性系统 |
m31f = m33f.solve(rhs31f, method); m32f = m33f.solve(rhs32f, method); |
| 每个元素的乘法 | m1.mul(m2); |
7.固定向量类
固定向量类就是从固定矩阵类派生而来的,它们只是为了更方便的使用cv::Matx<>。
在C++继承的意义上,固定向量模板cv::Vec是为列为1的cv::Matx<>。
Vec支持的操作为:
| 操作 | 示例 |
|---|---|
| 默认构造函数 | Vec2s v2s; Vec6f v6f; |
| 复制构造函数 | Vec3f u3f(v3f); |
| 值构造函数 | Vec2f v2f(x0, x1); Vec6d v6d(x0, x1, x2, x3, x4, x5); |
| 成员访问 | v4f[i]; v3w(j); |
| 向量叉乘 | v3f.cross(u3f); |
固定向量类的最主要的便利是它可以通过单个数索引各项,以及几个特定的额外的函数使常规矩阵运算有意义。
8.复数类
在OpenCV中还有一个应该包含在基础类型中的类,它就是复数类。OpenCV的复数类与STL中的复数类模板complex<>不一样,但是与之兼容可以互换。最大的区别在于成员获取。
在STL类中,虚部和实部通过成员函数real()和imag()和获取的,而在OpenCV中直接通过成员变量re和im获取。
OpenCV复数类支持的操作:
| 操作 | 示例 |
|---|---|
| 默认构造函数 | cv::Complexf z1; cv::Comlexd z2; |
| 复制构造函数 | cv::Complexf z2(z1); |
| 值构造函数 | cv::Complexd z1(re0); cv::Complexd(re0, im1_; |
| 复制构造函数 | cv::Complexd u2f(v2f); |
| 成员访问 | z1.re; z1.im; |
| 复共轭 | z2 = z1.conj(); |
与很多基本类型一样,复数类为重要的模板起了别名,cv::Complexf和cv::Complexd分别是单精度和双精度复数的别名.
本文介绍了OpenCV中的基础数据类型,包括Point、Scalar、Size、Rect、RotatedRect、固定矩阵类、固定向量类和复数类。每个类型都有其特定用途,如Point用于表示点,Scalar用于表示四维向量,Size表示尺寸,Rect表示矩形,RotatedRect表示旋转矩形,固定矩阵和向量类用于处理特定大小的矩阵,复数类则用于复数运算。这些类型提供了丰富的操作和支持,方便进行图像处理和计算机视觉任务。
169

被折叠的 条评论
为什么被折叠?



