使用 OpenCV 的过程中,经常会需要调用 Mat::type() 来查看一个矩阵的类型,但类型值是一个数字,往往难以理解其具体含义。
矩阵类型有两个构成部分:深度(矩阵每个元素的数据类型)和通道数(矩阵每个像素包含多少个元素)。比如 CV_32SC3
,是由深度 CV_32S
(32位有符号整型) 和通道数 3
构成。
参见 OpenCV 头文件 opencv2\core\hal\interface.h
,首先有 8 个基础类型(深度):
#define CV_8U 0 // 8位无符号,uchar
#define CV_8S 1 // 8位有符号,char
#define CV_16U 2 // 16位无符号,unsigned short
#define CV_16S 3 // 16位有符号,short
#define CV_32S 4 // 32位有符号,int
#define CV_32F 5 // 32位浮点,float
#define CV_64F 6 // 64位浮点,double
#define CV_USRTYPE1 7 // 用户自定义类型
然后根据深度和通道数构建类型码:
#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) // 确保深度码在 0~7 之间
#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))
#define CV_MAKE_TYPE CV_MAKETYPE
其中 CV_MAKETYPE(depth, cn)
就是用来构建类型码的宏定义,从代码可以看到:
因此,只需记住 8 个基础的深度码,就可以很容易地推算类型码的具体含义了。比如对于类型码 10
,将其除 8 加 1 得到通道数 2,取余数得到类型码 2,即 CV_16U
。