1、OpenCV使用说明1引言 OpenCV(Intel Open Source Computer Vision Library) 是Intel 公司面向应用程序开发者开发的计算机视觉库,其中包含大量的函数用来处理计算机视觉领域中常见的问题,例如运动分析和跟踪、人脸识别、3D 重建和目标识别等。目前该函数库的最新版本是OpenCV 4.0,可以通过访问 免费获得OpenCV 库以及相关的资料。另外,还可以通过访问 相对于其它图像函数库,OpenCV是一种源码开放式的函数库,开发者可以自由地调用函数库中的相关处理函数。OpenCV中包含500多个处理函数,具备强大的图像和矩阵运算能力,可以大大减少开
2、发者的编程工作量,有效提高开发效率和程序运行的可靠性。另外,由于OpenCV具有很好的移植性,开发者可以根据需要在MS-Windows和Linux两种平台进行开发,速度快,使用方便。2 OpenCV的结构目前OpenCV包含如下几个部分:Cxcore: 一些基本函数(各种数据类型的基本运算等)Cv: 图像处理和计算机视觉功能(图像处理,结构分析,运动分析,物体跟踪,模式识别,摄像定标)Highgui: 用户交互部分(GUI, 图像视频I/O, 系统调用函数)Cvaux: 一些实验性的函数(ViewMorphing, 三维跟踪,PCA,HMM)另外还有cvcam, 不过linux版本中已经抛弃。
3、Windows版本中将DirectX支持加入highgui后,cvcam将被彻底去掉。功能介绍:1) 图像增强直方图均衡化 cvEqualizeHist;2) 图像变换傅立叶变换:cvDFT离散余弦变换:cvDCT霍特林变换(PCA):cvCalPCA , cvProjectPCA, cvBackProjectPCA 3) 其它功能数学计算:矩阵的加减乘除,转置,逆,伪逆,逻辑运算, 统计,SVD分解图像处理:梯度,插值,几何变换,形态学操作, 滤波, 色彩空间变换, 矩,直方图, 特征匹配结构分析:轮廓处理, 几何形状计算, 平面划分运动分析:对象跟踪, 对象检测,相机定标,三维重建,分类器
4、设计3 VC 6下的安装与配置3.1安装OpenCV(略)3.2 配置Windows环境变量检查C:Program FilesOpenCVbin是否已经被加入到环境变量PATH,如果没有,请加入。加入后需要注销当前Windows用户(或重启)后重新登陆才生效。(可以在任务管理器里重启explorer.exe) 4 VC+的环境设置 OpenCV主要由大量C函数和少数的C+函数类构成的,在Visual C+中调用OpenCV相当方便,不过,在开始编译程序前需要设置好编译环境。因此,首先介绍VC+环境的设置。 由于OpenCV是一个图像库,因此在VC+中编程之前需要预先设置编程环境,即将OpenC
5、V需要的一些函数头文件和库文件加入到当前编译的工程中,使得程序在编译时能够正确地找到所需文件。 菜单Tools-Options-Directories:先设置lib路径,选择Library files,在下方填入路径: C:Program FilesOpenCVlib然后选择include files,在下方填入路径: C:Program FilesOpenCVcxcoreincludeC:Program FilesOpenCVcvincludeC:Program FilesOpenCVcvauxincludeC:Program FilesOpenCVmlincludeC:Program Fi
6、lesOpenCVotherlibshighguiC:Program FilesOpenCVotherlibscvcaminclude然后选择source files,在下方填入路径:C:Program FilesOpenCVcvsrcC:Program FilesOpenCVcxcoresrcC:Program FilesOpenCVcvauxsrcC:Program FilesOpenCVotherlibshighguiC:Program FilesOpenCVotherlibscvcamsrcwindows最后点击“ok”,完成设置。5如何创建一个项目来开始OpenCV 编程为了创建基于
7、 OpenCV 的项目,按如下步骤进行: (一)创建新的应用程序: 1)选择菜单 File-New.-Projects 标签。 选择Win32 console application 2)键入项目名称,并且选择保存位置。 3)可以为项目创建一个单独的 workspace (Create new workspace), 也可以将新的项目加入到当前的 workspace 中 (Add to current workspace)。 4)单击 next 按钮。 5)选择 An empty project,点击 Finish,OK。 经过以上步骤,Developer Studio 会创建一个项目目录 (
8、缺省情况下,目录名就是项目名), .dsp 文件以及.dsw,.ncb 等,如果你创建自己的workspace。 (二)添加文件到 project 中: 1)选择菜单File-New.-Files 。 2)选择C+ Source File, 键入文件名,点击OK 。 3)增加 OpenCV 相关的头文件目录: #include cv.h/* #inlcude cvaux.h / experimental stuff (if need) */#include highgui.h(三)配置项目: 每创建一个将要使用OpenCV的VC Project,都需要给它指定需要的lib。菜单:Project
9、-Settings,然后将Setting for选为All Configurations,然后选择右边的link标签,在Object/library modules附加上cxcore.lib cv.lib ml.lib cvaux.lib highgui.lib cvcam.lib如果你不需要这么多lib,你可以只添加你需要的lib。具体说明:选择菜单Project-Settings.以激活项目配置对话框,在左边选择你的项目。 调节设置,对 Release 和 Debug 配置都有效: 1) 选择 Settings For:-All Configurations 2) 选择 C/C+ 标签 -
10、 Preprocessor category - Additional Include Directories:。 加入用逗号分隔的相对路径 (对文件 .dsp 而言) 或绝对路径 opencvcxcoreinclude, opencvcvinclude, opencvotherlibshighgui 以及可选的 optionally, opencvcvauxinclude。 3) 选择 Link 标签 - Input category - Additional library path:. 加入输入库所在的路径 (cxcored.lib cvd.lib hihghuid.lib cvauxd
11、.lib) 调节 Debug 配置 1)选择 Settings For:-Win32 Debug。 2)选择 Link 标签 - General category - Object/library modules。 加入空格分隔的 cvd.lib, highguid.lib, cvauxd.lib (cvauxd.lib可选) 3) 可以改变输出文件的名称和位置。如想把产生的 .exe 文件放置于项目目录而不是Debug/ 子目录下,可在 Link tab - General category - Output file name: 中键入 ./d.exe 调节 Release 配置 1) 选
12、择 Settings For:-Win32 Release. 2)选择 Link 标签 - General category - Object/library modules. 加入空格分隔的 cv.lib, highgui.lib, cvaux.lib (cvaux.lib可选) 3) 另外,你也可以改变 .exe 文件名。 键入 ./.exe 到 Link 标签 - General category - Output file name:。 就这么多,可以编译并且运行一切了。 在设置完编译环境后,针对OpenCV函数库的一些基本图像函数,利用下面的例子分别从图像的载入、显示和基本的图像处理
13、方面介绍OpenCV的具体用法。6如何读入和显示图像 #include cv.h /*OpenCV的基本函数头文件*/ #include highgui.h /* OpenCV的图像显示函数头文件*/int main( int argc, char* argv ) IplImage* img; /* 定义IplImage指针变量img */ if( argc = 2 & (img = cvLoadImage( argv1, 1) != 0 ) cvNamedWindow( Image view, 1 ); /* 定义一个窗口名为Image view的显示窗口 */ cvShowImage( I
14、mage view, img ); /* 在Image view窗口中,显示img指针所指的图像*/ cvWaitKey(0); / 非常重要,内部包含事件处理循环 cvDestroyWindow( Image view ); cvReleaseImage( &img ); return 0; return -1;1)图像载入函数 IplImage* src=/cvLoadImage(lena.jpg,-1); /* 定义IplImage指针变量src,并且将src指向当前目录下的图像lena.jpg */函数cvLoadImage载入指定图像文件,并返回指向该文件的IplImage指针。函数
15、支持bmp、jpg、 png、 tiff等格式的图像。其函数原型如下: IplImage* cvLoadImage( const char* filename, int iscolor); 其中,filename 是待载入图像的名称,包括图像的扩展名;iscolor是一个辅助参数项,可选正数、零和负数三种值,正数表示作为三通道图像载入,零表示该图像作为单通道图像,负数表示载入图像的通道数由图像文件自身决定。 2)窗口定义函数 cvNamedWindow(src,CV_WINDOW_AUTOSIZE); /* 定义一个窗口名为src的显示窗口 */函数cvNamedWindow定义一个窗口,用于
16、显示图像。其函数原型如下: int cvNamedWindow( const char* name, unsigned long flags ); 其中,name是窗口名,flags是窗口属性指标值,可以选择CV_WINDOW_AUTOSIZE和0两种值。CV_WINDOW_AUTOSIZE表示窗口尺寸与图像原始尺寸相同,0表示以固定的窗口尺寸显示图像。 3)图像显示函数 cvShowImage(src,src); /* 在src窗口中,显示src指针所指的图像*/函数cvShowImage是在指定的窗口中显示图像,其函数原型如下: void cvShowImage( const char*
17、name, const CvArr* image ); 其中,name是窗口名称,image是图像类型指针,一般是IplImage指针。 4)图像保存函数 函数cvSaveImage以指定的文件名保存IplImage类型的指针变量,其函数原型如下: int cvSaveImage( const char* filename, const CvArr* image ); 其中,filename是图像保存路径和名称,image是IplImage指针变量。 说明: 函数cvSaveImage保存图像到指定文件。图像格式的的选择依赖于filename的扩展名,请参考cvLoadImage。只有8位单通
18、道或者3通道(通道顺序为BGR )可以使用这个函数保存。如果格式,深度或者通道不符合要求,请先用cvCvtScale 和cvCvtColor转换;或者使用通用的cvSave保存图像为XML或者YAML格式。5)图像销毁函数 函数cvReleaseImage销毁已定义的IplImage指针变量,释放占用内存空间。其函数原型如下: void cvReleaseImage( IplImage* image ); 其中,image为已定义的IplImage指针。 6)等待按键事件cvWaitKey int cvWaitKey( int delay=0 );delay 延迟的毫秒数。 函数cvWaitK
19、ey无限制的等待按键事件(delayorigin=IPL_ORIGIN_TL) 或者是左下角 img-origin=IPL_ORIGIN_BL) ) 假设有 8-bit 1通道的图像 I (IplImage* img): 假设有 8-bit 3-通道的图像 I (IplImage* img): 例如,给点 (100,100) 的亮度增加 30 ,那么可以这样做: 或者更高效地: 假设有 32-bit 浮点数, 1-通道 图像 I (IplImage* img): 现在,一般的情况下,假设有 N-通道,类型为 T 的图像: 你可以使用宏 CV_IMAGE_ELEM( image_header,
20、elemtype, y, x_Nc ) I(x,y)c CV_IMAGE_ELEM( img, T, y, x*N + c )也有针对各种图像(包括 4 通道图像)和矩阵的函数(cvGet2D, cvSet2D), 但是它们非常慢。 8如何访问矩阵元素 typedef struct CvMat int type; int step; /* for internal use only */ int* refcount; int hdr_refcount; union uchar* ptr; short* s; int* i; float* fl; double* db; data;#ifdef
21、_cplusplus union int rows; int height; ; union int cols; int width; ;#else int rows; int cols;#endifCvMat;方法是类似的(下面的例子都是针对 0 起点的列和行) 设有 32-bit 浮点数的实数矩阵 M (CvMat* mat): M(i,j) (float*)(mat-data.ptr + mat-step*i)j设有 64-bit 浮点数的复数矩阵 M (CvMat* mat): Re M(i,j) (double*)(mat-data.ptr + mat-step*i)j*2Im M(
22、i,j) (double*)(mat-data.ptr + mat-step*i)j*2+1对单通道矩阵,有宏 CV_MAT_ELEM( matrix, elemtype, row, col ), 例如对 32-bit 浮点数的实数矩阵: M(i,j) CV_MAT_ELEM( mat, float, i, j ),例如,这儿是一个 3x3 单位矩阵的初始化: CV_MAT_ELEM( mat, float, 0, 0 ) = 1.f;CV_MAT_ELEM( mat, float, 0, 1 ) = 0.f;CV_MAT_ELEM( mat, float, 0, 2 ) = 0.f;CV_M
23、AT_ELEM( mat, float, 1, 0 ) = 0.f;CV_MAT_ELEM( mat, float, 1, 1 ) = 1.f;CV_MAT_ELEM( mat, float, 1, 2 ) = 0.f;CV_MAT_ELEM( mat, float, 2, 0 ) = 0.f;CV_MAT_ELEM( mat, float, 2, 1 ) = 0.f;CV_MAT_ELEM( mat, float, 2, 2 ) = 1.f; 9如何在 OpenCV 中处理我自己的数据 设你有 300x200 32-bit 浮点数 image/array, 也就是对一个有 60000 个元素
24、的数组。 int cols = 300, rows = 200;float* myarr = new floatrows*cols;/ 第一步,初始化 CvMat 头CvMat mat = cvMat( rows, cols, CV_32FC1, / 32 位浮点单通道类型 myarr / 用户数据指针(数据没有被复制) );/ 第二步,使用 cv 函数, 例如计算 l2 (Frobenius) 模double norm = cvNorm( &mat, 0, CV_L2 );.delete myarr;其它情况在参考手册中有描述。 见 cvCreateMatHeader,cvInitMatHe
25、ader,cvCreateImageHeader, cvSetData 等 10. 例程10.1 Kalman滤波进行旋转点的跟踪下面是程序所用到的主要的三个函数(完整程序见kalman):CreateKalman分配 Kalman 滤波器结构, 设置A, B, Q, R 的初始状态 CvKalman* kalman = cvCreateKalman( 2, 1,0);CvKalman* cvCreateKalman( int dynam_params, int measure_params, int control_params=0 );dynam_params状态向量维数measure_p
26、arams测量向量维数control_params控制向量维数函数 cvCreateKalman 分配 CvKalman 以及它的所有矩阵和初始参数KalmanPredict估计后来的模型状态 const CvMat* prediction = cvKalmanPredict( kalman, 0 );const CvMat* cvKalmanPredict( CvKalman* kalman, const CvMat* control=NULL );#define cvKalmanUpdateByTime cvKalmanPredictkalman Kalman 滤波器状态 control
27、控制向量 (uk), 如果没有外部控制 (control_params=0) 应该为 NULL 函数 cvKalmanPredict 根据当前状态估计后来的随机模型状态,并存储于 kalman-state_pre: 其中 :xk 是预测状态 (kalman-state_pre), xk - 1 是前一步的矫正状态 (kalman-state_post),应该在开始的某个地方初始化,即缺省为零向量, uk 是外部控制(control 参数), Pk 是先验误差相关矩阵 (kalman-error_cov_pre) Pk - 1 是前一步的后验误差相关矩阵(kalman-error_cov_pos
28、t),应该在开始的某个地方初始化,即缺省为单位矩阵。函数返回估计得到的状态值。KalmanCorrect调节模型状态 cvKalmanCorrect( kalman, measurement );const CvMat* cvKalmanCorrect( CvKalman* kalman, const CvMat* measurement );#define cvKalmanUpdateByMeasurement cvKalmanCorrectkalman 被更新的 Kalman 结构的指针 measurement 指向测量向量的指针,向量形式为 CvMat 函数 cvKalmanCorrec
29、t 在给定的模型状态的测量基础上,调节随机模型状态:其中: zk - 给定测量(mesurement parameter) Kk - Kalman 增益 矩阵 函数存储调节状态到 kalman-state_post 中并且输出时返回它。跟踪算法与程序代码分析:1) 产生一个kalman滤波器,初始化A,H,Q,R.X(k)=A X(k-1)+B U(k)+W(k), Z(k)=H X(k)+V(k) ,X(k)是k时刻的系统状态,U(k)是k时刻对系统的控制量。A和B是系统参数,对于多模型系统,他们为矩阵。Z(k)是k时刻的测量值,H是测量系统的参数,对于多测量系统,H为矩阵。W(k)和V(k)分别表示过程和测量的噪声。他们被假设成高斯白噪声(White Gaussian Noise),他们的covariance 分别是Q,R。初始化滤波器的初始状态(随机) ,得到初始状态的角度, 横纵座标:CvKalman* kal
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1