1、OpenCV主体分为5个模块:
CXCore:基本数据结构和算法、绘图函数、XML支持。是其他模块的基础。
HighGUI:图像和视频 输入/输出 函数
CV:基本图像处理函数 和 高级计算机视觉算法
ML:机器学习库,包含一些基于统计的分类和聚类工具。
CvAux:即将淘汰的或者实验性的算法或函数
2、基本数据类型(原子类型)
结构 | 成员 | 意义 | 初始化函数 |
CvPoint | int x,y | 图像中的点 | CvPoint cvPoint( int x, int y ) |
CvPoint2D32f | float x,y | 二维空间点 | CvPoint2D32f cvPoint2D32f( double x, double y ) |
CvPoint3D32f | float x,y,z | 三维空间点 | CvPoint3D32f cvPoint3D32f( double x, double y, double z ) |
CvSize | int width,height | 图像尺寸 | CvSize cvSize( int width, int height ) |
CvRect | int x,y, width,height | 图像的部分区域 | CvRect cvRect( int x, int y, int width, int height ) |
CvScalar | double val[4] | RGBA的值 | cvScalar, cvRealScalar, cvScalarAll |
3、矩阵与图像(CvArr、CvMat、IplImage)
IplImage派生自CvMat,而CvMat派生自CvArr
3.1、CvMat矩阵
注意:OpenCV里面没有单独的向量。如需要用到向量,均用单列(行)矩阵代替。
注意:OpenCV里面的矩阵比线性代数里面的矩阵更加抽象。线代里的矩阵元素仅限于数值,OpenCV里面的矩阵可以是多种预定类型:CV_<位数>(S|U|F)C<通道数>,例如32位浮点数CV_32FC1,或者8位三元组无符号整型CV_8UC3。
3.1.1、CvMat数据结构构成:宽度、高度、类型、行数据长度、指向数据的指针
3.1.2、创建CvMat:cvCreateMat()。这个函数包含cvCreateMatHeader()和cvCreateData(),前者创建CvMat结构而不给数据指针分配内存,后者只负责为数据指针分配内存。构造函数cvMat()作用同cvCreateMatHeader(),只创建CvMat结构而不分配内存。
3.1.3、克隆CvMat:cvCloneMat(CvMat*)。OpenCV里面预定义的拷贝函数均是深度拷贝——描述部和数据区重新分配存储空间并原样复制。
3.1.4、释放CvMat:cvReaseMat(CvMat*)
3.1.5、矩阵查询:cvGetElemType,cvGetDims,cvGetDimSize
3.1.6、矩阵数据存取:
对于一维数组(n*1矩阵)和二维数组(n*m矩阵),可使用宏CV_MAT_ELEM(矩阵指针,待提取元素类型,行,列) 和 宏CV_MAT_ELEM_PTR(矩阵指针行,列)。前一个返回数据值,后一个返回指针,如果需要读取并设置可以使用后一个得到的指针来实现。
对于多维数组,可采用cvPtr<维度>D或者cvGet<维度>D函数,前者返回指针,后者返回值。例如uchar* cvPtr2D(CvArr* arr,int index_0,int index_1)。
特别注意:在多通道的矩阵中,通道是连续的。例如3通道的2维矩阵,矩阵的存储顺序是:rgbrgbrgb...也就是说,如果当前指针是在某像素的R值上,那么如果想访问下一个通道,只需将指针向后偏移一个单位,如果想访问下一个像素的R值那么需要将指针向后偏移3个单位。类似地,如果想访问下一行同列像素,可以借助CvMat的step(行数据长度)来实现。这也是cvPtr<维度>D常见的用途之一。
上述函数不可能在任何情况下都保持高效,最高效的方式是利用指针运算来获取元素指针并操作元素。下面介绍OpenCV里面的矩阵元素存储逻辑
元素是按照光栅扫描顺序存储的,列("x")是变化最快的量,通道是相互交错的。例如某张RGB图片(3*2像素)实际的像素是:
(01,02,03) (04,05,06) (07,08,09)
(10,11,12) (13,14,15) (16,17,18)
那么它顺序存储在内存中应该是:01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18
4、IplImage
本质上来说IplImage是一个CvMat对象,但是它还有其他的一些属性将矩阵解释为图像。
4.1、depth和nChannels
depth用于表示图像的深度;nChannels用于表示通道数。这两个属性在CvMat里面是用一个属性(type,用于表示矩阵元素的类型,取值类似于CV_8UC3)表示的。
depth的取值是IPL_DEPTH_<位数>(S|U|F),例如IPL_DEPTH_8U表示无符号8位整数。nChannels可取值1,2,3,4.
4.2、origin和dataOrder
origin表示图片的坐标原点,取值为IPL_ORIGIN_TL(左上角)或者IPL_ORIGIN_BL(左下角)
dataOrder表示图片数据的存储方式,取值为IPL_DATA_ORDER_PIXEL(交错排列,常用的排列方式,即类似rgbrgbrgb...方式)或者IPL_ORDER_PLAE(rrr...ggg...bbb...方式,实际上不被OpenCV支持)。
4.3、widthStep
类似于CvMat里面的step,用于表示相邻行同列点之间相差的字节数(注意,这个值对于图片的像素矩阵是一定的,但是不一定等于行长度(列数))。
4.4、imageData
指向数据域的指针
4.5、roi
表示感兴趣的区域。roi参数本身包括xOffset,yOffset,height,width和coi,其中coi表示感兴趣的通道。
如果设置了roi值,那么OpenCV函数所有对IplImage的处理都只会仅仅局限于roi指定的区域。