OpenCV中的数据类型可分为三类,而前两类(基础数据类型和辅助对象)在前面已进行详细讲述,下面将对最后一种——大型数组类型进行讲解。
大型数据类型中最重要的当属cv::Mat,这可谓是OpenCV的核心,所有主要函数几乎都和其相关。cv::Mat类用于表示任意维度的稠密数组。所谓“稠密”表示该数组的所有部分都有一个值存储,即使这个值为0。而和其相对的就是稀疏数组cv::SparseMat,稀疏数组中只有非0的数值会被存储,在数组存在很多0的时候,稀疏数组将非常节约内存;但是在数组比较稠密的时候,稀疏数组反而会浪费大量的内存。
cv::Mat类N维稠密矩阵
实际上cv::Mat由一个头部和一个数据块组成,头部包含了数组的相关信息(大小,数据类型,通道数等),数据块包含了图像中所有像素的值。头部还一个指向数据块的指针和一个引用计数器,即data属性和refcount属性。
创建一个数组
不拷贝数据的操作称为“浅拷贝”,只是复制了头部;如果拷贝了数据的操作叫“深拷贝”,这种操作会创建空间并拷贝对方的数据。
type的形式为CV_{8U, 16S, 16U, 32S, 32F, 64F}C{1, 2, 3},其中8,16,32,64指的是位数,U,S,F表示字符、整型和浮点型,1,2,3表示通道数。
构造 | 描述 |
---|---|
cv::Mat; | 默认构造函数 |
cv::Mat( int rows, int cols, int type ); | 指定类型的二维数组 |
cv::Mat(int rows, int cols, int type,const Scalar& s); | 指定类型的二维数组,并指定初始化值 |
cv::Mat(int rows, int cols, int type,void* data, size_t step=AUTO_STEP); | 指定类型的二维数组,并指定预先存储的数据 |
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_t step=AUTO_STEP); | 指定类型的二维数组,并指定预先存储的数据(大小由sz指定) |
cv::Mat(int ndims, const int* sizes,int type); | 指定类型的多维数组 |
cv::Mat(int ndims, const int* sizes,int type, const Scalar& s); | 指定类型的多维数组,并指定初始化值 |
cv::Mat(int ndims, const int* sizes,int type, void* data,size_t step=AUTO_STEP); | 指定类型的多维数组,并指定预先存储的数据 |
注:cv::Size传入参数是先cols后rows的。
构造 | 描述 |
---|---|
cv::Mat( const Mat& mat ); | 复制构造函数 |
cv::Mat(const Mat& mat,const cv::Range& rows,const cv::Range& cols); | 只从指定的行列中复制数据的复制构造函数(只对二维有效) |
cv::Mat(const Mat& mat,const cv::Rect& roi); | 只从感兴趣的区域中复制数据的复制构造函数(只对二维有效) |
cv::Mat(const Mat& mat,const cv::Range* ranges); | 服务于n维数组的,从泛化的感兴趣的区域中复制数据的复制构造函数 |
cv::Mat( const cv::MatExpr& expr ); | 从其他矩阵的线性代数表述中生成新矩阵的复制构造函数 |
构造 | 描述 |
---|---|
cv::Mat(const cv::Vec& vec,bool copyData=true); | 构造一个如同cv::Vec所指定的数据类型为T、大小为n的一维数组 |
cv::Mat(const cv::Matx& vec,bool copyData=true); | 构造一个如同cv::Vec所指定的数据类型为T、大小为 m × n的二维数组 |
cv::Mat(const std::vector& vec,bool copyData=true); | 构造STL的vector所指定的数据类型为T、大小为vector元素数的一维数组 |
cv::Mat::zeros( rows, cols, type ); | 构造一个大小为rows × cols、数据类型为type指定类型的、值全为0的矩阵 |
cv::Mat::ones( rows, cols, type ); | 构造一个大小为rows × cols、数据类型为type指定类型的、值全为1的矩阵 |
cv::Mat::eye( rows, cols, type ); | 构造一个大小为rows × cols、数据类型为type指定类型的单位矩阵 |
注:使用cv::Mat::ones和cv::Mat::eye时,如果要求创建的是一个多维数组,就只有第一通道会被设置为1,其余通道保持为0。
独立获取数组元素
OpenCV有几种不同的访问数组的方法。
① 通过模板函数at<>()实现
例:单通道
cv::Mat m = cv::Mat::eye( 10, 10, CV_32FC1 );
printf("element (3, 3) is %f\n", m.at<floa