OpenCV 用二进制位表示 type & channels 的方式
OpenCV 的类型与通道的表示方法。
OpenCV 的 type 共有 8 种,分别 Mat 中 element 应如何解析:
#define CV_8U 0
#define CV_8S 1
#define CV_16U 2
#define CV_16S 3
#define CV_32S 4
#define CV_32F 5
#define CV_64F 6
#define CV_USRTYPE1 7
但 OpenCV Mat::type() 的返回值的取值范围超过了 [0, 7],原因在于 type() 返回的类型包括通道数量(如CV_8UC3)。可以看到:
#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))
使用这个宏定义确定 type(),包括了 depth(数据类型)和 cn(通道信息)。而 CV_MAT_DEPTH 的计算如下:
#define CV_CN_SHIFT 3
#define CV_DEPTH_MAX (1 << CV_CN_SHIFT) // 1000
/*...*/
#define CV_MAT_DEPTH_MASK (CV_DEPTH_MAX - 1) // 0111
#define CV_MAT_DEPTH(flags) ((flags) & CV_MAT_DEPTH_MASK)
CV_MAT_DEPTH 作用是将二进制位高于 3 的部分全部置 0,确保 depth 的范围在 [0, 7]。
CV_MAKETYPE 中通道的计算,是将通道数减 1,然后左移 3 位,越过 depth 的范围。
channels() 和 type() 函数可分别参考:
https://github.com/opencv/opencv/blob/master/modules/core/src/matrix.cpp#L1971
https://github.com/opencv/opencv/blob/master/modules/core/src/matrix.cpp#L1898
会发现使用了一个宏 CV_MAT_CN,这个宏在:
https://github.com/opencv/opencv/blob/69f1d1ddffe03d2902ef8e4ce1a33e2d50fed734/modules/core/include/opencv2/core/cvdef.h#L407
CV_MAT_CN 的作用就是取高于 3 的位,右移 3 位,加 1。
总结
所以,以后可以自己口算数据类型。