opencv-flag

http://blog.csdn.net/yiyuehuan/article/details/43701797

在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所代表的意思,以及与其相关的一些成员变量或成员函数的求值和实现。

原文地址:https://www.cnblogs.com/jiahenhe2/p/7902606.html