OpenCV学习(3)--Mat矩阵的操作
CvMat的矩阵结构
1 typedef struct CvMat 2 { 3 //矩阵中元素的类型 4 int type; 5 //行数据长度 6 int step; 7 8 /* for internal use only */ 9 int* refcount; 10 int hdr_refcount; 11 12 //指向数据的指针 13 union 14 { 15 uchar* ptr; 16 short* s; 17 int* i; 18 float* fl; 19 double* db; 20 } data; 21 22 #ifdef __cplusplus 23 //矩阵的行数 24 union 25 { 26 int rows; 27 int height; 28 }; 29 //矩阵的列数 30 union 31 { 32 int cols; 33 int width; 34 }; 35 #else 36 int rows; 37 int cols; 38 #endif 39 40 } 41 CvMat;
矩阵的type的预定义类型为:CV_<bit_depth>(S|U|F)C(number_of_channels)。所以矩阵的元素可以是32位浮点型数据(CV_32FC1),或者是无符号的8位三元组的整型数据(CV_8UC3),一个CvMat的元素不一定就是个单一的数字,一般更可能是一个向量。
行数据长度step用字节表示而不是整型或者浮点型长度。
但是这个type在对Mat初始化以后,会通过一个宏把它装换成一个数值:
1 #define CV_32FC1 CV_MAKETYPE(CV_32F,1) 2 #define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))
下面说一下创建矩阵的方法:
创建一个矩阵方法一:
1 /* Allocates and initializes CvMat header and allocates data */ 2 CVAPI(CvMat*) cvCreateMat( int rows, int cols, int type );
指向数据部分的指针有各种类型的,但是他们的起始地址是一样的。
创建矩阵的方法二:
创建CvMat结构体,但是不分配内存
1 /* Allocates and initalizes CvMat header */ 2 CVAPI(CvMat*) cvCreateMatHeader( int rows, int cols, int type );
分配数据所需要的内存
1 /* Allocates array data */ 2 CVAPI(void) cvCreateData( CvArr* arr );
创建矩阵方法三:
克隆矩阵
1 /* Creates an exact copy of the input matrix (except, may be, step value) */ 2 CVAPI(CvMat*) cvCloneMat( const CvMat* mat );
该函数根据现有的矩阵克隆一个新的矩阵,分配独立的内存空间,需要使用单独的cvReleaseMat函数释放内存空间。
创建矩阵方法四:
在已有的CvMat结构体上初始化矩阵,这样的结果是数组和矩阵的数据部分有相同的内存空间。
1 /* Initializes CvMat header */ 2 CVAPI(CvMat*) cvInitMatHeader( CvMat* mat, int rows, int cols, 3 int type, void* data CV_DEFAULT(NULL), 4 int step CV_DEFAULT(CV_AUTOSTEP) );
注意这个函数的第一个参数,一定要是初始化的结构体,不能只是一个空指针,所以可以这样用:
1 CvMat pMat; 2 float data[4] = {3,4,5,7}; 3 4 cvInitMatHeader(&pMat, 2, 2, CV_32FC1, data);
但是不可以这样:
1 CvMat* pMat; 2 float data[4] = {3,4,5,7}; 3 4 cvInitMatHeader(pMat, 2, 2, CV_32FC1, data);
因为pMat是一个没有初始化的指针。
有关CvMat数据内存空间的释放:
上面的着三种方式的数据内存都是开辟在堆内存中的,所以要释放占用的内存。
1 /* Releases CvMat header and deallocates matrix data 2 (reference counting is used for data) */ 3 CVAPI(void) cvReleaseMat( CvMat** mat );