opencv 简介

47
OpenCV 简简

Upload: svea

Post on 09-Jan-2016

209 views

Category:

Documents


16 download

DESCRIPTION

OpenCV 简介. OpenCV 的特征. OpenCV 具有以下的特征: (1)开源计算机视觉采用C/C++编写。 (2)使用目的是开发实时应用程序。 (3)独立与操作系统、硬件和图形管理器。 (4)具有通用的图象/视频载入、保存和获取模块。 (5)具有底层和高层的应用开发包。. OpenCV 的功能. 应用 OpenCV 能够实现以下功能: (1)对图象数据的操作,包括分配、释放、复制和转换数据。 (2)对图象和视频的输入输出,指文件和摄像头作为输入,图象和视频文件作为输出。 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: OpenCV 简介

OpenCV 简介

Page 2: OpenCV 简介

OpenCV 的特征OpenCV具有以下的特征:(1)开源计算机视觉采用C/C++编写。(2)使用目的是开发实时应用程序。(3)独立与操作系统、硬件和图形管理器。(4)具有通用的图象/视频载入、保存和获取

模块。(5)具有底层和高层的应用开发包。

Page 3: OpenCV 简介

OpenCV 的功能应用 OpenCV 能够实现以下功能:(1)对图象数据的操作,包括分配、释放、复制和转换数

据。(2)对图象和视频的输入输出,指文件和摄像头作为输入,

图象和视频文件作为输出。(3)具有对距陈和向量的操作以及线性代数的算法程序,

包括距阵、解方程、特征值以及奇异值。(4)可对各种动态数据结构,如列表、队列、集合、树和

图等进行操作。(5)具有基本的数字图象处理能力,如可进行滤波、边缘

检测、角点检测、采样与差值、色彩转换、形态操作、直方图和图象金字塔等操作。

Page 4: OpenCV 简介

(6)可对各种结构进行分析,包括连接部件分析、轮廓处理、距离变换、各种距的计算、模板匹配、 Hongh 变换、多边形逼近、直线拟合、椭圆拟合和 Delaunay 三角划分等。

( 7 )对摄像头的定标,包括发现与跟踪定标模式、定标、基本矩阵估计、齐次矩阵估计和立体对应。

( 8 )对运动的分析,如对光流、运动分割和跟踪的分析。

( 9 )对目标的识别,可采用特征法和隐马尔科夫模型( HMM )法。

( 10 )具有基本的 GUI 功能,包括图像与视频显示、键盘和鼠标事件处理及滚动条等。

( 11 )可对图像进行标注,如对线、二次曲线和多边形进行标注,还可以书写文字(目前之支持中文)。

Page 5: OpenCV 简介

OpenCV 模块OpenCV 包括以下几个模块,其具体功能是:( 1 ) CV 主要的 OpenCV 函数。( 2 ) CVAUX 辅助的(实验性) OpenCV 函数。( 3 ) CXCORE 数据结构与线性代数支持。( 4 ) HIGHGUI 图像界面函数。( 5 ) ML 机器学习,包括模式分类和回归分析等。( 6 ) CVCAM 负责读取摄像头数据的模块(在以

后版本中,当 HIGHGUI 模块中加入 Direct Show支持后,此模块将被废除)。

Page 6: OpenCV 简介

学习资源目前, OpenCV 方面的资源已经很多,当然最简单的方法还是在网上搜

索,比如在 Google 搜索引擎( http://www.google.com)中输入” OpenCV” 即可进行相关查找,这里给出一些信息作为参考。( 1 )参考手册 英文 请打开文件 <opencv-root>/docs/index.htm 进行查询。 中文 请打开网页 http://www.opencv.org.cn/进行查阅。( 2 )网络资源 官方网站 网址是 http://www.intel.com/technology/computing/opencv/。 中文官方网站 网址是 http://www.opencv.org.cn/。 软件下载 网址是 http://sourceforge.net/projects/opencvlibrary/。( 3 )书籍 请阅读北京航空航天大学出版社出版的《 OpenCV教程》。

Page 7: OpenCV 简介

OpenCV 基础1.OpenCV命名规则2.基本数据结构3.矩阵的使用与操作4.图象的使用与操作5.数据结构与数据操作

Page 8: OpenCV 简介

OpenCV命名规则1.1. 函数命名规则函数命名规则 通用函数名为 cvActionTargetMod(…) 其中, Action 表示核心函数(比如: Set , Create ); Target 表示目标图像区域(比如:轮廓,多边形); Mod 表示可选变种(比如:变量类型)。

2.2. 矩阵数据类型矩阵数据类型 通用矩阵数据类型为 CV_<bit_depth><S|U|P)C<number_of_channels> 其中, S 表示带符号整数; U 表示无符号整数; F 表示浮点数。 例如: CV_8UC1 表示 8位无符号单通道矩阵; CV_32FC2 表示 32位浮点数双通道矩阵。

Page 9: OpenCV 简介

3. 通用图像数据类型为 IPL_DEPTH_<bit_depth>(S|U|F)

其中, S,U,F 的意义同矩阵数据类型。 例如: IPL_DEPTH_8U 表示 8位无符号整数图像 IPL_DEPTH_32F 表示 32位浮点数图像

4. 头文件OpenCV 的头文件有如下几个:#include<cv.h>

#include<cvaux.h>

#include<highgui.h>

#include<cxcore.h>//不是必须的,它包含在 cv.h 中

Page 10: OpenCV 简介

基本的数据结构1. 图像结构2. 矩阵的与向量结构3. 其他的数据结构( 1 )点的表示( 2 )长方形维数的表示( 3 )有偏移量的长方形表示

Page 11: OpenCV 简介

图像结构Opencv 中的所有图像都采用同一个结构

IplImage,该图像结构说明参考后面的PPT 。实际上, IplImage 是借鉴于Intel公司最早发布的 IPP 图像处理开发包中的定义;但由于 IPP并非开源项目,因此对于 OpenCV 基本采用这个较复杂的图像结构,其版权方面的问题还有待研究。

Page 12: OpenCV 简介

矩阵与向量结构矩阵与向量结构的 和说明也可以参见后面的

PPT 。 OpenCV 采用一种独特的结构 CvArr* 。该结构是一个通用数组的表现形式,用做函数

的参数,说明函数在调用该参数时接受多种类型的输入数据形式,比如IplImage* , CvMat*甚至 CvSeq* 。具体的数组形式在运行时应根据实际情况来分析。

Page 13: OpenCV 简介

其他数据结构(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.0p.y=5.0

Page 14: OpenCV 简介

(2)长方形的维数表示 :

CvSize r=cvSize(int width,int height);

CvSize2D32f r=cvSize2D32f(float width,float height);

(3) 有便移量的长方形表示Cvrect r = cvrect (int x,int y,int width,int height);

Page 15: OpenCV 简介

矩阵的使用和操作1 . 分配和释放矩阵OpenCV 有一个矩阵操作的C语言的接口,另外也有一些C++语言的矩阵操作接口,通常C++语言接口更方便,且同样有效。

在 OpenCV 中,向量是被当成是行或列为1的矩阵,并且矩阵在内存中的存储方式是按行存储,且每行按4字节对齐。

Page 16: OpenCV 简介

(1) 分配矩阵 分配矩阵的原型为CvMat * cvCreateMat(int rows,int cols,int type);其中, type 表示矩阵元素的类型,可以用如下形式表达CV_<bit_depth>(S|U|F)C<number_of_channels>Eg :CvMat* M = cvCreateMar(4,4CV_32FC1);

(2) 释放矩阵释放矩阵的函数原型为Void cvReleaseMat(CvMat**);Eg:CvMat* M = cvCreateMat(4,4,CV_32FC1);cvReleaseMat(&M);

Page 17: OpenCV 简介

(3) 复制矩阵复制矩阵的函数原型为CvMat* cvCloneMat(cvMat);Eg:CvMat* M1 = cvCreateMat(4,4,CV_32FC1);CvMat* M2;M2 = cvCloneMat(M1);(4)初始化矩阵可按如下方法初始化一个3行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(&Ma,3,4,CV_64FC1,a);

Page 18: OpenCV 简介

(5)初始化单位矩阵可按如下方法初始化一个单位矩阵。CvMat* M = cvCreateMat(4,4,CV_32FC1);

cvSetIdentity(M);

Page 19: OpenCV 简介

访问矩阵元素(1) 直接访问下例是对元素M(i,j) 进行数据赋值和读取。cvmSet(M,I,j,2,0); //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;Data[i*n+j] = 3.0;

Page 20: OpenCV 简介

(3) 未知对齐方式的直接访问下例是对某种对齐方式存储的元素进行赋值。CvMat* M = cvCreateMat(4,4CV_32FC1);

int step = M->step/sizeof(float);

float * data = M->data.fl;

(data + i*step) [i]= 3.0;

(4) 直接访问一个已初始化的矩阵下例对已出吃化的矩阵 a 进行数据赋值。Double a[16];

CvMat Ma = cvM<at(3,4,CV_64FC1,a);

A[i*4+j] = 2.0; //Ma(i,j) = 2.0;

Page 21: OpenCV 简介

矩阵的向量操作对矩阵和向量的操作分以下几种类型。(1) 矩阵与矩阵之间的操作此类型包括:CvMat* Ma,*Mb,*Mc;

cvAdd(Ma,Mb,Mc); //Ma+Mb->Mc

cvSub(Ma,Mb,Mc); //Ma-Mb->Mc

cvMatMul(Ma,Mb,Mc); //Ma*Mb->Mc

Page 22: OpenCV 简介

(2) 矩阵元素之间的操作此类型包括:CvMat* Ma,*Mb,*Mc;cvMul(Ma,Mb,Mc); //Ma.*Mb->MccvDiv(Ma,Mb,Mc); //Ma./Mb->MccvAddS(Ma,cvScalar(-10.0),Mc); //Ma.-10->Mc

(3) 向量乘法操作此类型包括:double va[]={1,2,3};double vb[]={0,0,1};double vc[3];

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->rescvCrossProduct(&Va,&Vb,&Vc); //cross product:Va*Vb->Vc

注意 VA,VbVc 在叉积中必须是3个元素的向量。

Page 23: OpenCV 简介

(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);

Page 24: OpenCV 简介

(6) 特征值分析(对称矩阵)操作此类型包括:CvMat* 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,CV_SVD_U_T|CV_SVD_V_T);

Page 25: OpenCV 简介

图象的使用与操作1.分配和释放图象(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);

Page 26: OpenCV 简介

(2) 释放一幅图象释放图象的函数原型为Void cvReleaseImage(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);

Page 27: OpenCV 简介

(4)设置或得到感兴趣区域 ROI

函数原型分别为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 。

Page 28: OpenCV 简介

图象的读写(1)从文件读区图象IplImage* img = 0;img = cvLoadImage(fileName);If(!img) printf(“Couldnot load image file:%s\n”,fileName);默认情况下:img = cvLoadImage(fileName,flag);flag 取不同的值表示的意义不同

(2) 向文件中写图象If(!cvSaveImage(outFileName,img)) printf(“Could not save:%s\n”,outFileName);输出的图象文件格式依赖于文件的扩展名。

Page 29: OpenCV 简介

访问图像像素 (坐标是从 0 开始的,并且是相对图像原

点的位置。图像原点或者是左上角 (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]

Page 30: OpenCV 简介

假设有 8-bit 3- 通道的图像 I (IplImage* img) : I(x,y)blue ~ ((uchar*)(img->imageData + img-

>widthStep*y))[x*3] 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->widthStep*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_ptr[0] += 30; temp_ptr[1] += 30; temp_ptr[2] += 30;

Page 31: OpenCV 简介

假设有 32-bit 浮点数 , 1- 通道 图像 I (IplImage* img) :

I(x,y) ~ ((float*)(img->imageData + img->widthStep*y))[x]

Page 32: OpenCV 简介

现在,一般的情况下,假设有 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 ), 但是它们非常慢。

Page 33: OpenCV 简介

数据结构与数据操作 1 CvPoint 2 CvPoint2D32f 3 CvPoint3D32f 4 CvSize 5 CvSize2D32f 6 CvRect 7 CvScalar 8 CvTermCriteria 9 CvMat 10 CvMatND 11 CvSparseMat 12 IplImage 13 CvArr

Page 34: OpenCV 简介

CvPoint

二维坐标系下的点,类型为整型 typedef struct CvPoint { int x; /* X坐标 , 通常以 0 为基点 */ int y; /* y坐标 , 通常以 0 为基点 */ } CvPoint; /* 构造函数 */ inline CvPoint cvPoint( int x, int y ); /* 从 CvPoint2D32f 类型转换得来 */ inline CvPoint cvPointFrom32f( CvPoint2D32f point )

Page 35: OpenCV 简介

CvPoint2D32f

二维坐标下的点,类型为浮点 typedef struct CvPoint2D32f { float x;/* X坐标 , 通常以 0 为基点 */ float y; /* Y坐标 , 通常以 0 为基点 */ } CvPoint2D32f; /* 构造函数 */ inline CvPoint2D32f cvPoint2D32f( double x, double y ); /* 从 CvPoint 转换来 */ inline CvPoint2D32f cvPointTo32f( CvPoint point );

Page 36: OpenCV 简介

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 );

Page 37: OpenCV 简介

CvSize

矩形框大小,以像素为精度 typedef struct CvSize { int width; /* 矩形宽 */ int height; /* 矩形高 */ } CvSize; /* 构造函数 */ inline CvSize cvSize( int width, int height );

Page 38: OpenCV 简介

CvSize2D32f 以亚像素精度标量矩形框大小 typedef struct CvSize2D32f { float width; /* 矩形宽 */ float height; /* 矩形高 */ } CvSize2D32f; /* 构造函数 */ inline CvSize2D32f cvSize2D32f( double width, double height ); { CvSize2D32f s; s.width = (float)width; s.height = (float)height; return s;}

Page 39: OpenCV 简介

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 );

Page 40: OpenCV 简介

CvScalar 可存放在 1- , 2- , 3- , 4-TUPLE 类型的捆绑数据的容器 typedef struct CvScalar { double val[4] } CvScalar; /* 构造函数:用 val0初始化 val[0] 用 val1初始化 val[1], 以此类推

*/inline CvScalar cvScalar( double val0, double val1=0, double val2=0,

double val3=0 ); /* 构造函数:用 val0123初始化所有 val[0]...val[3] */ inline CvScalar cvScalarAll( double val0123 ); /* 构造函数:用 val0初始化 val[0], 用 0初始 val[1],val[2],val[3] */ inline CvScalar cvRealScalar( double val0 );

http://doc.blueruby.mydns.jp/opencv/classes/OpenCV/CvScalar.html

Page 41: OpenCV 简介

CvTermCriteria 迭代算法的终止准则 #define CV_TERMCRIT_ITER 1 #define CV_TERMCRIT_NUMBER CV_TERMCRIT_ITER#define CV_TERMCRIT_EPS 2 typedef struct CvTermCriteria { int type; /* CV_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 */ CvTermCriteria cvCheckTermCriteria( CvTermCriteria criteria, double

default_eps, int default_max_iters );

Page 42: OpenCV 简介

CvMat 多通道矩阵

Page 43: OpenCV 简介

CvMatND 多维、多通道密集数组

Page 44: OpenCV 简介

CvSparseMat 多维、多通道稀疏数组

Page 45: OpenCV 简介

IplImage IPL 图像头

Page 46: OpenCV 简介

IplImage 结构来自于 Intel Image Processing Library (是其本身所具有的)。OpenCV 只支持其中的一个子集 :

alphaChannel 在 OpenCV 中被忽略。 colorModel 和 channelSeq 被 OpenCV忽略。 OpenCV颜色转换的唯一函

数 cvCvtColor把原图像的颜色空间的目标图像的颜色空间作为一个参数。

dataOrder 必须是 IPL_DATA_ORDER_PIXEL (颜色通道是交叉存取 ) ,然而平面图像的被选择通道可以被处理,就像 COI (感兴趣的通道)被设置过一样。

align 是被 OpenCV忽略的,而用 widthStep 去访问后继的图像行。 不支持 maskROI 。处理 MASK 的函数把他当作一个分离的参

数。 MASK 在 OpenCV 里是 8-bit ,然而在 IPL他是 1-bit 。 tileInfo 不支持。 BorderMode 和 BorderConst 是不支持的。每个 OpenCV 函数处理像素的邻近的像素,通常使用单一的固定代码边际模式。

除了上述限制, OpenCV 处理 ROI 有不同的要求。要求原图像和目标图像的尺寸或 ROI 的尺寸必须(根据不同的操作,例如 cvPyrDown 目标图像的宽(高)必须等于原图像的宽(高)除以 2 ±1)精确匹配,而 IPL 处理交叉区域,如图像的大小或 ROI大小可能是完全独立的。

[ 编辑 ]

Page 47: OpenCV 简介

CvArr

不确定数组 typedef void CvArr; CvArr* 仅仅是被用于作函数

的参数,用于指示函数接收的数组类型可以不止一个,如 IplImage*, CvMat* 甚至 CvSeq*. 最终的数组类型是在运行时通过分析数组头的前 4 个字节判断。

取自 http://www.opencv.org.cn/index.php/Cxcore%E5%9F%BA%E7%A1%80%E7%BB%93%E6%9E%84

相关函数的运用见实例 (PPT)