欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenCV Mat数据类型构造

程序员文章站 2022-05-16 11:23:37
...

Mat 的大致的数据结构可以理解为 ROW * COL 规模的矩阵,矩阵中的每个元素,是规格统一但不确定的数据元,统称为Scalar,而Scalar的格式大致为[a(,b,c,d)]这样的向量或者标量,向量的长度有时可以被理解为通道数,数据的具体类型有时可以被理解为深度,即该数占用多少比特来完成描述。


Mat(int rows, int cols, int type);

rows规定行数,cols规定列数
type可以使用一些预置的宏,如CV_8UC1,CV_64FC4
CV_8UC3 => CV_8U(nsigned)C(hannel)3 => 8位无符号整数 3通道
得到的就是一个rows * cols规模的矩阵,而矩阵中的每个元素,又是维数为3,每一维取值范围为0-255的向量
也可以使用约定的函数来直接构造可能需要的数据元类型
如CV_8UC(n),CV_64FC(n)


Size size(int rows, int cols);
Mat(Size size, int type);

应该可以理解,即将rows和cols结合在一起作为不可分割的消息传入构造


Scalar s(a); // s = [a]
Scalar s(a, b, c, d); // s = [a, b, c, d]
Mat(int rows, int cols, int type, const Scalar& s);

在原先的基础上,附加了一个参数 s ,用于将矩阵中所有的数据项初始化为特定的Scalar标量,由于数据项的深度和通道数都有可能不同,故Scalar需要符合前面type参数所规定的格式
上面补充了构建各类Scalar数据元的方法,由于采用了模板的概念,Scalar的定义方法比较灵活,直接向构造函数中传入1-4个(可能有误)符合深度要求(即数据类型)的数即可


Mat(int ndims, const int* sizes, int type);

指定该矩阵有ndims维,其中第1维长度为sizes[0],第二维长度为sizes[1] … ,且数据类型为type


Mat(const std::vector<int>& sizes, int type);

功能同上,由于vector可以动态获取有效长度,故少一个参数


Mat(int ndims, const int* sizes, int type, const Scalar& s);

其功能可以通过上面介绍过的函数组合推断得到


Mat(const std::vector<int>& sizes, int type, const Scalar& s);

其功能可以通过上面介绍过的函数组合推断得到


Mat(const Mat& m);

基于一个已有的Mat构造一个新的Mat,但是是一个浅拷贝,对构造出的Mat内的数据的变动会影响到原副本内的数据。建议使用Mat::clone()进行深拷贝。


Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);

由于Mat的本质数据是data指针所指向的数据集合,因此提供直接将符合条件的数据集直接分派给Mat对象进行格式化处理的手段。这里还涉及到一个可以缺省step参数,用于表明一行数据所占的实际比特数,用于应对给定data数据集中的一种情况,即每一行数据的尾部,都存在一些填充字节的情况。比如:
1 2 3 x x
4 5 6 x x
即保证对于这种情况能正确地连带着填充比特分离出每一行。
该构造方法的应用要求data指向的数据集合是连续存储的,而且该方法只是简单的将指针指向数据域,相当于一个引用,而没有创建实际的存储空间。


Mat(Size size, int type, void* data, size_t step=AUTO_STEP);

其功能可以通过上面介绍过的函数组合推断得到


Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0);

其功能可以通过上面介绍过的函数组合推断得到


Mat(const std::vector<int>& sizes, int type, void* data, const size_t* steps=0);

其功能可以通过上面介绍过的函数组合推断得到


Range r(int _start, int _end);
Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all());

从原矩阵中m,用行的范围和列的范围切分出一个子矩阵并送回,Range对象的定义较为方便。但是要注意这个子矩阵提取是以一种引用的方式实现的, 故会存在相互影响的情况


Rect roi(int x, int y, int xwidth, int yheight);
Mat(const Mat& m, const Rect& roi);

功能和上一个提到的相同,但是这个是采用一个描述长方形的对象Rect来描述切割的范围,Rect是Rect_模板类的一个特例,其一种较为直观的定义方式如上,采用x,y,width,height四个整数完成定义



还有若干基于template的构造函数,暂时不列举