第四章 OpenCv的数据类型

第四章 OpenCv的数据类型

1 直接从C++继承来的基础数据类型

本质:这类数据类型直接从C++原语中继承而来,仅仅是稍加修饰,如int、float、及简单数组和矩阵,同时也有一些代表简单几何概念的数据类型,如点、矩形、大小等。
OpenCv中6种基本数据类型缩写:
b = unsigned char
w = unsigned short
s = short
i = int
f = float
d = double

  • cv::Vec<>类

本质:固定向量容器,即定义时必须制定其大小,通过下标i访问。
用法:对于2到6维的6种数据类型的任何组合都是有效的。虽然Vec<>可以包含其他类对象,但是opencv中一般只用作一个C语言原语的类型的容器。且仅用于少数量的元素。
Opencv中的常用别名:

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;
  • cv::Matx<>类

本质:固定矩阵类,通过下标(i,j)访问。
用法:用于一些特定的小型固定矩阵,支持矩阵的操作。
Opencv中的常用别名

typedef Matx<float, 1, 2> Matx12f;
typedef Matx<double, 1, 2> Matx12d;
typedef Matx<float, 1, 3> Matx13f;
typedef Matx<double, 1, 3> Matx13d;
typedef Matx<float, 1, 4> Matx14f;
typedef Matx<double, 1, 4> Matx14d;
typedef Matx<float, 1, 6> Matx16f;
typedef Matx<double, 1, 6> Matx16d;

typedef Matx<float, 2, 1> Matx21f;
typedef Matx<double, 2, 1> Matx21d;
typedef Matx<float, 3, 1> Matx31f;
typedef Matx<double, 3, 1> Matx31d;
typedef Matx<float, 4, 1> Matx41f;
typedef Matx<double, 4, 1> Matx41d;
typedef Matx<float, 6, 1> Matx61f;
typedef Matx<double, 6, 1> Matx61d;

typedef Matx<float, 2, 2> Matx22f;
typedef Matx<double, 2, 2> Matx22d;
typedef Matx<float, 2, 3> Matx23f;
typedef Matx<double, 2, 3> Matx23d;
typedef Matx<float, 3, 2> Matx32f;
typedef Matx<double, 3, 2> Matx32d;

typedef Matx<float, 3, 3> Matx33f;
typedef Matx<double, 3, 3> Matx33d;

typedef Matx<float, 3, 4> Matx34f;
typedef Matx<double, 3, 4> Matx34d;
typedef Matx<float, 4, 3> Matx43f;
typedef Matx<double, 4, 3> Matx43d;

typedef Matx<float, 4, 4> Matx44f;
typedef Matx<double, 4, 4> Matx44d;
typedef Matx<float, 6, 6> Matx66f;
typedef Matx<double, 6, 6> Matx66d;
  • cv::Point类

本质:类似于固定向量类,但仅用来表示一个点。
用法:一般用来表示二维点或者三维点,通过成员变量访问元素,而不是下标。
Opencv中的常用别名

typedef Point_<int> Point2i;
typedef Point_<int64> Point2l;
typedef Point_<float> Point2f;
typedef Point_<double> Point2d;
typedef Point3_<int> Point3i;
typedef Point3_<float> Point3f;
typedef Point3_<double> Point3d;
  • cv::Scalar类

本质:一个四维Point类。通过下标访问访问。

  • cv::Size类

本质:与point类似,表示区域的大小,拥有width和height。
Opencv中的常用别名

typedef Size_<int> Size2i;
typedef Size_<int64> Size2l;
typedef Size_<float> Size2f;
typedef Size_<double> Size2d;
typedef Size2i Size;
  • cv::Rect类

本质:顾名思义,表示一个矩形。
非对称矩形:cv::RotateRect。

  • cv::Complex类

本质:复数类,实部通过re获取,虚部通过im获取。
Opencv中的常用别名

typedef Complex<float> Complexf;
typedef Complex<double> Complexd;

2 辅助对象类型

  • cv::TermCriteria类

本质:一个终止条件检测类。集成了迭代次数和误差参数。

  • cv::Range类

本质:一个连续的整数序列,两个重要元素start和end。范围包含初始值start但不包含终止值end。

  • cv::ptr智能指针

本质:与C++只能指针类似。

  • cv::InputArray和cv::OutputArray类

本质:数组的封装,可以表示任何数组,常用于函数的传人参数和返回参数。前者为常量数组。

3 工具函数

函数名称 描述
Cv::alignPtr() 对齐指针到给点字节数
Cv::alignSize() 将缓冲区大小与给定的字节数对齐
Cv::allocate() 分配一个C风格的数组对象
cvCeil() 浮点数向上取整
Cv::cubeRoot() 计算一个数的立方根
Cv::CV_Assert() 如果给定的条件不为真,则抛出异常
CV_Error() 构造cv::Exception(从固定的字符串)并抛出异常的一个宏
CV_Error_() 构造cv::Exception(从格式化字符串)并抛出异常的一个宏
Cv::deallocate() 释放一个c风格的数组对象
Cv::error() 指示错误并抛出异常
Cv::fastAtan2() 向量的二维角度的计算
Cv::fastFree() 释放一个内存缓存区
Cv::fastMalloc() 分配一个对齐的内存缓存区
cvFloor() 浮点数向下取整
Cv::format() 以sprintf类似格式创建一个STL字符串
Cv::getCPUTickCount() 以内部CPU计时器获得tick计数
Cv::getNumThreads() 获得当前OpenCv使用的线程数
Cv::getOptimalDFTSize() 计算要传递给cv::DFT()的数组的最适合大小
Cv::getThreadNum() 获得当前线程的索引
Cv::getTickFrequency () 获得系统每秒的tick计数
Cv::getTickCount() 获得系统的tick计数
cvIsInf() 判断一个浮点数是否无穷
cvIsNaN() 判断一个浮点数是否不是一个数
cvRound() 近似一个浮点数到最近整数
Cv::setNumThreads() 设定OpenCv使用的线程数
Cv::setUseOptimized() 开启或关闭优化代码
Cv:useOptimized() 指示代码优化的启用

4 图像和大型数组类型

Cv::Mat类用于表示任意维度的稠密数组。
稠密:表示该数组的所有部分都有一个值存储,即使这个值是0。
稀疏:表示只有非0的数组会被存储。
Mat理解:它仅仅是数据实体的头,是对数据的描述,并不代表实际数据本身。

4.1 Mat的构造

Mat的非复制构造函数

Mat(int rows, int cols, int type);
指定类型的二维数组,type取值为:CV_{8U,16S,16U,32S,32F,64F}C{1,2,3}的多种组合。

Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);
指定类型的二维数组,并指定预先存储的数据。

Mat(Size size, int type);
指定类型的二维数组,大小由Sz指定。

Mat(int rows, int cols, int type, const Scalar& s);
指定类型的二维数组,并指定初始化值。

Mat(Size size, int type, void* data, size_t step=AUTO_STEP);
指定类型的二维数组,并指定预先存储的数据。

Mat(int ndims, const int* sizes, int type);
指定类型的多维数组。

Mat(int ndims, const int* sizes, int type, const Scalar& s);
指定类型的多维数组,并指定初始化值。

Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0);
指定类型的多维数组,并指定预先存储的数据。

Mat的复制构造函数

Mat(const Mat& m);
Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all());
只从指定的行列中复制数据的复制构造函数。

Mat(const Mat& m, const Rect& roi);
只从感兴趣的区域中复制数据的复制构造函数。
Mat(const Mat& m, const Range* ranges);
服务于n维数组的,从泛化的感兴趣区域中复制数据的复制构造函数。
构造Mat的静态方法
static MatExpr zeros(int rows, int cols, int type);
构造指定大小的0矩阵。
static MatExpr ones(int rows, int cols, int type);
构造指定大小的全1矩阵。
static MatExpr eyes(int rows, int cols, int type);
构造指定大小的单位矩阵。

4.2 Mat独立获取数组元素

Mat访问一个元素主要有两种方法:位置和迭代器。

4.2.1 位置访问

直接访问通过模板函数at<>()来实现。
本质:先将at<>()特化到矩阵所包含的数据类型,然后使用得到的数据类型的行和列位置访问该元素。
通过位置访问元素最快的方式:获取某一行的指针。
mtx.ptr(3) 获取指向第三行第一个元素的指针。
注意:Mat中的数据按行组织的,行于行之间有可能是连续的,可有使用isContinuous()进行判断。
示例:

Mat type(2, 2, CV_8UC3);
type.at<Vec3b>(0, 1)[0] = 1;
type.at<Vec3b>(0, 1)[1] = 2;
type.at<Vec3b>(0, 1)[2] = 3;
std::cout << type;

// 取得某一行的指针
Ptr<Vec3b> p = type.ptr<Vec3b>(0);
p[1][0] = 4;
p[1][1] = 5;
p[1][2] = 6;

std::cout << std::endl;
std::cout << type;

4.2.2 迭代器访问

Mat I(2, 2, CV_8UC3);
MatIterator_<Vec3b> it, end;
for (it = I.begin<Vec3b>(), end = I.end<Vec3b>(); it != end; ++it)
{
	(*it)[0] = 1;
	(*it)[1] = 2;
	(*it)[2] = 3;
}

4.3 通过块访问数组元素

通过制定行、制定列、制定行范围、制定列范围、制定Range范围来获得制定的块元素。返回值同样是Mat。

4.4 Mat其他重要的函数成员

m1 = m0.clone() 从m0进行完全复制
m0.copyTo(m1) 将m0复制给m
m0.convertTo(m1, type, scale,offset) 转换m0中的数据元素
m0.setTo(s, mask) 设置m0所有元素为s,如果存在mask,则只对制定区域置值
m0.total() 计算数组元素数量(不包含通道)
m0.isContinuous() 判断数组是否连续
m0.type() 返回m0元素的类型
m0.depth() 返回m0通道中的元素类型
m0.channels() 返回m0的通道数目
m0.size() size返回m0的大小

5 总结

本章主要介绍了OPenCv中的一些基本数据类型和其使用方法,重点介绍了核心数据类型Mat,同时还介绍了一些常用的工具函数。

猜你喜欢

转载自blog.csdn.net/a369189453/article/details/85238074