您的位置:首页 > 运维架构

OpenCV中矩阵类型的个人理解

2013-04-08 14:34 218 查看
在应用OpeCV函数库的时候经常需要查看图像的类型(也就是矩阵的类型,因为在OpenCV中图像是以Mat保存的),如果直接打印image.type,如:

image=imread("lina.jpg");
cout<<image.type()<<endl;

会发现,打印出来的是数字,而不是我们在OpenCV中常见的CV_8UC3等类型。看起来很不方便和直观。原来CV_8UC3等内置类型是OpenCV定义的宏,它们都是int型。同样地,image.type()返回的也是int类型。

我们需要的是找到它是怎样定义该宏的。

OpenCV的core文件夹下types_c.h中含有对矩阵类型的宏定义。

/****************************************************************************************\
*                                  Matrix type (CvMat)                                   *
\****************************************************************************************/

#define CV_CN_MAX     512
#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)

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

#define CV_8UC1 CV_MAKETYPE(CV_8U,1)
#define CV_8UC2 CV_MAKETYPE(CV_8U,2)
#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
#define CV_8UC4 CV_MAKETYPE(CV_8U,4)
#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_8SC3 CV_MAKETYPE(CV_8S,3)
#define CV_8SC4 CV_MAKETYPE(CV_8S,4)
#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_16UC3 CV_MAKETYPE(CV_16U,3)
#define CV_16UC4 CV_MAKETYPE(CV_16U,4)
#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_16SC3 CV_MAKETYPE(CV_16S,3)
#define CV_16SC4 CV_MAKETYPE(CV_16S,4)
#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_32SC3 CV_MAKETYPE(CV_32S,3)
#define CV_32SC4 CV_MAKETYPE(CV_32S,4)
#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_32FC3 CV_MAKETYPE(CV_32F,3)
#define CV_32FC4 CV_MAKETYPE(CV_32F,4)
#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_64FC3 CV_MAKETYPE(CV_64F,3)
#define CV_64FC4 CV_MAKETYPE(CV_64F,4)
#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n))

通过上面的源代码,我们发现OpenCV对depth的定义已经一目了然,分别是从0到7。由于type是由depth和channels组成的,OpenCV通过CV_MAKETYPE(depth, cn)来实现宏定义。上面代码中有CV_MAKETYPE的定义过程,也是用宏来实现的,为了便于理解,我重新把他写成了函数形式。

#include <iostream>

using namespace std;
#define CV_CN_SHIFT 3
int DepthMax()          //数字1向左移3位,16进制的低8位为:00001000
{
    return (1<<CV_CN_SHIFT);
}
int MatDepth(int flags) //DepthMax()-1后,16进制的低8位为:00000111
{                       //位与运算,只保留flags的后3位,其他位清零
    return (flags)&(DepthMax()-1);
}
int MakeType(int depth, int cn) //通道数cn减1,然后向左移3位,与深度相加
{

    return MatDepth(depth)+(((cn)-1)<<3);
}
int main()
{
    int a=MakeType(0,1);
    int b=MakeType(0,2);
    int c=MakeType(0,3);
    cout<<a<<endl;
    cout<<b<<endl;
    cout<<c<<endl;
    return 0;
}

程序运行结果:



原理:因为depth用三位就可以表示,作为低三位;通道cn最大值为512,把cn作为高9位,生成可达12位的type,例如CV_16UC2。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: