opencv矩阵元素类型

来源:互联网 发布:淘宝最近生意不好 编辑:程序博客网 时间:2024/06/01 08:37

基础

1 位移操作

移位操作有两种类型,一种是逻辑移位(logical shift)和算术移位(arithmetic shift)。逻辑移位中被移出的位被丢弃,空缺位(variant bit)0填充。算术移位中移出位被丢弃,空缺位用符号位填充。

c/c++中,整数分为有符号和无符号两种类型,它们的移位操作有所区别。对于无符号整数,左移右移均采用逻辑移位;对于有符号整数,右移使用算术移位,左移使用逻辑移位。

所以对于有符号整数的右移,并不会改变整数的正负,但是左移中却有可能会改变。

 

2 负数存储

在机器里,有符号的整数的存储,对于负整数来说,它是用补码存储的,这里需要知道原码,反码和补码。原码指的本来的数据,反码则是对原码按位取反,补码则是对原码取反后加1,即补码=反码+1

以占两个字节长度的数据为例,它的取值范围是-32768-32767

1000 0000 0000 0000(原码) --->0111 1111 1111 1111(反码)-->1000 0000 0000 0000(补码)

该补码的值是32768,因为它本来是负值,所以1000 0000 0000 0000(原码)表示的值即为-32768

1111 1111 1111 1111(原码)--->0000 0000 0000 0000(反码)-->0000 0000 0000 0001(补码),所以这里原码表示的值是-1

 

opencv矩阵元素类型

1 CV_MAKETYPE

创建矩阵的时候,有几个函数,下面是其中的

CvMat cvMat(introws,intcols, inttype,void*dataCV_DEFAULT(NULL))

cvCreateMat( intheight,intwidth,int type )

从这些函数可以看出,第三个参数type用来确定矩阵的类型,它是int类型的,在当前的32位程序中,它占4个字节。矩阵元素类型包括了两部分信息,首先是元素数据的类型,还有就是该元素包含的通道个数

opencv中矩阵的类型有如下几种:

#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_8UC1 CV_MAKETYPE(CV_8U,1)

#define CV_8UC2 CV_MAKETYPE(CV_8U,2)

....

#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))

 

#define CV_8SC1 CV_MAKETYPE(CV_8S,1)

#define CV_8SC2 CV_MAKETYPE(CV_8S,2)

....

#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n))

 

#define CV_16UC1 CV_MAKETYPE(CV_16U,1)

#define CV_16UC2 CV_MAKETYPE(CV_16U,2)

....

#define CV_16UC(n) CV_MAKETYPE(CV_16U,(n))

 

#define CV_16SC1 CV_MAKETYPE(CV_16S,1)

#define CV_16SC2 CV_MAKETYPE(CV_16S,2)

....

#define CV_16SC(n) CV_MAKETYPE(CV_16S,(n))

 

#define CV_32SC1 CV_MAKETYPE(CV_32S,1)

#define CV_32SC2 CV_MAKETYPE(CV_32S,2)

....

#define CV_32SC(n) CV_MAKETYPE(CV_32S,(n))

 

#define CV_32FC1 CV_MAKETYPE(CV_32F,1)

#define CV_32FC2 CV_MAKETYPE(CV_32F,2)

....

#define CV_32FC(n) CV_MAKETYPE(CV_32F,(n))

 

#define CV_64FC1 CV_MAKETYPE(CV_64F,1)

#define CV_64FC2 CV_MAKETYPE(CV_64F,2)

....

#define CV_64FC(n)CV_MAKETYPE(CV_64F,(n))

 

这些数据类型都以宏的形式定义,它们的具体含义通过宏CV_MAKETYPE来确定,该宏包含两个参数,第一个参数指明数据的类型,第二个指明每个元素的通道数,每个元素至少需要有一个通道,直接使用CV_8U这样的类型表示的是一个通道。进一步查看它们的定义

#define CV_CN_MAX     512

#define CV_CN_SHIFT   3

#define CV_DEPTH_MAX  (1 <<CV_CN_SHIFT)  //值为1000(2进制)

#define CV_MAT_DEPTH_MASK       (CV_DEPTH_MAX- 1)     //值为0111

#define CV_MAT_DEPTH(flags)    ((flags) &CV_MAT_DEPTH_MASK)//取flags的低3位

#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth)+ (((cn)-1) << CV_CN_SHIFT))

CV_MAKETYPE的使用过程中,cn的取值可以是1到n,n一般不超过CV_CN_MAX。(((cn)-1) <<CV_CN_SHIFT)得到的结果是低三位必然0,只有高于低三位的位才有值,也就是说CV_MAKETYPE(depth,cn)得到的结果有两部分组成,第一部分是低3位的数据,这部分数据指明了数据的类型,第二部分则是高于低3位的其他位,这部分指明了矩阵元素的通道个数,这两部分互补干扰。

同时该宏生成的数据被传递给int类型的参数,由于该宏中只包含左移操作,所以无需考虑符号位的问题。

 

2 其他常用宏

#define CV_MAT_CN_MASK          ((CV_CN_MAX- 1) <<CV_CN_SHIFT)

0010 0000 0000 - 1 -->0001 1111 1111<< 3 -->1111 1111 1000

|#define CV_MAT_CN(flags)       ((((flags) &CV_MAT_CN_MASK) >>CV_CN_SHIFT)+ 1)

这个操作是取出矩阵的通道个数,(flags) & CV_MAT_CN_MASK)首先是取出通道位,为什么可以使用CV_MAT_CN_MASK <--((CV_CN_MAX - 1)<<CV_CN_SHIFT)来取出通道位呢,从上面的矩阵类型的定义宏可以看出

#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth)+ (((cn)-1) << CV_CN_SHIFT))

这里面就是((cn)-1) << CV_CN_SHIFT)定义了通道位,而又因为cn的值不超过CV_CN_MAX,所以可以使用(flags) & ((CV_CN_MAX - 1) << CV_CN_SHIFT)来取出通道位。CV_MAT_CN就是CV_MAKETYPE里计算通道的逆操作。

 

l  #define CV_MAT_TYPE_MASK        (CV_DEPTH_MAX*CV_CN_MAX - 1)

值为8*512 -1 = 0001 0000 0000 0000 = 1111 1111 1111

可以用它来提取出表示矩阵类型的位,这里需要验证一下表示类型的数据的大小,也就是使用

max((cn-1)>> CV_CN_SHIFT) = (CV_CN_MAX-1)>> CV_CN_SHIFT= (0010 0000 0000-1)>>3 = (0001 1111 1111)>>3 = 1111 1111 1000

从这里可以看出,表示通道数的最大值如上,而表示数据类型的最大值为0111,所以表示矩阵元素类型的值的大小不超过11111111 1111,因而可以用掩码CV_MAT_TYPE_MASK提取出来

l  #define CV_MAT_TYPE(flags)     ((flags) &CV_MAT_TYPE_MASK)

使用取出表示矩阵元素类型的位,包括数据类型和通道数信息,也就是提取出使用CV_MAKETYPE(depth,cn)生成的数据

|#define CV_MAT_DEPTH(flags)

#define CV_CN_SHIFT   3

#define CV_DEPTH_MAX  (1 <<CV_CN_SHIFT)  //值为1000(2进制)

#define CV_MAT_DEPTH_MASK       (CV_DEPTH_MAX- 1)     //值为0111

#define CV_MAT_DEPTH(flags)    ((flags) &CV_MAT_DEPTH_MASK)//取flags的低3位

即该宏取数据的低三位,这三位表示的是单个通道对应的数据类型,最大值为7,表示用户自定义类型。

原创粉丝点击