OpenCV源码解析之基本数据类型操作与概念
Mat是何处理数据类型的
在OpenCV中,矩阵在创建时,会传入一个数据类型,比如create函数要求传入_type; 然后,数据类型会被保存到flags中,create函数原型如下,
inline
void Mat::create(int _rows, int _cols, int _type)
{
_type &= TYPE_MASK;
if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
return;
int sz[] = {_rows, _cols};
create(2, sz, _type); // 这里会调用create(int d, const int* _sizes, int _type)
}
void Mat::create(int d, const int* _sizes, int _type)
{
…
flags = (_type & CV_MAT_TYPE_MASK) | MAGIC_VAL; //保存数据类型
…
}
这里的TYPE_MASK就是mat.hpp中定义的那个枚举类型,它和后面要讲的CV_MAT_TYPE_MASK是完全一致的,
enum { MAGIC_MASK = 0xFFFF0000, TYPE_MASK = 0x00000FFF, DEPTH_MASK = 7 };
在矩阵的计算和使用中,经常会有对数据类型的说明和判断,例如调用type函数来得到数据类型
inline
int Mat::type() const
{
return CV_MAT_TYPE(flags);
}
假设数据类型为CV_64FC1(= 0x06),根据定义
#define CV_MAT_TYPE_MASK (CV_DEPTH_MAX*CV_CN_MAX - 1) // 8*512-1 = 0x1000 – 1 = 0xFFF
#define CV_MAT_TYPE(flags) ((flags) & CV_MAT_TYPE_MASK) // flags&0xFFF
那么type()函数就会返回6,从而得知矩阵的数据类型是CV_64FC1。数据类型就是这样操作的。
数据类型是如何定义的
定义在:Core.hal.interface.h中,我只挑几个稍作说明一下,注意看注释
#define CV_CN_MAX 512
#define CV_CN_SHIFT 3
#define CV_DEPTH_MAX (1 << CV_CN_SHIFT)
// 这里:CV_DEPTH_MAX = 1000b = 0x08
#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)
// 这里:CV_MAT_DEPTH_MASK = 0x08 – 1 = 0x07
#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))
// 相当于定义:CV_MAKETYPE(depth,cn)= depth & 0x07 + (cn-1)<<3
#define CV_8UC1 CV_MAKETYPE(CV_8U,1) // = 0;
#define CV_8UC2 CV_MAKETYPE(CV_8U,2) // 1000b = 0x80
#define CV_8UC3 CV_MAKETYPE(CV_8U,3) // 1 0000b
#define CV_8UC4 CV_MAKETYPE(CV_8U,4) // 1 1000b
#define CV_8SC1 CV_MAKETYPE(CV_8S,1) //=0001b
#define CV_8SC2 CV_MAKETYPE(CV_8S,2) //=1001b
#define CV_8SC3 CV_MAKETYPE(CV_8S,3) //=1 0001b
#define CV_8SC4 CV_MAKETYPE(CV_8S,4) //=1 1000b
上面只列出了8U,8S,当然16,32,64位的也是类似的定义方法,其中符号
S|U|F--S--代表有符号整数(signed int)
U--代表无符号整数(unsigned int)
F--代表单精度浮点型(float)
C<number_of_channels>----代表一张图片的通道数,如
-灰度图是单通道
-RGB彩色图是3通道
-带Alph通道的ARGB图像是4通道
【1】CV_8UC1--可创建8位无符号的单通道灰度图
#define CV_8UC1 CV_MAKETYPE(CV_8U,1)
#define CV_8UC2 CV_MAKETYPE(CV_8U,2)
【2】CV_8UC3--可创建8位无符号的3通道RGB彩色图像
#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
【3】CV_8UC4--可创建8位无符号的4通道带透明度的RGB图像
#define CV_8UC4 CV_MAKETYPE(CV_8U,4)