美文网首页
OpenCV源码分析(二):基本数据类型

OpenCV源码分析(二):基本数据类型

作者: 奔向火星005 | 来源:发表于2018-12-07 18:07 被阅读0次

OpenCV内使用宏定义了各种数据类型,在代码中随处可见,在此简单介绍一下。

原始类型的宏定义

//原始类型
#define CV_8U   0     //unsigned char
#define CV_8S   1     //unsigned char
#define CV_16U  2     //unsigned short
#define CV_16S  3     //short
#define CV_32S  4     //32位有符号整型(不一定是int)
#define CV_32F  5     //32位浮点型
#define CV_64F  6     //64位浮点型
#define CV_USRTYPE1 7

矩阵Mat相关的类型

#define CV_CN_MAX     512  //通道数最大值
#define CV_CN_SHIFT   3     //通道数偏移值
#define CV_DEPTH_MAX  (1 << CV_CN_SHIFT)  //深度最大值

#define CV_MAT_DEPTH_MASK       (CV_DEPTH_MAX - 1)  //深度值掩码
#define CV_MAT_DEPTH(flags)     ((flags) & CV_MAT_DEPTH_MASK)

//深度值和通道数,一起组成TYPE
#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))  
#define CV_MAKE_TYPE CV_MAKETYPE

//TPYE
#define CV_8UC1 CV_MAKETYPE(CV_8U,1)  //0
#define CV_8UC2 CV_MAKETYPE(CV_8U,2)  //8
#define CV_8UC3 CV_MAKETYPE(CV_8U,3)  //16
#define CV_8UC4 CV_MAKETYPE(CV_8U,4)  //24
#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))

#define CV_8SC1 CV_MAKETYPE(CV_8S,1)  //1
#define CV_8SC2 CV_MAKETYPE(CV_8S,2)  //9
#define CV_8SC3 CV_MAKETYPE(CV_8S,3)  //17
#define CV_8SC4 CV_MAKETYPE(CV_8S,4)  //25
#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n))

#define CV_16UC1 CV_MAKETYPE(CV_16U,1)  //2
#define CV_16UC2 CV_MAKETYPE(CV_16U,2)  //10
#define CV_16UC3 CV_MAKETYPE(CV_16U,3)  //18
#define CV_16UC4 CV_MAKETYPE(CV_16U,4)  //26
#define CV_16UC(n) CV_MAKETYPE(CV_16U,(n))

#define CV_16SC1 CV_MAKETYPE(CV_16S,1)  //3
#define CV_16SC2 CV_MAKETYPE(CV_16S,2)  //11
#define CV_16SC3 CV_MAKETYPE(CV_16S,3)  //19
#define CV_16SC4 CV_MAKETYPE(CV_16S,4)  //27
#define CV_16SC(n) CV_MAKETYPE(CV_16S,(n))

#define CV_32SC1 CV_MAKETYPE(CV_32S,1)  //4
#define CV_32SC2 CV_MAKETYPE(CV_32S,2)  //12
#define CV_32SC3 CV_MAKETYPE(CV_32S,3)  //20
#define CV_32SC4 CV_MAKETYPE(CV_32S,4)  //28
#define CV_32SC(n) CV_MAKETYPE(CV_32S,(n))

#define CV_32FC1 CV_MAKETYPE(CV_32F,1)  //5
#define CV_32FC2 CV_MAKETYPE(CV_32F,2)  //13
#define CV_32FC3 CV_MAKETYPE(CV_32F,3)  //21
#define CV_32FC4 CV_MAKETYPE(CV_32F,4)  //29
#define CV_32FC(n) CV_MAKETYPE(CV_32F,(n))

#define CV_64FC1 CV_MAKETYPE(CV_64F,1)  //6
#define CV_64FC2 CV_MAKETYPE(CV_64F,2)  //14
#define CV_64FC3 CV_MAKETYPE(CV_64F,3)  //22
#define CV_64FC4 CV_MAKETYPE(CV_64F,4)  //30
#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n))

从上面TYPE的组合可以看出,OpenCV中,深度和原始类型是同一个意思,如宏定义#define CV_8UC1 CV_MAKETYPE(CV_8U,1),CV_8UC1是由原始类型CV_8U和通道数1组成,而#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT)) ;在CV_MAKETYPE宏定义的depth参数位置,输入的是CV_8U。

在OpenCV中,用的最多的类无疑是Mat,它的父类是InputArray,在InputArray内有一个flags成员变量,他是一个标识符,标记了它所属的对象的真实类型以及存储数据的类型和信息,InputArray类的简化版如下:

class CV_EXPORTS _InputArray
{
public:
    enum {
        KIND_SHIFT = 16,       //KIND信息的偏移值
        FIXED_TYPE = 0x8000 << KIND_SHIFT,
        FIXED_SIZE = 0x4000 << KIND_SHIFT,
        KIND_MASK = 31 << KIND_SHIFT,

        //下面都是InputArray的子类
        NONE              = 0 << KIND_SHIFT,    
        MAT               = 1 << KIND_SHIFT,
        MATX              = 2 << KIND_SHIFT,
        STD_VECTOR        = 3 << KIND_SHIFT,
        STD_VECTOR_VECTOR = 4 << KIND_SHIFT,
        STD_VECTOR_MAT    = 5 << KIND_SHIFT,
        EXPR              = 6 << KIND_SHIFT,
        OPENGL_BUFFER     = 7 << KIND_SHIFT,
        CUDA_HOST_MEM     = 8 << KIND_SHIFT,
        CUDA_GPU_MAT      = 9 << KIND_SHIFT,
        UMAT              =10 << KIND_SHIFT,
        STD_VECTOR_UMAT   =11 << KIND_SHIFT,
        STD_BOOL_VECTOR   =12 << KIND_SHIFT,
        STD_VECTOR_CUDA_GPU_MAT = 13 << KIND_SHIFT,
        STD_ARRAY         =14 << KIND_SHIFT,
        STD_ARRAY_MAT     =15 << KIND_SHIFT
    };

int kind() const {
        return flags & KIND_MASK;
}    //

//略去一堆....

protected:
    int flags;    //用flags判断对象的真实类型
    void* obj;   //指向真实对象

    //略去一堆....
};

再看下Mat相关的类型的宏定义,

/****************************************************************************************\
*                                  Matrix type (Mat)                                     *
\****************************************************************************************/
//通道数
#define CV_MAT_CN_MASK          ((CV_CN_MAX - 1) << CV_CN_SHIFT)
#define CV_MAT_CN(flags)        ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)
//TYPE, 和最上面的TPYE一样,由深度值和通道数组合成TPYE
#define CV_MAT_TYPE_MASK        (CV_DEPTH_MAX*CV_CN_MAX - 1)
#define CV_MAT_TYPE(flags)      ((flags) & CV_MAT_TYPE_MASK)

//矩阵内存是否连续
#define CV_MAT_CONT_FLAG_SHIFT  14
#define CV_MAT_CONT_FLAG        (1 << CV_MAT_CONT_FLAG_SHIFT)
#define CV_IS_MAT_CONT(flags)   ((flags) & CV_MAT_CONT_FLAG)
#define CV_IS_CONT_MAT          CV_IS_MAT_CONT

//是否是子矩阵?
#define CV_SUBMAT_FLAG_SHIFT    15
#define CV_SUBMAT_FLAG          (1 << CV_SUBMAT_FLAG_SHIFT)
#define CV_IS_SUBMAT(flags)     ((flags) & CV_MAT_SUBMAT_FLAG)

还有矩阵看访问权限的宏定义

enum { ACCESS_READ=1<<24, ACCESS_WRITE=1<<25,
    ACCESS_RW=3<<24, ACCESS_MASK=ACCESS_RW, ACCESS_FAST=1<<26 };

最后看一下Mat中flag标识符的内存图:


相关文章

网友评论

      本文标题:OpenCV源码分析(二):基本数据类型

      本文链接:https://www.haomeiwen.com/subject/opxxhqtx.html