opencv教程.docx
《opencv教程.docx》由会员分享,可在线阅读,更多相关《opencv教程.docx(42页珍藏版)》请在冰豆网上搜索。
opencv教程
一、简介
[编辑]
1、OpenCV的特点
[编辑]
(1)总体描述
OpenCV是一个基于C/C++语言的开源图像处理函数库
其代码都经过优化,可用于实时处理图像
具有良好的可移植性
可以进行图像/视频载入、保存和采集的常规操作
具有低级和高级的应用程序接口(API)
提供了面向IntelIPP高效多媒体函数库的接口,可针对你使用的IntelCPU优化代码,提高程序性能(译注:
OpenCV2.0版的代码已显着优化,无需IPP来提升性能,故2.0版不再提供IPP接口)
[编辑]
(2)功能
图像数据操作(内存分配与释放,图像复制、设定和转换)
Imagedatamanipulation(allocation,release,copying,setting,conversion).
图像/视频的输入输出(支持文件或摄像头的输入,图像/视频文件的输出)
ImageandvideoI/O(fileandcamerabasedinput,image/videofileoutput).
矩阵/向量数据操作及线性代数运算(矩阵乘积、矩阵方程求解、特征值、奇异值分解)
Matrixandvectormanipulationandlinearalgebraroutines(products,solvers,eigenvalues,SVD).
支持多种动态数据结构(链表、队列、数据集、树、图)
Variousdynamicdatastructures(lists,queues,sets,trees,graphs).
基本图像处理(去噪、边缘检测、角点检测、采样与插值、色彩变换、形态学处理、直方图、图像金字塔结构)
Basicimageprocessing(filtering,edgedetection,cornerdetection,samplingandinterpolation,colorconversion,morphologicaloperations,histograms,imagepyramids).
结构分析(连通域/分支、轮廓处理、距离转换、图像矩、模板匹配、霍夫变换、多项式逼近、曲线拟合、椭圆拟合、狄劳尼三角化)
Structuralanalysis(connectedcomponents,contourprocessing,distancetransform,variousmoments,templatematching,Houghtransform,polygonalapproximation,linefitting,ellipsefitting,Delaunaytriangulation).
摄像头定标(寻找和跟踪定标模式、参数定标、基本矩阵估计、单应矩阵估计、立体视觉匹配)
Cameracalibration(findingandtrackingcalibrationpatterns,calibration,fundamentalmatrixestimation,homographyestimation,stereocorrespondence).
运动分析(光流、动作分割、目标跟踪)
Motionanalysis(opticalflow,motionsegmentation,tracking).
目标识别(特征方法、HMM模型)
Objectrecognition(eigen-methods,HMM).
基本的GUI(显示图像/视频、键盘/鼠标操作、滑动条)
BasicGUI(displayimage/video,keyboardandmousehandling,scroll-bars).
图像标注(直线、曲线、多边形、文本标注)
Imagelabeling(line,conic,polygon,textdrawing)
[编辑]
(3)OpenCV模块
cv–核心函数库
cvaux–辅助函数库
cxcore–数据结构与线性代数库
highgui–GUI函数库
ml–机器学习函数库
、OpenCV命名规则
[编辑]
(1)函数名:
cvActionTargetMod(...)
Action=核心功能(corefunctionality)(e.g.set,create)
Target=目标图像区域(targetimagearea)(e.g.contour,polygon)
Mod=(可选的)调整语(optionalmodifiers)(e.g.argumenttype)
[编辑]
(2)矩阵数据类型:
CV_(S|U|F)C
S=符号整型
U=无符号整型
F=浮点型
E.g.:
CV_8UC1是指一个8位无符号整型单通道矩阵,
CV_32FC2是指一个32位浮点型双通道矩阵.
[编辑]
(3)图像数据类型:
IPL_DEPTH_(S|U|F)
E.g.:
IPL_DEPTH_8U图像像素数据是8位无符号整型.
IPL_DEPTH_32F图像像素数据是32位浮点型.
[编辑]
(4)头文件:
#include
#include
#include
#include
#include//一般不需要,cv.h内已包含该头文件
[编辑]
4、编译建议
[编辑]
(1)Linux:
g++hello-world.cpp-ohello-world\
-I/usr/local/include/opencv-L/usr/local/lib\
-lm-lcv-lhighgui-lcvaux
[编辑]
(2)Windows:
在VisualStudio的‘选项’和‘项目’中设置好OpenCV相关文件的路径。
[编辑]
5、C例程
////////////////////////////////////////////////////////////////////////
//
//hello-world.cpp
//
//该程序从文件中读入一幅图像,将之反色,然后显示出来.
//
////////////////////////////////////////////////////////////////////////
#include
#include
#include
#include
#include
intmain(intargc,char*argv[])
{
IplImage*img=0;
intheight,width,step,channels;
uchar*data;
inti,j,k;
if(argc<2){
printf("Usage:
main\n\7");
exit(0);
}
//loadanimage
img=cvLoadImage(argv[1]);
if(!
img){
printf("Couldnotloadimagefile:
%s\n",argv[1]);
exit(0);
}
//gettheimagedata
height=img->height;
width=img->width;
step=img->widthStep;
channels=img->nChannels;
data=(uchar*)img->imageData;
printf("Processinga%dx%dimagewith%dchannels\n",height,width,channels);
//createawindow
cvNamedWindow("mainWin",CV_WINDOW_AUTOSIZE);
cvMoveWindow("mainWin",100,100);
//inverttheimage
//相当于cvNot(img);
//IplImage*pDstImg=cvCreateImage(cvGetSize(img),img->depth,img->nChannels);
//cvNot(img,pDstImg);
for(i=0;idata[i*step+j*channels+k]=255-data[i*step+j*channels+k];
//showtheimage
cvShowImage("mainWin",img);
//waitforakey
cvWaitKey(0);
//releasetheimage
cvReleaseImage(&img);
return0;
}
[编辑]
二、GUI指令
[编辑]
1、窗口管理
[编辑]
(1)创建和定位一个新窗口:
cvNamedWindow("win1",CV_WINDOW_AUTOSIZE);
cvMoveWindow("win1",100,100);//offsetfromtheULcornerofthescreen
[编辑]
(2)载入图像:
IplImage*img=0;
img=cvLoadImage(fileName,CV_LOAD_IMAGE_COLOR);
if(!
img)printf("Couldnotloadimagefile:
%s\n",fileName);
[编辑]
(3)显示图像:
cvShowImage("win1",img);
该函数可以在上面建立的窗口(win1)中显示彩色或灰度的字节型/浮点型图像。
字节型图像像素值范围为[0-255];浮点型图像像素值范围为[0-1]。
彩色图像的三色元素按BGR(蓝-绿-红)顺序存储。
[编辑]
(4)关闭窗口:
cvDestroyWindow("win1");
[编辑]
(5)改变窗口大小:
cvResizeWindow("win1",100,100);//newwidth/heighinpixels
[编辑]
2、输入处理
[编辑]
(1)处理鼠标事件:
定义一个鼠标处理程序:
voidmouseHandler(intevent,intx,inty,intflags,void*param)
{
switch(event){
caseCV_EVENT_LBUTTONDOWN:
if(flags&CV_EVENT_FLAG_CTRLKEY)
printf("LeftbuttondownwithCTRLpressed\n");
break;
caseCV_EVENT_LBUTTONUP:
printf("Leftbuttonup\n");
break;
}
}
x,y:
相对于左上角的像素坐标
event:
CV_EVENT_LBUTTONDOWN,CV_EVENT_RBUTTONDOWN,CV_EVENT_MBUTTONDOWN,
CV_EVENT_LBUTTONUP,CV_EVENT_RBUTTONUP,CV_EVENT_MBUTTONUP,
CV_EVENT_LBUTTONDBLCLK,CV_EVENT_RBUTTONDBLCLK,CV_EVENT_MBUTTONDBLCLK,
CV_EVENT_MOUSEMOVE:
flags:
CV_EVENT_FLAG_CTRLKEY,CV_EVENT_FLAG_SHIFTKEY,CV_EVENT_FLAG_ALTKEY,
CV_EVENT_FLAG_LBUTTON,CV_EVENT_FLAG_RBUTTON,CV_EVENT_FLAG_MBUTTON
注册该事件处理程序:
mouseParam=5;
cvSetMouseCallback("win1",mouseHandler,&mouseParam);//第三个参数可以设置为NULL
[编辑]
(2)处理键盘事件:
实际上对于键盘输入并没有专门的事件处理程序.
按一定间隔检测键盘输入(适用于循环体中):
intkey;
key=cvWaitKey(10);//wait10msforinput
中止程序等待键盘输入:
intkey;
key=cvWaitKey(0);//waitindefinitelyforinput
键盘输入的循环处理程序:
while
(1){
key=cvWaitKey(10);
if(key==27)break;
switch(key){
case'h':
...
break;
case'i':
...
break;
}
}
[编辑]
(3)处理滑动条事件:
定义一个滑动条处理程序:
voidtrackbarHandler(intpos)
{
printf("Trackbarposition:
%d\n",pos);
}
注册该事件处理程序:
inttrackbarVal=25;
intmaxVal=100;
cvCreateTrackbar("bar1","win1",&trackbarVal,maxVal,trackbarHandler);
获取当前的滑动条位置:
intpos=cvGetTrackbarPos("bar1","win1");
设置滑动条位置:
cvSetTrackbarPos("bar1","win1",25);
[编辑]
三、OpenCV的基本数据结构
(译注:
OpenCV1.1、1.2或2.0版本中各数据结构的结构体元素有所调整,以下仅作参考)
[编辑]
1、图像数据结构
[编辑]
(1)IPL图像:
IplImage
|--intnChannels;//颜色通道数目(1,2,3,4)
|--intdepth;//像素的位深:
|//IPL_DEPTH_8U,IPL_DEPTH_8S,
|//IPL_DEPTH_16U,IPL_DEPTH_16S,
|//IPL_DEPTH_32S,IPL_DEPTH_32F,
|//IPL_DEPTH_64F
|--intwidth;//图像宽度(像素为单位)
|--intheight;//图像高度
|--char*imageData;//图像数据指针
|//注意彩色图像按BGR顺序存储数据
|--intdataOrder;//0-将像素点不同通道的值交错排在一起,形成单一像素平面
|//1-把所有像素同通道值排在一起,形成若干个通道平面,再把平面排列起来
|//cvCreateImage只能创建像素交错排列式的图像
|--intorigin;//0–像素原点为左上角,
|//1–像素原点为左下角(Windowsbitmapsstyle)
|--intwidthStep;//相邻行的同列点之间的字节数
|--intimageSize;//图像的大小(字节为单位)=height*widthStep
|--struct_IplROI*roi;//图像的感兴趣区域(ROI).ROI非空时对图像的
|//处理仅限于ROI区域.
|--char*imageDataOrigin;//图像数据未对齐时的数据原点指针
|//(需要正确地重新分配图像内存)
|//(neededforcorrectimagedeallocation)
|--intalign;//图像数据的行对齐:
4or8bytealignment
|//OpenCV中无此项,采用widthStep代替
|--charcolorModel[4];//颜色模型–OpenCV中忽略此项
[编辑]
2、矩阵与向量
[编辑]
(1)矩阵:
CvMat//2D矩阵
|--inttype;//元素类型(uchar,short,int,float,double)与标志
|--intstep;//整行长度字节数
|--introws,cols;//行、列数
|--intheight,width;//矩阵高度、宽度,与rows、cols对应
|--uniondata;
|--uchar*ptr;//datapointerforanunsignedcharmatrix
|--short*s;//datapointerforashortmatrix
|--int*i;//datapointerforanintegermatrix
|--float*fl;//datapointerforafloatmatrix
|--double*db;//datapointerforadoublematrix
CvMatND//N-维矩阵
|--inttype;//元素类型(uchar,short,int,float,double)与标志
|--intdims;//矩阵维数
|--uniondata;
||--uchar*ptr;//datapointerforanunsignedchar矩阵
||--short*s;//datapointerforashortmatrix
||--int*i;//datapointerforanintegermatrix
||--float*fl;//datapointerforafloatmatrix
||--double*db;//datapointerforadoublematrix
|
|--structdim[];//各维信息
|--size;//元素数目
|--step;//元素间距(字节为单位)
CvSparseMat//N-维稀疏矩阵
[编辑]
(2)一般矩阵:
CvArr*//仅作为函数定义的参数使用,
//表明函数可以接受不同类型的矩阵作为参数,
//例如:
IplImage*,CvMat*甚至是CvSeq*.
//矩阵的类型通过矩阵头的前4个字节信息来确定
[编辑]
(3)标量:
CvScalar
|--doubleval[4];//4D向量
初始化函数:
CvScalars=cvScalar(doubleval0,doubleval1=0,doubleval2=0,doubleval3=0);
//Example:
CvScalars=cvScalar(20.0);
s.val[0]=20.0;
注意该初始化函数的函数名与对应的结构体名称几乎同名,差别仅在于函数名第一个字母是小写的,而结构体名第一个字母是大写的。
它并不是一个C++构造函数。
(译注:
类似的还有cvMat与CvMat、cvPoint与CvPoint等等)
[编辑]
3、其它结构类型
[编辑]
(1)点:
CvPointp=cvPoint(intx,inty);
CvPoint2D32fp=cvPoint2D32f(floatx,floaty);
CvPoint3D32fp=cvPoint3D32f(floatx,floaty,floatz);
//E.g.:
p.x=5.0;
p.y=5.0;
[编辑]
(2)矩形框大小(以像素为精度):
CvSizer=cvSize(intwidth,intheight);
CvSize2D32fr=cvSize2D32f(floatwidth,floatheight);
[编辑]
(3)矩形框的偏置和大小:
CvRectr=cvRect(intx,inty,intwidth,intheight);
[编辑]
四、图像处理
[编辑]
1、图像的内存分配与释放
[编辑]
(1)分配内存给一幅新图像:
IplImage*cvCreateImage(CvSizesize,intdepth,intchannels);
size:
cvSize(width,height);
depth:
像素深度:
IPL_DEPTH_8U,IPL_DEPTH_8S,IPL_DEPTH_16U,
IPL_DEPTH_16S,IPL_DEPTH_32S,IPL_DEPTH_32F,IPL_DEPTH_64F
channels:
像素通道数.Canbe1,2,3or4.
各通道是交错排列的.一幅彩色图像的数据排列格式如下:
b0g0r0b1g1r1...
示例:
//Allocatea1-channelbyteimage
IplImage*img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
//Allocatea3-channelfloatimage
IplImage*img2=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
[编辑]
(2)释放图像:
IplImage*img=cvCreateImage(cvSize