OpenCV 用二进制位表示 type & channels 的方式

OpenCV 的类型与通道的表示方法。

参考文件 https://github.com/opencv/opencv/blob/05b15943d6a42c99e5f921b7dbaa8323f3c042c6/modules/core/include/opencv2/core/hal/interface.h

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。

总结

所以,以后可以自己口算数据类型。

posted @ 2017-03-20 14:57  JingeTU  阅读(805)  评论(0编辑  收藏  举报