第1章 数字图像处理软件开发概述
“心有多大,舞台就有多大。”开发数字图像处理软件,需要想象力,而要把想象变成现实,则需要得心应手的开发平台。
目前常用于开发数字图像处理软件的平台可以粗略地分为通用平台和专用平台两大类。通用平台不是专门针对数字图像处理软件开发而打造的,但是却可以用于开发数字图像处理系统,如Visual C++、Matlab等。为了提高开发效率,通用平台往往结合专门的软件包(如OpenCV、VTK 等)或工具箱(如Matlab中的Image Processing工具箱等)进行数字图像处理软件开发。专用平台则是专为数字图像处理或更进一步的机器视觉系统开发量身定制的,这类开发平台中均内置了大量专门用于数字图像处理的数据结构、对象、函数或组件模块,可供开发人员方便地调用,在更高的层次上进行数字图像处理系统的开发,如Halcon、VisionPro等。本章主要介绍本书将要用到的几种开发平台及其配置和使用方法。
本章要点
Visual C++处理数字图像的基本方法
在Visual C++中使用OpenCV
在Visual C++中使用VTK
1.1 Visual C++
“工欲善其事,必先利其器。”Visual C++便是众多开发工具中的“一把所向披靡的利器”。Visual C++(简称VC)是Microsoft公司的Visual Studio开发工具箱中的一个C++程序开发环境。自诞生以来,凭借着C++语言的强大威力、开发环境的良好支持,以及与Windows操作系统的“血缘”关系,一直是Windows操作系统环境下最主要的开发工具之一。使用VC可以完成各种各样应用程序的开发,从底层软件到上层直接面向用户的软件,而且用VC开发出的产品与Windows操作系统最具“亲和力”。掌握了VC,就等于进入了Windows编程的自由王国。VC在数字图像处理软件开发中也占据着极其重要的地位。
第1章
Visual C++
1.1.1 Visual C++概述
VC是一个面向对象的可视化集成开发系统,它不但具有程序框架自动生成、灵活方便的类管理、代码编写和界面设计集成交互操作、可开发多种程序等优点,而且通过简单的设置就可使其生成的程序框架支持数据库接口、OLE2、WinSock网络、3D控制界面。VC以拥有语法高亮、智能感知(在编辑环境中,光标悬停在函数上时显示类定义和注释,键入函数或属性名时可以自动完成这些名称的输入)、高级除错、最小重建及累加链接功能而著称,这些特功能有助于缩短程序编辑、编译及链接的时间花费,在大型软件开发中效果尤其显著。
VC已历经数个版本,伴随着Microsoft .NET计划的展开,又诞生了一系列VC.NET版本,从当年的1.0版本到现在最新的VC 2010(10.0版本),VC在界面、功能、库支持方面都增强了很多。
VC 1.0是Microsoft公司于1993年推出的,它集成了MFC 2.0(MFC是一个以C++类的形式封装了Windows API的基础类库,其中包含一个应用程序框架、大量Windows句柄封装类和很多Windows的内建控件和组件的封装类,1992年随微软的Microsoft C/C++ 7.0编译器发布,可以减少应用程序开发人员的工作量),可算是Microsoft C/C++ 7.0的更新版本。VC 1.5集成了MFC 2.5,增加了OLE 2.0 和支持MFC的ODBC。VC 2.0集成了MFC 3.0。VC 4.0集成了MFC 4.0,这个版本是专门为Windows 95以及Windows NT设计的。由于VC 2.0是在Windows 95之前发布的,且发布时间与Windows 95非
常接近,当Windows 95发布时,VC 4.0也已经发布了,很多程序员直接从1.x过渡到4.0,把2.x跳过去了,所以VC 2.0的应用并不广泛。VC 5.0集成了MFC 4.21,是4.2版以来比较大的一次升级。VC 6.0集成了MFC 6.0,于1998年发布,发布至今一直被广泛地用于大大小小的项目开发。VC.NET 2002(VC 7.0)于2002年发布,集成了 MFC 7.0,支持.NET 1.0,支持链接时代码生成和调试执行时检查。VC.NET 2003(VC 7.1)集成了MFC 7.1,于2003年发布,支持.NET 1.1。VC 2005(VC 8.0)集成了MFC 8.0,于2005年发布,支持.NET 2.0,该版本引进了对C++/CLI语言和OpenMP的支持。VC 2008(VC 9.0)集成了MFC 9.0,于2007年发布,支持.NET 3.5。VC 2010(VC 10.0)于2010年发布,集成了MFC 10.0,支持.NET 4.0,支持C++0x新标准。
在数字图像处理领域,积累了大量采用VC 6.0开发的应用软件。尽管VC 6.0版本代码可以自动迁移到VC.NET版本,但由于VC.NET各版本与VC 6.0并不完全兼容,有时迁移后并不能直接
编译通过,还需要对源程序做必要的修改。
1.1.2 Visual C++处理数字图像的基本方法
数字图像文件的格式多达几十种,但多数都是经过压缩的,不便于直接处理。数字图像处理时最常使用的文件格式是未经压缩的位图图像(BMP图像文件),其他格式的压缩图像一般都要
数字图像处理典型案例详解数字图像处理软件开发概述
windows开发平台先解压缩成位图图像再进行处理。本节主要介绍用VC处理位图的基本方法。
Windows中的位图有DDB(Device-dependent Bitmap)和DIB(Device-independent Bitmap)两种格式,它们的文件扩展名都是“.bmp”。
DDB位图又叫GDI(Graphics Device Interface,图形设备接口)位图,它是一种GDI对象,用句柄HBITMAP来操作,或者用MFC类CBitmap的成员函数来操作。在CBitmap中包含一种和Windows的GDI模块相关的Windows数据结构,该数据结构是与设备相关的,DDB位图只能显示在颜模式与其匹配的显示设备上。
DIB位图则能保证用某个应用程序创建的位图图像可以被其他应用程序装载且显示效果相同。DIB位图的与设备无关性主要体现在以下两个方面:1)DIB的颜模式与设备无关。例如,一个256的DIB既可以在真彩显示模式下使用,也可以在16模式下使用。2)256(含)以下的DIB拥有自己的颜表,像素的颜独立于系统调板。
由于DIB不依赖于具体设备,因此可以用来永久性地保存图像,通常以后缀为“.bmp”的文件形式保存在磁盘中或作为资源存在于程序的EXE或DLL文件中,所以,需要保证图像的显示效果时,要使用DIB位图。DDB位图在匹配的显示设备上的显示速度要比DIB快,因此,当性能是主要问题时,应该采用DDB位图。
在VC中,可以通过CBitmap类、Image类、Bitmap类和CImage类来处理位图,但不同的类所能处理的位图种类不同,不同的VC版本对上述类的支持也不同。
CBitmap类继承自CGdiObject,是封装了GDI的位图,提供成员函数来操纵位图。在使用CBitmap对象之前需要先构造CBitmap对象,再用其初始化成员函数与一个位图句柄关联起来,然后便可以调用该CBitmap对象的其他成员函数了。CBitmap类主要用于处理DDB位图,封装了与DDB位图操作函数相关的数据结构和操作函数。结构体BITMAP定义了DDB位图的类型、宽度、高度、颜和像素值。CBitmap的LoadBitmap、CreateCompatibleBitmap、SetBitmapBits、GetBitmap等成员函数定义了对DDB位图的装载、创建、设定位值和属性查询等操作。创建或装入内存的位图必须用CDC::SelectObject函数来将其选入设备上下文中,然后用CDC的BitBlt(或StretchBlt)函数显示出来,该函数把源设备上下文中的位图复制到本身的设备上下文中,两个设备上下文可以是内存设备上下文,也可以是同一个设备上下文。StretchBlt函数必要时可按目标设备设置的模式进行图像的拉伸或压缩。
在VC.NET之前,MFC未提供现成的类来封装DIB,这给MFC用户带来很多不便。因为用户要想使用DIB,首先应该了解DIB的结构。DIB的颜信息存储在自己的颜表中,程序一般要根据颜表为DIB创建逻辑调板。在输出一幅DIB之前,程序应该将其逻辑调板选入到相关的设备上下文中并实现到系统调板中,然后再调用相关的GDI函数(如::SetDIBitsToDevice 或::StretchDIBits)输出DIB。在输出过程中,GDI函数会把DIB转换成DDB:先将DIB的颜
第1章
Visual C++
格式转换成与输出设备相同的颜格式,再将DIB像素的逻辑颜索引转换成系统调板索引。由于MFC未提供一个封装好的易用的DIB类,用户在使用DIB时将面临繁重的Windows API编程任务,所以传统的图像处理方法中一般都会把这些Win32 SDK中操作DIB位图的API封装起来并自定义为一个通用的类来使用,以减轻后续算法编写中的编程负担。
在VC.NET版本中,GDI+的Image类封装了对BMP、GIF、JPEG、PNG、TIFF、WMF和EMF图像文件的调入、显示、格式转换以及简单处理(如缩放、旋转、拉伸等)的功能。而Bitmap 类(注意不是
结构BITMAP)是从Image类继承的一个图像类(另一个从Image继承的类是Metafile 类),它封装了Windows位图操作的常用功能。例如,Bitmap::SetPixel和Bitmap::GetPixel分别用来对位图进行读写像素操作,从而可以为图像的柔化和锐化处理提供一种可能。这些功能和MFC 的新类CImage功能基本一样,如果仅用于图像的读取与显示,用Bitmap类或Image类是不错的选择,如果是做图像处理,则CImage可能更符合MFC程序员的编程习惯。
CImage类是VC.NET中MFC和ATL共享的新类,它能从外部磁盘中调入一个BMP、JPEG、GIF或PNG格式的图像文件加以显示,而且这些文件格式可以相互转换。CImage既能处理DIB 位图,也能处理非DIB位图,可以用Create或Load方法来创建或加载DIB位图的CImage对象,也可以使用Attach方法把一个非DIB位图连接给CImage对象,但不能使用下列方法(这些方法仅支持DIB位图):GetBits、GetColorTable、GetMaxColorTable、Entries、GetPitch、GetPixelAddress、IsIndexed、SetColorTable。要确定一个连接的位图是否是一个DIB位图,可用成员函数IsDibSection 来判断。CImage提供了HBITMAP操作符,因此用作参数的HBITMAP,都可以用CImage来替代。
由于在不同的Windows操作系统中CImage的某些性能是不一样的,因此在使用时要特别注意。例如,CImage::PlgBlt和CImage::MaskBlt只能在Windows NT 4.0 或更高版本中使用,但不能运行在Windows 95/98 应用程序中。CImage::AlphaBlend和CImage::TransparentBlt也只能在Windows 2000/98或更高版本中使用。即使是在Windows 2000上运行程序,也必须将stdafx.件中的WINVE
R和_WIN32_WINNT的预定义修改成0x0500才能正常使用。CImage可以在MFC 或ATL中使用。当使用CImage创建一个项目时,必须包含atlimage.件。
由于编程习惯或版本自动迁移等原因,不少在VC.NET平台上开发的程序依然使用自定义的DIB 类来处理DIB位图,而没有使用CImage类(本书的案例中也存在这样的现象),希望VC图像
处理编程的初学者不要被这种现象所误导,应该更多地重视CImage类的使用。
1.2 OpenCV
牛顿说:“如果说我能看得更远一些,那是因为我站在巨人的肩膀上。”对于用VC开发图像处理软件的程序员来讲,OpenCV就是巨人的肩膀。
数字图像处理典型案例详解数字图像处理软件开发概述
1.2.1 OpenCV概述
OpenCV(Open source Computer Vision library)是1999年由Intel公司开发的图像处理和计算机视觉
开放源码库,现在由Willow Garage实验室提供支持。OpenCV提供C++、C和Python接口(即将支持Java接口),可以运行在Linux、Windows、Mac OS和Android操作系统上。
OpenCV拥有包括500多个C/C++函数的跨平台的中、高层API,具有强大的图像和矩阵运算能力。截止到2012年年初,OpenCV已发展到2.3.1版本。每一次版本升级都伴随着众多的函数更新和优化。
早期版本的OpenCV包括CxCore、Cv、CxAuv、HighGUI和ml 5个主要模块。CxCore包括一些基本结构和算法函数,如数据结构与线性代数支持,主要提供对各种数据类型的基本运算功能;Cv主要实现图像处理和计算机视觉功能,包括图像处理、结构分析、运动分析、物体跟踪、模式识别及摄像机标定等功能;CxAuv是OpenCV附加库函数,包括一些实验性的函数,如View Morphing、三维跟踪、PCA(Principal Component Analysis)和HMM(Hidden Markov Model)等函数;HighGUI是用户交互部分,包括GUI(Graphical User Interface,图形用户接口)、图像视频I/O和系统调用函数等;ml是机器学习模块,主要内容为分类器。OpenCV中曾经还有一个CvCam 模块,但从1.1版本开始OpenCV便不再包含它,其功能被HighGUI所取代。
自2.2版本之后,OpenCV将原有的5个模块重组为12个小模块。
opencv_core:核心功能模块,包括基本结构、算法、线性代数、离散傅里叶变换、XML(Extensible Markup Language,扩展标识语言)和Y AML(Y AML Ain't Markup Language,即“Y AML不是标识语
言”之意,Y AML是一种能够被电脑识别的直观的数据序列化格式)文件I/O等。
opencv_imgproc:图像处理模块,包括滤波、高斯模糊、形态学处理、几何变换、颜空间转换、直方图计算等。
opencv_highgui:高层用户交互模块,包括GUI、图像与视频I/O等。
opencv_ml:机器学习模块,包括支持向量机、决策树、Boosting方法(一种用来提高弱分类器准确度的算法)等。
opencv_features2d:二维特征检测与描述模块,包括图像特征检测、描述、匹配等。
opencv_video:视频模块,包括光流法、运动模板、背景减除、目标跟踪等。
opencv_objdetect:目标检测模块,包括基于Haar特征或LBP(Local Binary Pattern,局部二值模式)特征的人脸检测、基于HOG(Histogram of Oriented Gradient,方向梯度直方图)特征的人体检测等。
opencv_calib3d:3D模块,包括相机标定、立体匹配、3D重建等。
opencv_flann:FLANN(Fast Library for Approximate Nearest Neighbors,近似最近邻快速算法库)接口模块,FLANN库中包含在高维空间中进行搜索和聚类的算法。
第1章
Visual C++
opencv_contrib:新贡献模块,包括一些开发者新贡献出来的尚不成熟的代码。
opencv_legacy:遗留模块,包括一些过期代码,用于保持向后兼容。
opencv_gpu:GPU(Graphic Processing Unit,图形处理器)加速模块,包括一些可以利用CUDA (Compute Unified Device Architecture,计算统一设备架构是一种由NVIDIA公司推出的通用并行计算架构,即一种编程模型,它包含了GPU内部的并行计算引擎)进行加速的函数。
早期版本的OpenCV为Intel公司的IPP(Integrated Performance Primitives,集成高性能原件)提供了透明接口,这意味着如果有为Intel的特定处理器优化的IPP库,OpenCV将在运行时自动加
载这些库。OpenCV 2.0版的代码已显著优化,无需IPP来提升性能,因此从2.0版开始OpenCV
不再提供IPP接口。
1.2.2 在Visual C++中使用OpenCV
在使用OpenCV编程之前,首先要进行安装和配置。OpenCV可以从网站sourceforge/ projects/opencvlibrary上免费下载。安装前要先认真阅读安装指南,确认OpenCV与VC版本之间是否匹配,两者不能任意混搭(如OpenCV 2.3.1不支持VC 6.0)。OpenCV中文网站(www. )上提供了各种版本的OpenCV的中文安装指南,可以参考。
要先安装VC,然后安装OpenCV。OpenCV的安装过程非常简单,按安装向导操作即可,这里不再赘述。较新版本的OpenCV有些情况下直接解压缩即可,不需要安装,具体要看相应版本的安装指南。若安装过程中出现“Add <…>\OpenCV\bin to the system PA TH”选项,选择该项,这样可以将OpenCV的“<…>\OpenCV\bin”路径加入到系统变量PA TH中。如果是直接解压缩的,须手动将相应的“<…>\OpenCV\bin”的完整路径加入到系统变量PA TH中。有些函数需要TBB(Thread Building Blocks,线程构建模块),所以需要将TBB所在的目录也加入到环境变量PA TH中。
然后配置VC,一是配置全局选项,指定OpenCV的头文件和库文件的路径,二是配置每个新建项目,在链接器的附加依赖项中添加所需的库文件(*.lib)。各种版本的配置方法是类似的,但是不同版本的配置参数均不同,随着版本始终在升级,此处不再列出,请读者配置时自行查阅相应版本的安装指南。
如果需要对OpenCV库进行重新编译(非必需步骤),可以从/cmake/resources/ software.html下载并安装CMake软件,用CMake生成VC项目,然后用VC打开项目文件(针
对VC.NET版本生成的是OpenCV.sln),重新生成即可。
在VC中使用OpenCV,先创建项目,然后为项目的Debug和Release配置附加依赖项(添加所需的OpenCV库文件),在程序中添加所需的OpenCV头文件(OpenCV 2.2以后的头文件与以前版本的不同),即可使用OpenCV库中的结构、函数和类,原型定义及具体用法可到opencv.itseez网站上查阅OpenCV开发文档或查阅随机安装的开发文档。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论