1、 认识Mat
Mat是OpenCV中最核心的类,是Matrix的缩写,代表矩阵或者数组的意思,在头文件opencv2\core\core.hpp中声明。构造Mat相当于构造一个矩阵(数组),需要四个基本的要素:行(高)、列(宽)、通道数及数据类型,如下:
Mat(int rows,int cols,int type);
其中rows和cols分别代笔矩阵的行和列数,type代表类型,包括通道数及其数据类型,可以设置为:
CV_8UC(n),CV_8SC(n),CV_16SC(n),CV_16UC(n),CV_32SC(n),CV_32FC(n),CV_64FC(n)
对应着8U,8S,16S,16U,32S,32F,64F前面的数字代表Mat中每一个数值所占的bit数,1byte=8bit;
32F:4字节的float
64F:8字节的double
32S:4字节的int
8U :1字节的uchar
...
C(n)代表通道数,当n=1时,即构成单通道矩阵(二维矩阵),n>1时,构成多通道矩阵(三维矩阵),
直观上就是n个二维矩阵组成的三维矩阵,所以说:
单通道矩阵和二维ndarray等价,
多通道矩阵和三维ndarray是等价的,所以Mat的构造形式还可以为:
Mat (Size(int cols,int rows),int type);
Size(int cols,int rows)与Size(int x,int y)等价,
水平为x,竖直为y,零点为左上角。
2、Mat基本构造
OpenCV所有主要函数都或是cv::Mat类的成员,或是将cv::Mat作为参数,或是返回一个cv::Mat类型。cv::Mat 类型用于表示任意维度的稠密数组。“稠密”表示该数组的所有部分都有一个值,即使这个值是0,对于大多数图像来说,都是以稠密数组的形式存储的。与此同时相对的还有稀疏矩阵(spare array)。稀疏数组中只有非0的数值会被存储,从结论上来说,如果数组很多地方都是0,那么稀疏数组会非常节约内存。
cv::Mat类可以作为任意维度的数组使用,其数据可以看作是按照栅格扫描顺序存储的n维数组,这意味着在一维数组中,元素是按顺序排列的,而在一个二维数组中,数据按行组织,每一行也按顺序排列,对于三位数组来说,所有的通道都被行填充,每一个通道同样按顺序排列。
所有的矩阵都含有一个表示它所包含数组类型的元素flag,一个表示其维度的元素dims,分别表示行和列的数目的元素rows和cols(dims大于2时无效),一个指示数据真正存储的位置的data指针,以及一个表示该内存区域有多少个引用的refcount元素,类似于cv::Ptr<>的引用计数器,这个成员cv::Mat像智能指针一样管理内存区域。
创建一个数组,可以通过实例化变量cv::Mat来创建一个数组,通过这种方式船舰的数组没有大小和数据类型,之后也可以使用成员函数create()来申请一个内存区域,一个create的变体是通过指定行数列数以及数据类型来配置二维数组的规模。数组类型(type)决定了他含有什么样的元素。一个有效的数据类型需要同时指明数据的类型和通道数,所有的这些都在库的头文件中声明,包含CV_{8U,16S,16U,32S,32F,64F}C{1,2,3}的多种组合。
注意:OpenCV允许定义超过3通道的数据类型,但是为了创建它,需要调用函数CV_{8U,16S,16U,32S,32F,64F}C()。这些函数只有一个参数,表明通道数,所以CV_8UC(3)等效于CV_8UC3,但由于没有宏CV_8UC7,所以调用它,必须使用CV_8UC(7)。