今后开始通过《 Learning OpenCV 》 英文版和查阅 OpenCV2.1 源代码来学习OpenCV。
OpenCV是Intel®开源计算机视觉库。它由一系列 C 函数和少量 C++ 类构成,实现了图像处理和计算机视觉方面的很多通用算法。
OpenCV包含以下几部分:
- CV 图像处理和视觉算法
- CXCORE 基本数据结构和算法 绘图函数
- HIGHGUI GUI,图像视频输入输出相关
- Machine Learning(ML) 机器学习相关 //ML!=Make Love
- CVAUX 一些即将被淘汰的算法和函数
目前查阅的相关源代码主要是以下文件:
- cxtypes.h 定义了C语言数据结构
- cxcore.h 声明了与数据结构相关的基本算法和绘图函数
- cxcore.hpp 定义了C++数据结构的类
- cxmat.hpp 与Mat类相关的函数
- cxoperations.hpp 定义C++其他数据结构的操作
计划先通过学习C版的库,再学习C++版本。以下记录的是C语言版。
————————————————————————基本数据结构———————————————————————————
点 CvPoint (CvPoint2D32f,CvPoint3D32f)
数据类型 内容 介绍
CvPoint int x, y 图像上的点
CvPoint2D32f float x, y 2维的点
CvPoint3D32f float x, y, z 3维的点
CvSize 与CvPoint相似,只不过数据成员为width和height。
接下来是CvRect,它是CvPoint与CvSize的结合体,包含x,y,width,height。
下面是CvScalar:通常可以用CvScalar来作为存储小于等于4个数值的结构体。
它有三个构造函数. 第一个是cvScalar(), 通过一个,两个,三个或四个参数来初始化val[];第二个是cvRealScalar(),它只有一个参数,把val[0]初始化为指定的值,其余三个数初始化为0;第三个是cvScalarAll(),它有一个参数,并把4个数全部初始化为这个参数。 代码如下:
——————————————————————————CvMat————————————————————————————
上面是一些基本的数据结构,以下记录一个非常重要的数据结构:CvMat
CvMat 派生于CvArr,而它有个子类叫IplImage。
CvArr
|
— — CvMat
|
——IplImage
在一些函数中经常会见到参数为(CvArr *)此时可以将CvMat* 或ImlImage*作为参数带入函数,将会发生动态绑定,确定进行正在操作的是哪个类。
CvMat的源代码如下:
CvMat可以通过一些方法来创建。
(cxcore/cxarray.cpp)
需要注意的是 cvMat()函数并没有创建数据,所以cvMat()函数要和cvCreateData()函数一起使用,或者用cvCreateMat()来代替以上两个函数。见以下代码:
下面举例说明如何用cvInitMatHeader()来为已经存在的矩阵初始化矩阵头:
- 矩阵信息的提取
好了,矩阵建立好了,那么我们怎么提取矩阵的信息呢?
有如下函数:
cvGetElemType( const CvArr* arr ) 获得矩阵的type
cvGetDims( const CvArr* arr, int* sizes=NULL ) 获得矩阵的维数
cvGetDimSize( const CvArr* arr, int index ). 获得矩阵相应坐标的Size
源代码中是这么注释的:
- 访问CvMat数据
我们可以通过宏定义CV_MAT_ELEM_PTR()和CV_MAT_ELEM().来得到矩阵相应位置的指针和存储的数据。
下面是宏定义的源代码:
可以看到,通过输入相应的行,列以及数据类型,就可以得到相应的指针和数据,非常的方便,非常Easy。
例如:
我们可以通过相应的函数来对高维矩阵进行操作。
用cvPtr*D来访问数据的一个重要的原因是,我们得到了一个指针,可以通过算术运算来移动指针去访问相邻的地址或指定的位置。但需要注意的是各个通道的物理存储是相邻的,例如一个三通道(RGB)二维矩阵,它每行的存储为:rgbrgbrgb..。这样的话,如果想访问相邻通道,那么指针+1,如果想访问相邻像素点,那么指针需要+3。