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标识符的内存图:

网友评论