OpenCV学习篇1:Mat类构造

简介

首先来看一下Mat类的源码简介:

The class Mat represents an n-dimensional dense numerical single-channel or multi-channel array. It
can be used to store real or complex-valued vectors and matrices, grayscale or color images, voxel
volumes, vector fields, point clouds, tensors, histograms (though, very high-dimensional histograms
may be better stored in a SparseMat ).

Mat类表示一个n维密集的单通道或多通道数列。它可以用来存储实数或复数向量和矩阵,灰度或彩色图像,卷积,向量场,点云,张量,直方图(不过,非常高维的直方图最好存储在SparseMat)。

由介绍可以看出,Mat类在OpenCV中本质上是一个存数字的矩阵类(matrix),扩展到应用场景上可以存储图像点云等,因为这些东西本质上就是矩阵。例如图像就是多通道的二维数组。

构造

首先一个类型最基础的就是如何构造。Mat类的构造函数有多达20多种。不一一列出,先列几个常用的,后续有接触再添加:

第一种:Mat(int _rows, int _cols, int _type)
最简单的矩阵构造,定义好行、列、数据类型。

Mat a(2, 3, CV_8UC1);
cout<<a<;

输出:

[  0,   0,   0;
   0,   0,   0]

这里说一下这个type。CV_8UC1这里从构造函数参数类型上来看,其本质就是一个int数,那这个CV_8UC1代表什么呢?
CV_[每元素占位数][带符号与否][类型前缀]C[通道数]
所以这里的CV_8UC1就代表每个元素为8位unsigned char 型,每个像素为1通道。

第二种:Mat(int _rows, int _cols, int _type, const Scalar& _s)
跟第一种相比就是增加了一个const Scalar&参数。此是一个可选的参数,用于初始化矩阵的每一个元素为特定值,这个是跟前面类型的通道数挂钩的,通道数为几个,它就是个几维的向量。

    Mat M(2, 2, CV_8UC3, Scalar(0, 125, 255));
    cout<

输出:

[  0,   125, 255,   0,   125, 255;
   0,   125, 255,   0,   125, 255]

第三种:Mat::Mat(Size _sz, int _type, const Scalar& _s)

    Size sz(2, 3);
    Mat MM(sz, CV_8UC3, Scalar(0, 125, 255));
    cout<<"sz="<

输出:

sz=
[  0, 125, 255,   0, 125, 255;
   0, 125, 255,   0, 125, 255;
   0, 125, 255,   0, 125, 255]

这中利用Size构造的方式在长宽上有点小绕,
首先看一下Size类型的构造:Size_(_Tp _width, _Tp _height); 可以看出Size的构造是宽*高。
再来看构造函数中具体实现:

{
    create(_sz.height, _sz.width, _type);
    *this = _s;
}

发现是用create函数创建的,再看create函数:

create(int _rows, int _cols, int _type){...}

由对应可发现,Size的宽被当做了列数、高被当做了行数。由于这种方式基本就是用来构造图像用的,所以:
Size的第一个参数宽,对应图像的横向宽度,
Size的第二个参数高,对应图像的纵向高度,
也易于直观理解,但是注意,这里跟矩阵的理解方式就不应样了,Size的两个参数并不是对应数出矩阵的行*列!从输出结果也可以看出,Size为2*3,输出矩阵其实是3行2列!

*第四种:**Mat(int _dims, const int _sz, int _type, const Scalar& _s){…}
这种方式主要用于创建3维和3维以上的矩阵:
_dims:指定维数
_sz:数组指针,此数组包含了每个维度的尺寸,注意,这不是Size类型的,而仅仅是个int数组指针。
后两个从参数就是数据类型和各元素初始值了。

    int size3[3] = {2, 2, 2};
    Mat a_3d_mat(3, size3, CV_8UC1, Scalar::all(0));
    //cout<

数组规定了三个维度的尺寸就是2*2*2的方块,数组长度一定要跟维度对应上。另外一个点就是超过2维的矩阵就不能用cout<<进行输出了,也就是代码中注释的一行如果打开是会报错的。

第五种:利用create()函数
create()函数也有好多重载,基本跟Mat类的构造差不多:

void create(int rows, int cols, int type);
void create(Size size, int type);
void create(int ndims, const int* sizes, int type);
...

create函数主要是用于创建Mat和赋值分开的情况:

    Mat a;
    a.create(2, 3, CV_8UC1);
    cout<<"a="<a<;

输出:

a=
[  0,   0,   0;
   0,   0,   0]

其余的重载create()用法也是一样的。

**第六种:**MATLAB形式初始化
有三种函数:zeros(),ones(),eye(),对应的分别是创建全0阵,全1阵,单位阵。

    Mat Z = Mat::zeros(2, 2, CV_8UC1);
    cout<<"Z="<O = Mat::ones(3, 3, CV_8UC1);
    cout<<"O="<O<E = Mat::eye(4, 4, CV_8UC1);
    cout<<"E="<E<

输出:

Z=
[  0,   0;
   0,   0]
O=
[  1,   1,   1;
   1,   1,   1;
   1,   1,   1]
E=
[  1,   0,   0,   0;
   0,   1,   0,   0;
   0,   0,   1,   0;
   0,   0,   0,   1]

第七种:小矩阵直接输入赋值
使用了Mat_类型模板类:Mat_(rows, cols)

    Mat c = (Mat_<int>(3, 3)<<0, 1, 2, 3, 4, 5, 6, 7, 8);
    cout<<"c="<

输出:

c=
[0, 1, 2;
 3, 4, 5;
 6, 7, 8]

以上基本就是看代码看到的用法,看源代码后面还有vector类型的构造方法,没有看了,碰到再总结吧,当然还有clone()和copyto()等函数也可以用于构造新的Mat,但是准备放在成员函数中再总结吧

你可能感兴趣的:(OpenCV学习,opencv)