在Mat类中定义了这样一个成员变量:
/*! includes several bit-fields:
- the magic signature
- continuity flag
- depth
- number of channels
*/
int flags;
从flags的注释来看,这个变量应该是用来作为标志的。主要包含magic signature、submat flag、continuity flag、number of channels、depth。
从定义可以看出flags是int类型,共占32位,结合上图可以看出各位所代表的意思。
从低位到高位:
0-2位代表depth即数据类型(如CV_8U),OpenCV的数据类型共7类,故只需3位即可全部表示。
3-11位代表通道数channels,因为OpenCV默认最大通道数为512,故只需要9位即可全部表示,可参照下面求通道数的部分。
0-11位共同代表type即通道数和数据类型(如CV_8UC3)
12-13位暂没发现用处,也许是留着后用,待发现了再补上。
14位代表Mat的内存是否连续,一般由creat创建的mat均是连续的,如果是连续,将加快对数据的访问。
15位代表该Mat是否为某一个Mat的submatrix,一般通过ROI以及row()、col()、rowRange()、colRange()等得到的mat均为submatrix。
16-31代表magic signature,暂理解为用来区分Mat的类型,如果Mat和SparseMat
上面对flags中的信息作了剖析,接下来看获取这些信息的函数或方法:
获得depth:
inline int Mat::depth() const { return CV_MAT_DEPTH(flags); }
可以看出获取depth,实际是通过宏定义CV_MAT_DEPTH来实现的,该宏定义实际上就是取flags的0-2位来计算depth的。看看与这个宏定义相关的内容:
#define CV_CN_SHIFT 3
#define CV_DEPTH_MAX (1 << CV_CN_SHIFT)
#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
#define CV_MAT_DEPTH_MASK (CV_DEPTH_MAX - 1)
#define CV_MAT_DEPTH(flags) ((flags) & CV_MAT_DEPTH_MASK)
获取channels:
inline int Mat::channels() const { return CV_MAT_CN(flags); }
可以看出获取channels也是宏定义来实现,该宏定义为CV_MAT_CN,作用是取flags的3-11位,然后计算通道数。相关内容:
#define CV_CN_MAX 512
#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)
CV_CN_MAX - 1将通道的可能值变为[0,511],这样就能够用9位来表示所有的可能值。左移CV_CN_SHIFT(=3)位,是为了在&运算时排除depth所在位的影响。
获取type:
inline int Mat::type() const { return CV_MAT_TYPE(flags); }
计算type用到了宏定义CV_MAT_TYPE,相关内容:
#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))
#define CV_MAKE_TYPE CV_MAKETYPE
// 具体类型太多,不一一列出了
#define CV_MAT_TYPE_MASK (CV_DEPTH_MAX*CV_CN_MAX - 1)
#define CV_MAT_TYPE(flags) ((flags) & CV_MAT_TYPE_MASK)
是否Continuous:
inline bool Mat::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; }
也可以通过宏定义来实现:
#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
是否submatrix:
inline bool Mat::isSubmatrix() const { return (flags & SUBMATRIX_FLAG) != 0; }
对应的宏定义:
#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)
上面主要是分析了flags所代表的意思,以及与其相关的一些成员变量或成员函数的求值和实现。