
学习目标:
掌握OpenCV最基本的安装配置、OpenCV类库中最基本的类和函数的使用方法。
一、OpenCV
1、OpenCV十一个优秀的开源图像处理算法库,包含一系列C函数和少量的C++类,实现了图像处理和计算机视觉方面的很多通用算法。
2、OpenCV为Intel公司的Integrated Performance Primitives(IPP)提供了透明接口。如果有为特定处理器优化的IPP库,OpenCV将在运行时自动加载这些库。
3、OpenCV库特点及组成
优点:(1)跨平台——Windows、Linux;(2)免费(开放源代码);(3)速度快使用方便;(4)可扩展性好;(5)通用的图像视频载入、保存和获取模块。
模块:(1)CxCore:基本结构和算法函数;(2)Cv:图像处理和计算机视觉功能(主要的OpenCV函数);(3)CvAux:PCA,HMM等函数;(4)HighGUI:用户交互部分。(5)ML:机器学习模块。(6)CvCam:(加入到HighGUI中)
4、OpenCV资源
(1)OpenCV中文站:www.opencv.org.cn (中科院自动化所维护)
(2)OpenCV中文论坛:www.opencv.org.cn/forum
(3)OpenCV英文http://opencvlibrary.sourceforge.net/
(4)项目主页、源代码及文档下载:http://sourceforge.net/projects/opencvlibrary
(5)书籍
学习OpenCV(Learning OpenCV)
基于OpenCV的计算机视觉技术实现
OpenCV教程(基础篇)
5、支持开发语言:C、Python
6、版本:
1.0、1.2、2.0、2.1、2.2、2.3、2.3.1
我们使用的是1.0版本
7、安装
(1)安装OpenCV
(2)配置window环境变量
(3)配置Visual C++ 6.0
全局设置
菜单Tools->Options->Directories:先设置lib路径,选择Library files,在下方填入路径:
C:\\Program Files\\OpenCV\\lib
然后选择include files,在下方填入路径:
C:\\Program Files\\OpenCV\\cxcore\\include
C:\\Program Files\\OpenCV\\cv\\include
C:\\Program Files\\OpenCV\\cvaux\\include
C:\\Program Files\\OpenCV\\ml\\include
C:\\Program Files\\OpenCV\\otherlibs\\highgui
C:\\Program Files\\OpenCV\\otherlibs\\cvcam\\include
然后选择source files,在下方填入路径:
C:\\Program Files\\OpenCV\\cv\\src
C:\\Program Files\\OpenCV\\cxcore\\src
C:\\Program Files\\OpenCV\\cvaux\\src
C:\\Program Files\\OpenCV\\otherlibs\\highgui
C:\\Program Files\\OpenCV\\otherlibs\\cvcam\\src\\windows
项目设置
每创建一个将要使用OpenCV的VC Project,都需要给它指定需要的lib。菜单:Project->Settings,然后将Setting for选为All Configurations,然后选择右边的link标签,在Object/library modules附加上
cxcore.lib cv.lib ml.lib cvaux.lib highgui.lib cvcam.lib
二、OpenCV体系结构
1、常用数据结构体系
基础数据类型包括:图像类的IplImage、矩阵类的CvMat、可变集合类的CvSeq、CvSet、CvGraph以及用于柱状图的混合类CvHistogram
帮助数据类型包括:二维点坐标CvPoint、图像高宽的CvSize,迭代过程结束条件CvTermCriteria、图像转换内核的IplConvKernel和空间力矩的CvMoments。
如:CvSize
Typedef struct CvSize
{int width;
Int height;
}CvSize;
与CvSize相关的构造函数:
Inline CvSize cvSize(int width, int height);
2、常用类体系
CxCore、CV、CvAux、HighGUI、CvCam
所有的函数命名都以“cv”开头,然后是该函数的行为或者作用目标。
如:用来创建图像的函数“cvCreateImage”、载入图像的函数“cvLoadImage”。
3、示例
例1、显示图像(2.2.3)
#include "cv.h" /* OpenCV的基本函数头文件 */
#include "highgui.h" /* OpenCV的图像显示函数头文件 */
void main()
{
IplImage *src; /* 定义IplImage指针变量src */
/* 将src指向当前工程文件目录下的图像
/* 定义一个窗口名为src的显示窗口 */
/* 在src窗口中,显示src指针所指的图像 */
cvWaitKey(0); /* 无限等待,即图像总显示 */
/* 保存图像到D盘根目录下 */
/* 销毁窗口 */
cvReleaseImage(&src); /* 释放IplImage指针src */
}
说明:
(1)cvLoadImage:图像载入函数
IplImage * cvLoadImage(const char * filename, int iscolor=1);
Iscolor:默认读取图像的原通道数(-1),强制转化读取图像为灰度图(0),读取彩色图(1)。
(2)cvNamedWindow:窗口定义函数
Int cvNamedWindow(const char * name,unsigned long flags);
Flags:CV_WINDOW_AUTOSIZE(1)和0
(3)cvShowImage:图像显示函数
Void cvShowImage(const char * name,const CvArr * image);
(4)cvSaveImage:图像保存函数
Int cvSaveImage(const char * filename,const CvArr * image);
(5)cvDestroyWindow:窗口销毁函数
Void cvDestroyWindow(const char * name);
(6)cvReleaseImage:图像销毁函数
Void cvReleaseImage(IplImage ** image);
(7)cvCreateImage:创建图像
IplImage * cvCreateImage(CvSize size, int depth, int channels);
//depth:图像元素的位深度;channels:每个像素的颜色通道数量
例2 添加按钮,显示图像(2.3)
创建对话框MFC项目,添加按钮
void COpenCVTest2Dlg::OnLoadingimage()
{
OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,
char title[]= {"Open Image"};
dlg.m_ofn.lpstrTitle= title;
if (dlg.DoModal() == IDOK) {
CString path= dlg.GetPathName();
// ImageProcessor ip(path);
}
}
添加ImageProcessor类
#if !defined IMAGEPROCESSOR
#define IMAGEPROCESSOR /* 宏定义 */
#include "cv.h" /*包含cv类头文件 */
#include "highgui.h" /*包含highgui类头文件 */
class ImageProcessor
{
IplImage* img;
public:
ImageProcessor(CString filename, bool display=true)
{
img = cvvLoadImage( filename );
if (display)
{
cvvNamedWindow( "Original Image", 1 );
/*1为CV_WINDOW_AUTOSIZE,表示窗口尺寸与图像原始尺寸相同*/
cvvShowImage( "Original Image", img ); /* 显示图片 */
}
}
~ImageProcessor()
{
cvReleaseImage( &img ); /* 释放图象指针 */
}
};
#endif
例3、用命令行传递图像名称(3-1)
#include "cv.h"
#include "highgui.h"
int main(int argc, char ** argv)
{
IplImage * pImg;
if (argc==2 && (pImg=cvLoadImage(argv[1],1))!=0)
{
cvNamedWindow("Image",1); //创建窗口
cvShowImage("Image",pImg);
cvWaitKey(0);
cvDestroyWindow("Image");
cvReleaseImage(&pImg);
return 0;
}
else if (argc==3 && (pImg=cvLoadImage(argv[1],1))!=0)
{
IplImage * pImg2=cvCreateImage(cvGetSize(pImg),pImg->depth,pImg->nChannels);
cvCopy(pImg,pImg2,NULL);
cvSaveImage(argv[2],pImg2);
cvNamedWindow("Image",1);
cvShowImage("Image",pImg);
cvWaitKey(0);
cvDestroyWindow("Image");
cvReleaseImage(&pImg);
return 0;
}
return -1;
}
例4图像大小变换(3-2)
#include "cv.h"
#include "highgui.h"
#include "math.h"
int main(int argc, char ** argv)
{
IplImage * src =0;
IplImage * dst =0;
double scale = 0.618;
CvSize dst_cvsize;
if (argc == 2 && (src=cvLoadImage(argv[1],1))!=0)
{
dst_cvsize.width = (int) (src->width * scale);
dst_cvsize.height= (int) (src->height * scale);
dst = cvCreateImage(dst_cvsize, src->depth, src->nChannels);
cvResize(src,dst,CV_INTER_LINEAR);
cvNamedWindow("src",CV_WINDOW_AUTOSIZE);
cvNamedWindow("dst",CV_WINDOW_AUTOSIZE);
cvShowImage("src",src);
cvShowImage("dst",dst);
cvWaitKey(0);
cvReleaseImage(&src);
cvReleaseImage(&dst);
cvDestroyWindow("src");
cvDestroyWindow("dst");
}
return 0;
}
说明:
(1)cvSize类型:表示矩形尺寸的结构,分别定义了矩形的宽度和高度。
cvSize cvsize=cvSize(800,600);
cvSize cvsize;
cvsize.width=800;
cvsize.height=600;
(2)cvResize:图像大小变换
Void cvResize(const CvArr * src, CvArr * dst, int interpolation=CV_INTER_LINEAR);
Src:输入图像,dst:输出图像,interpolation:修改、补插方法(CV_INTER_NN:最近邻插值,CV_INTER_LINEAR:双线性插值,CV_INTER_AREA:像素面积相关重采样,CV_INTER_CUBIC:立方插值)。
例5:边缘检测(3-3)
#include "cv.h"
#include "highgui.h"
int main(int argc, char ** argv)
{
IplImage * pImg =NULL;
IplImage * pCannyImg =NULL;
if (argc == 2 && (pImg=cvLoadImage(argv[1],0))!=0)
{
pCannyImg = cvCreateImage(cvGetSize(pImg),IPL_DEPTH_8U,1);
cvCanny(pImg,pCannyImg,50,150,3);
cvNamedWindow("canny",CV_WINDOW_AUTOSIZE);
cvShowImage("canny",pCannyImg);
cvWaitKey(0);
cvReleaseImage(&pCannyImg);
cvDestroyWindow("canny");
return 0;
}
return -1;
}
说明:
cvCanny:图像边缘检测
void cvCanny(const CvArr * image,CvArr * edges,double threshold1,double threshold2,int aperture_size=3);
参数:
Image:输入图像,edges:输出边缘图像,threshold1:第一个阈值,threshold2:第二个阈值,小阈值用来控制边缘连接,大阈值用来控制边缘的初始分割。aperture_size:Sobel算子内核大小。
其他常用函数还有:cvSobel、cvLaplace、cvErode、cvDilate、cvSmooth、cvThreshold等。
图像分类
(1)黑白图像:图像的每个像素只能是黑或者白,没有中间的过渡,故称为二值图像,二值图像的像素值为0、1。
(2)灰度图像:每个像素信息由一个量化的灰度级来描述的图像,没有彩色信息。
(3)彩色图像:每个像素信息由RGB三原色构成的图像,其中RGB是由不同的灰度级来描述的。
例6:视频播放(3-4)
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
int main(int argc, char ** argv)
{
cvNamedWindow("test",CV_WINDOW_AUTOSIZE);
CvCapture * capture =cvCreateFileCapture(argv[1]);
IplImage * frame;
while (1)
{
frame=cvQueryFrame(capture);
if (!frame) break;
cvShowImage("test",frame);
char c=cvWaitKey(33);
if (c==27) break;
}
cvReleaseCapture(&capture);
cvDestroyWindow("test");
}
说明:
(1)CvCapture:视频获取结构
(2)cvCreateFileCapture:初始化从文件中获取视频
CvCapture* cvCreateFileCapture( const char* filename );
函数cvCreateFileCapture给指定文件中的视频流分配和初始化CvCapture结构。 当分配的结构不再使用的时候,它应该使用cvReleaseCapture函数释放掉。
(3)cvCreateCameraCapture :初始化从摄像头中获取视频
CvCapture* cvCreateCameraCapture( int index );
index :要使用的摄像头索引。如果只有一个摄像头或者用哪个摄像头也无所谓,那使用参数-1应该便可以。
函数cvCreateCameraCapture给从摄像头的视频流分配和初始化CvCapture结构。目前在Windows下可使用两种接口:Video for Windows(VFW)和Matrox Imaging Library(MIL); Linux下也有两种接口:V4L和FireWire(IEEE1394)。
(4)cvQueryFrame :从摄像头或者文件中抓取并返回一帧
IplImage* cvQueryFrame( CvCapture* capture );
函数cvQueryFrame从摄像头或者文件中抓取一帧,然后解压并返回这一帧。这个函数仅仅是函数cvGrabFrame和函数cvRetrieveFrame在一起调用的组合。返回的图像不可以被用户释放或者修改。抓取后,capture被指向下一帧,可用cvSetCaptureProperty调整capture到合适的帧。
注意: cvQueryFrame返回的指针总是指向同一块内存。建议cvQueryFrame后拷贝一份。而且返回的帧需要FLIP后才符合OPENCV的坐标系。若返回值为NULL,说明到了视频的最后一帧。
cvReleaseCapture :释放CvCapture结构
void cvReleaseCapture( CvCapture** capture );
函数cvReleaseCapture释放由函数cvCreateFileCapture或者cvCreateCameraCapture分配的CvCapture结构。
注:若从capture中使用cvQueryFrame获取图像指针,在releaseCapture的时候同时函数释放图像指针,用户不用再自己释放。
