**
OpenCV最重要的数据类型— Mat类总结
**
Mat类简介:cv::Mat是用于表示任意维度的稠密数组
Mat是按照栅格扫描顺序存储的n维数组
可以存储二维三维等多位数组并可以有多通道,即Mat的每个元素存多个数字
(有时数据并不按绝对顺序存储,原因是数据对齐)
创建方法
- 1.实例化(没有大小和数据类型),之后再通过create()函数来申请内存空间。
例:cv::Mat m;
m.create(3,10,CV_32FC3);//三行10列3通道的32位浮点数
m.setTo(cv::Scalar(1.0f,0.0f,1.0f));
//等效于cv::Mat m(3,10,CV_32FC3,cv::scalar(1.0f,0.0f,1.0f));
声明方式有CV_{8U,16S,16U,32S,32F,64F}C{1,2,3}
2。构造函数
cv::Mat(int ros,int cols,int type,(const Scalar&s));
指定类型的二维数组(Scalar为初始化值)
cv::Mat(int rows,int cols,int type,void* data,size_t step=AUTO_STEP)
利用size构造
cv::Mat(cv::Size sz,int type,(const Scalar&s));//Scalar 用于初始化
多维数组
cv::Mat(int ndims,const int* sizes,int type,(const Scalar&s));//指定类型的多维数组并可以初始化
-
2.复制构造函数
cv::Mat(const Mat&mat);
cv::Mat(const Mat&mat,const cv::Range&rows,cv::Range&cols);//只从指定行列中复制数据
cv::Mat(const Mat&mat,const cv::Rect&roi);只从感兴趣的区域中复制函数
cv::Mat(const Mat&mat,const cv::Range*ranges);服务于多维数组
cv::Mat(const cv::MatExpr&expr); -
3.模板类
cv::Mat( const cv::Vec<T,n>&vec,bool copyData=true );
cv::Mat( const cv::Matx<T,m,n>&vec,bool copyData=true );
cv::Mat( const std::vector<T,n>&vec,bool copyData=true ); -
4.静态方法
构造指定的矩阵
cv::Mat::zeros(rows,cols,type);
cv::Mat::ones(rows,cols,type);
cv::Mat::eye(rows,cols,type);
访问数组元素
- 利用模板实现
例:
cv::Mat m=cv::Mat::eye(10,10,32FC1);
printf( "Element (3,3) is %f\n",m.at<float>(3.3)
);
cv::Mat m=cv::Mat::eye(10,10,32FC2);
printf(
"Element (3,3) is (%f,%f)\n,
m.at<cv::Vec2f)(3.3)[0],
m.at<cv::Vec2f)(3.3)[1]);
利用模板访问Mat关键字at
M.at<int>(i);for int
M.at<float>(i,j);
M.at<int>(pt);//(pt.x,pt.y)
基于迭代器的访问
cv::MatConstIterator<>
cv::MatIterator<>
Example
int sz[3]={4,4,4};
Mat m(3,sz,CV_32FC3);
cv::randu(m,-1.0f,1.0f);
float maxs=0.0f,len2;
cv::MatConstIterator_<cv::Vec3f>it=m.begin<Vec3f>();
while(it!=m.end<Vec3f>()){
len2 =(*it)[0]*(*it)[0]+(*it)[1]*(*it)[1]+(*it)[2]*(*it)[2];
if(len2>maxs)maxs=len2;
it++;
}
NAryMatlterator
此迭代器要求被迭代的数组有相同的几何结构,会返回一堆以为数组进行迭代器操作,这种数组被称为面。
const int sz=5;
const int siz[]={sz,sz,sz};
Mat n_mat(3,siz,CV_32FC1);
RNG rng;
rng.fill(n_mat,RNG::UNIFORM,0.f,1.f);
const Mat* arrays[]={&n_mat,0};
Mat my_planes[1];
NAryMatIterator it(arrays,my_planes);
float s=0.f;
int n=0;
for(int p=0;p<it.nplanes;p++,++it)
{
s+=sum(it.planes[0])[0];
n++;
}
cout<<s<<endl;
按数据块访问
m.row();
m.col();
m.diag();
这两个函数用于访问数组中指定的行和列及对角,但需要注意的是,这个函数不会产生新的数组,而是对旧数组的引用。修改会修改旧数组的值。而且这些函数不适用于高维数组。
函数 | 描述 |
---|---|
m.row(i) | m中第i行 |
m.col(j) | m中第j列 |
m.rowRange(i0,i1) | m中i0~i1-1行 |
m.colRange(cv::Range(j0.j1)) | m中j0~j1-1行 |
m.diag(d) | 偏移量为d的对角线(上为正) |
m(Range(i0,i1),Range(j0,j1)) | 访问m中(i0,j0)到(i1-1,j1-1)所包含的数据 |
m(cv::Rect(i0,i1,w,h)) | 访问m中(i0,j0)到(i0+w-1,j0+h-1)所包含的数据 |
索引法 |