1、单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,,中国,.,中学政治教学网崇尚互联共享,OpenCV,简介,OpenCV,的特征,OpenCV,具有以下的特征:,()开源计算机视觉采用编写。,()使用目的是开发实时应用程序。,()独立与操作系统、硬件和图形管理器。,()具有通用的图象视频载入、保存和获取模块。,()具有底层和高层的应用开发包。,OpenCV,的功能,应用,OpenCV,能够实现以下功能:,()对图象数据的操作,包括分配、释放、复制和转换数据。,()对图象和视频的输入输出,指文件和摄像头作为输入,图象和视频文件作为输出。,()具有对距陈和
2、向量的操作以及线性代数的算法程序,包括距阵、解方程、特征值以及奇异值。,()可对各种动态数据结构,如列表、队列、集合、树和图等进行操作。,()具有基本的数字图象处理能力,如可进行滤波、边缘检测、角点检测、采样与差值、色彩转换、形态操作、直方图和图象金字塔等操作。,()可对各种结构进行分析,包括连接部件分析、轮廓处理、距离变换、各种距的计算、模板匹配、,Hongh,变换、多边形逼近、直线拟合、椭圆拟合和,Delaunay,三角划分等。,(,7,)对摄像头的定标,包括发现与跟踪定标模式、定标、基本矩阵估计、齐次矩阵估计和立体对应。,(,8,)对运动的分析,如对光流、运动分割和跟踪的分析。,(,9,
3、对目标的识别,可采用特征法和隐马尔科夫模型(,HMM,)法。,(,10,)具有基本的,GUI,功能,包括图像与视频显示、键盘和鼠标事件处理及滚动条等。,(,11,)可对图像进行标注,如对线、二次曲线和多边形进行标注,还可以书写文字(目前之支持中文)。,OpenCV,模块,OpenCV,包括以下几个模块,其具体功能是:,(,1,),CV,主要的,OpenCV,函数。,(,2,),CVAUX,辅助的(实验性),OpenCV,函数。,(,3,),CXCORE,数据结构与线性代数支持。,(,4,),HIGHGUI,图像界面函数。,(,5,),ML,机器学习,包括模式分类和回归分析等。,(,6,),C
4、VCAM,负责读取摄像头数据的模块(在以后版本中,当,HIGHGUI,模块中加入,Direct Show,支持后,此模块将被废除)。,学习资源,目前,,OpenCV,方面的资源已经很多,当然最简单的方法还是在网上搜索,比如在,Google,搜索引擎(,),中输入,”,OpenCV,”,即可进行相关查找,这里给出一些信息作为参考。,(,1,)参考手册,英文 请打开文件,/docs/,index.htm,进行查询。,中文 请打开网页,网址是,网址是,网址是,和说明也可以参见后面的,PPT,。,OpenCV,采用一种独特的结构,CvArr,*,。,该结构是一个通用数组的表现形式,用做函数的参数,说明
5、函数在调用该参数时接受多种类型的输入数据形式,比如,IplImage,*,,,CvMat,*,甚至,CvSeq,*,。具体的数组形式在运行时应根据实际情况来分析。,其他数据结构,(1),点的表示:,CvPoint,p=,cvPoint(int,x,int,y);,CvPoint2D32f p=cvPoint2D32f(float,x,float,y);,CvPoint3D32f p=cvPoint3D32f(float,x,float,y,float,z);,Eg,:,p.x,=5.0,p.y,=5.0,(2),长方形的维数表示,:,CvSize,r=,cvSize(int,width,int
6、height);,CvSize2D32f r=cvSize2D32f(float,width,float,height);,(3),有便移量的长方形表示,Cvrect,r,cvrect,(,int,x,int,y,int,width,int,height);,矩阵的使用和操作,.,分配和释放矩阵,OpenCV,有一个矩阵操作的语言的接口,另外也有一些语言的矩阵操作接口,通常语言接口更方便,且同样有效。,在,OpenCV,中,向量是被当成是行或列为的矩阵,并且矩阵在内存中的存储方式是按行存储,且每行按字节对齐。,(1),分配矩阵,分配矩阵的原型为,CvMat,*,cvCreateMat(int
7、rows,int,cols,int,type);,其中,,type,表示矩阵元素的类型,可以用如下形式表达,CV_(S|U|F)C,Eg,:,CvMat,*M=cvCreateMar(4,4CV_32FC1);,(2),释放矩阵,释放矩阵的函数原型为,Void,cvReleaseMat(CvMat,*);,Eg,:,CvMat,*M=cvCreateMat(4,4,CV_32FC1);,cvReleaseMat(&M,);,(3),复制矩阵,复制矩阵的函数原型为,CvMat,*,cvCloneMat(cvMat,);,Eg,:,CvMat,*M1=cvCreateMat(4,4,CV_32F
8、C1);,CvMat,*M2;,M2=cvCloneMat(M1);,(4),初始化矩阵,可按如下方法初始化一个行列矩阵。,Double a=1,2,3,4,5,6,7,8,9,10,11,12;,CvMat,Ma=cvMat(3,4,CV_64FC1,a);,或者:,CvMat,Ma;,CvInitMatHeader(,(5),初始化单位矩阵,可按如下方法初始化一个单位矩阵。,CvMat,*M=cvCreateMat(4,4,CV_32FC1);,cvSetIdentity(M,);,访问矩阵元素,直接访问,下例是对元素,M(i,j,),进行数据赋值和读取。,cvmSet(M,I,j,2,0
9、);/set,M(i,j,),t=,cvmGet(M,i,j,);/Get,M(i,j,),(2),已知对齐方式的直接访问,下例是对,32,位对齐方式存储的元素进行赋值。,CvMat,*M=cvCreateMat(4,4CV_32FC1);,int,n=M-cots;,float*data=M-,data.fl,;,Datai,*,n+j,=3.0;,(3),未知对齐方式的直接访问,下例是对某种对齐方式存储的元素进行赋值。,CvMat,*M=cvCreateMat(4,4CV_32FC1);,int,step=M-step/,sizeof(float,);,float*data=M-,data
10、fl,;,(data+i*step)i=3.0;,(4),直接访问一个已初始化的矩阵,下例对已出吃化的矩阵,a,进行数据赋值。,Double a16;,CvMat,Ma=,cvM,Mc,cvSub(Ma,Mb,Mc,);/Ma-Mb-Mc,cvMatMul(Ma,Mb,Mc,);/Ma*Mb-Mc,(2),矩阵元素之间的操作,此类型包括:,CvMat,*Ma,*Mb,*Mc;,cvMul(Ma,Mb,Mc,);/Ma.*Mb-Mc,cvDiv(Ma,Mb,Mc,);/Ma./Mb-Mc,cvAddS(Ma,cvScalar(-10.0),Mc);/Ma.-10-Mc,(3),向量乘法操作,此
11、类型包括:,double,va,=1,2,3;,double,vb,=0,0,1;,double vc3;,CvMat,Va,=cvMat(3,1,CV_64FC1,va);,CvMat,Vb,=cvMat(3,1,CV_64FC1,vb);,CvMat,Vc,=cvMat(3,1,CV_64FC1,vc);,double res=,cvDotProduct(&Va,&Vb,);/dot product:,Va.Vb,-res,cvCrossProduct(&Va,&Vb,&Vc,);/cross,product:Va,*,Vb,-,Vc,注意,VA,VbVc,在叉积中必须是个元素的向量。,(
12、4),单个矩阵的操作,此类型包括:,CvMat,*Ma,*Mb;,cvTranspose(Ma,Mb,);,CvScalar,t=cvTrace(Ma0;,Double d=,cvDet(Ma,);,cvInvert(Ma,Mb,);,(5),非齐次线性系统求解操作,此类型包括:,CvMat,*A=cvCreateMat(3,3,CV_32FC1);,CvMat,*x=cvCreateMat(3,3,CV_32FC1);,CvMat,*b=cvCreateMat(3,3,CV_32FC1);,cvSolve(&A,&b,&x,);,(6),特征值分析(对称矩阵)操作,此类型包括:,CvMat,
13、A=cvCreateMat(3,3,CV_32FC1);,CvMat,*E=cvCreateMat(3,3,CV_32FC1);,CvMat,*I=cvCreateMat(3,3,CV_32FC1);,cvEigenVV(&A,&E,&I,);,(7),奇异值分解操作,此类型包括:,CvMat,*A=cvCreateMat(3,3,CV_32FC1);,CvMat,*U=cvCreateMat(3,3,CV_32FC1);,CvMat,*D=cvCreateMat(3,3,CV_32FC1);,CvMat,*V=cvCreateMat(3,3,CV_32FC1);,cvSVD(A,DU,V,
14、CV_SVD_U_T|CV_SVD_V_T,);,图象的使用与操作,分配和释放图象,(1),分配一幅图象,分配图象的函数原型为,IplImage,*,cvCreateImage(CvSize,size,int,depth,int,channels);,Eg1:,IplImage,*img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);,Eg2:,IplImage,*img2=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);,(2),释放一幅图象,释放图象的函数原型为,Void,cvReleaseIma
15、ge(IplImage,*);,Eg,:,IplImage,*,img,=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);,cvReleaseImage(&img,);,(3),复制一幅图象,复制图象的函数原型为,IplImage,*,cvCloneImage(IplImage,*);,Eg,:,IplImage,*img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);,IplImage,*img2;,Img2=cvCloneImage(img1);,(4),设置或得到感兴趣区域,ROI,函数原型分别为
16、Void,cvSetImageROI(IplImage,*,image,CvRec,rect,);,Void,cvResetImageROI(IplImage,*image);,vRect,cvGetImageROI(IplImage,*image);,大多数,OpenCv,函数都支持,ROI,。,(5),设置或得到感兴趣区域,COI,函数原型分别为,Void,cvSetImageCOI(IplImage,*,image,int,coi);/0=all,Int,cvGetImageCOI(IplImage,*image);,大多数,OpenCv,函数都支持,COI,。,图象的读写,(1),从
17、文件读区图象,IplImage,*,img,=0;,img,=,cvLoadImage(fileName,);,If(!img,),printf(“Couldnot,load image,file:%sn”,fileName,);,默认情况下:,img,=,cvLoadImage(fileName,flag,);,flag,取不同的值表示的意义不同,(2),向文件中写图象,If(!cvSaveImage(outFileName,img,),printf(“Could,not,save:%sn”,outFileName,);,输出的图象文件格式依赖于文件的扩展名。,访问图像像素,(坐标是从,0,
18、开始的,并且是相对图像原点的位置。图像原点或者是左上角,(,img,-origin=IPL_ORIGIN_TL),或者是左下角,(,img,-origin=IPL_ORIGIN_BL),),假设有,8-bit 1,通道的图像,I(,IplImage,*,img,),:,I(x,y,)(,uchar,*)(,img,-,imageData,+,img,-,widthStep,*,y)x,假设有,8-bit 3-,通道的图像,I(,IplImage,*,img,),:,I(x,y)blue,(,uchar,*)(,img,-,imageData,+,img,-,widthStep,*,y)x,*3
19、I(x,y)green,(,uchar,*)(,img,-,imageData,+,img,-,widthStep,*,y)x,*3+1,I(x,y)red,(,uchar,*)(,img,-,imageData,+,img,-,widthStep,*,y)x,*3+2,例如,给点,(100,100),的亮度增加,30,,那么可以这样做:,CvPoint,pt=100,100;(,uchar,*)(,img,-,imageData,+,img,-,widthStep,*,pt.y)pt.x,*3+=30;(,uchar,*)(,img,-,imageData,+,img,-,widthSte
20、p,*,pt.y)pt.x,*3+1+=30;(,uchar,*)(,img,-,imageData,+,img,-,widthStep,*,pt.y)pt.x,*3+2+=30;,或者更高效地:,CvPoint,pt=100,100;,uchar,*,temp_ptr,=&(,uchar,*)(,img,-,imageData,+,img,-,widthStep,*,pt.y)pt.x,*3;temp_ptr0+=30;temp_ptr1+=30;temp_ptr2+=30;,假设有,32-bit,浮点数,1-,通道 图像,I(,IplImage,*,img,),:,I(x,y,)(floa
21、t*)(,img,-,imageData,+,img,-,widthStep,*,y)x,现在,一般的情况下,假设有,N-,通道,类型为,T,的图像:,I(x,y)c,(T*)(,img,-,imageData,+,img,-,widthStep,*,y)x,*N+c,你可以使用宏,CV_IMAGE_ELEM(,image_header,elemtype,y,x_Nc,),I(x,y)c,CV_IMAGE_ELEM(,img,T,y,x*N+c),也有针对各种图像(包括,4,通道图像)和矩阵的函数(,cvGet2D,cvSet2D,),但是它们非常慢。,数据结构与数据操作,1,CvPoint,
22、2 CvPoint2D32f,3 CvPoint3D32f,4,CvSize,5 CvSize2D32f,6,CvRect,7,CvScalar,8,CvTermCriteria,9,CvMat,10,CvMatND,11,CvSparseMat,12,IplImage,13,CvArr,CvPoint,二维坐标系下的点,类型为整型,typedef,struct,CvPoint,int,x;/*X,坐标,通常以,0,为基点*,/,int,y;/*y,坐标,通常以,0,为基点*,/,CvPoint,;,/*,构造函数*,/,inline,CvPoint,cvPoint,(,int,x,int,y
23、);,/*,从,CvPoint2D32f,类型转换得来*,/,inline,CvPoint,cvPointFrom32f(CvPoint2D32f point),CvPoint2D32f,二维坐标下的点,类型为浮点,typedef,struct,CvPoint2D32f,float x;/*X,坐标,通常以,0,为基点*,/,float y;/*Y,坐标,通常以,0,为基点*,/,CvPoint2D32f;,/*,构造函数*,/,inline CvPoint2D32f,cvPoint2D32f,(double x,double y);,/*,从,CvPoint,转换来*,/,inline Cv
24、Point2D32f cvPointTo32f(,CvPoint,point);,CvPoint3D32f,三维坐标下的点,类型为浮点,typedef,struct,CvPoint3D32f,float x;/*x-,坐标,通常基于,0*/,float y;/*y-,坐标,通常基于,0*/,float z;/*z-,坐标,通常基于,0*/CvPoint3D32f;,/*,构造函数*,/inline CvPoint3D32f,cvPoint3D32f,(double x,double y,double z);,CvSize,矩形框大小,以像素为精度,typedef,struct,CvSize,i
25、nt,width;/*,矩形宽*,/,int,height;/*,矩形高*,/,CvSize,;,/*,构造函数*,/,inline,CvSize,cvSize,(,int,width,int,height);,CvSize2D32f,以亚像素精度标量矩形框大小,typedef,struct,CvSize2D32f,float width;/*,矩形宽*,/,float height;/*,矩形高*,/,CvSize2D32f;,/*,构造函数*,/,inline CvSize2D32f,cvSize2D32f,(double width,double height);,CvSize2D32f
26、 s;,s.width,=(,float)width,;,s.height,=(,float)height,;,return s;,CvRect,矩形框的偏移和大小,typedef,struct,CvRect,int,x;/*,方形的最左角的,x-,坐标*,/,int,y;/*,方形的最上或者最下角的,y-,坐标*,/,int,width;/*,宽*,/,int,height;/*,高*,/,CvRect,;,/*,构造函数*,/inline,CvRect,cvRect,(,int,x,int,y,int,width,int,height);,CvScalar,可存放在,1-,,,2-,,,3
27、4-TUPLE,类型的捆绑数据的容器,typedef,struct,CvScalar,double val4,CvScalar,;,/*,构造函数:用,val0,初始化,val0,用,val1,初始化,val1,以此类推*,/,inline,CvScalar,cvScalar,(double val0,double val1=0,double val2=0,double val3=0);,/*,构造函数:用,val0123,初始化所有,val0.val3*/,inline,CvScalar,cvScalarAll,(double val0123);,/*,构造函数:用,val0,初始化
28、val0,用,0,初始,val1,val2,val3*/,inline,CvScalar,cvRealScalar,(double val0);,,doc.blueruby.mydns.jp/opencv/classes/OpenCV/CvScalar.html,CvTermCriteria,迭代算法的终止准则,#define CV_TERMCRIT_ITER 1,#define CV_TERMCRIT_NUMBER CV_TERMCRIT_ITER,#define CV_TERMCRIT_EPS 2,typedef,struct,CvTermCriteria,int,type;,/*CV_
29、TERMCRIT_ITER,和,CV_TERMCRIT_EPS,二值之一,或者二者的组合*,/,int,max_iter,;/*,最大迭代次数*,/,double epsilon;/*,结果的精确性*,/,CvTermCriteria,;,/*,构造函数*,/,inline,CvTermCriteria,cvTermCriteria,(,int,type,int,max_iter,double epsilon);,在满足,max_iter,和,epsilon,的条件下检查终止准则并将其转换使得,type=CV_TERMCRIT_ITER+CV_TERMCRIT_EPS*/,CvTermCrit
30、eria,cvCheckTermCriteria,(,CvTermCriteria,criteria,double,default_eps,int,default_max_iters,);,CvMat,多通道矩阵,CvMatND,多维、多通道密集数组,CvSparseMat,多维、多通道稀疏数组,IplImage,IPL,图像头,IplImage,结构来自于,Intel Image Processing Library,(是其本身所具有的)。,OpenCV,只支持其中的一个子集,:,alphaChannel,在,OpenCV,中被忽略。,colorModel,和,channelSeq,被,Op
31、enCV,忽略。,OpenCV,颜色转换的唯一函数,cvCvtColor,把原图像的颜色空间的目标图像的颜色空间作为一个参数。,dataOrder,必须是,IPL_DATA_ORDER_PIXEL(,颜色通道是交叉存取,),,然而平面图像的被选择通道可以被处理,就像,COI,(感兴趣的通道)被设置过一样。,align,是被,OpenCV,忽略的,而用,widthStep,去访问后继的图像行。,不支持,maskROI,。处理,MASK,的函数把他当作一个分离的参数。,MASK,在,OpenCV,里是,8-bit,,然而在,IPL,他是,1-bit,。,tileInfo,不支持。,BorderMo
32、de,和,BorderConst,是不支持的。每个,OpenCV,函数处理像素的邻近的像素,通常使用单一的固定代码边际模式。,除了上述限制,,OpenCV,处理,ROI,有不同的要求。要求原图像和目标图像的尺寸或,ROI,的尺寸必须(根据不同的操作,例如,cvPyrDown,目标图像的宽(高)必须等于原图像的宽(高)除以,2 1),精确匹配,而,IPL,处理交叉区域,如图像的大小或,ROI,大小可能是完全独立的。,编辑,CvArr,不确定数组,typedef,void,CvArr,;,CvArr,*,仅仅是被用于作函数的参数,用于指示函数接收的数组类型可以不止一个,如,IplImage,*,CvMat,*,甚至,CvSeq,*.,最终的数组类型是在运行时通过分析数组头的前,4,个字节判断。,取自,






