• 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 );
  • 相关阅读:
    开放不应是唯一的价值观,互联网营销 狼人:
    什么是互联网产品的运营?,互联网营销 狼人:
    十年:邮箱,互联网营销 狼人:
    瘦客户端那些事 开篇,互联网营销 狼人:
    谈谈互动型网站中垃圾贴的应对方案,互联网营销 狼人:
    告诉你一个真实的中国互联网:精英与草根,互联网营销 狼人:
    从Google Wave和XML看软件复杂性之争,互联网营销 狼人:
    构建可伸缩高性能的互联网应用,互联网营销 狼人:
    注册接口使用StructureMap和Autofac等Ioc容器
    备份文件oracle 10g rman备份与恢复 之二
  • 原文地址:https://www.cnblogs.com/stemon/p/3836910.html
Copyright © 2020-2023  润新知