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 );
原文地址:https://www.cnblogs.com/stemon/p/3836910.html