本书全面系统地介绍了数字图像处理技术的理论与方法,内容涉及几何变换、灰度变换、图像增强、图像分割、图像去噪、小波变换、形态学处理、多尺度融合、偏微分方程应用、正交变换与图像压缩、边缘及轮廓检测、图像复原、图像去雾、多尺度空间构建与特征匹配等15大核心话题。工欲善其事,必先利其器。本书所有算法均配有完整的MATLAB实现代码,并以此为基础详细介绍了MATLAB中与图像处理有关的近200个函数的使用方法,便于读者学习与实践。此外,本书还提供了丰富的在线支持资源,方便为读者答疑解惑及提供辅助资料下载。
前言
1. 引子
于本书之前,笔者已经在数字图像处理领域陆续出版了多部作品。彼时我的新作《数字图像处理:技术详解与Visual C++实践》一书刚刚问世,余便开始筹划或许应该出一本用MATLAB来作为描述语言的数字图像处理书籍。此前的“Visual C++数字图像处理”系列已经出到了第三版,先后重印近十次,可以说在业界赢得了颇佳的成绩。许多读者纷纷来信与笔者讨论技术问题,交流心得感想。此外,据不完全统计,前两本图书的科技文献参考引用量已经超过百余篇次。另根据中国互动出版网的实际销售数据统计,前两个版本的图书自问世以来一直居于数字图像处理类图书畅销排行榜前五名之列(由于第三版刚刚问世暂无统计数据)。可见这一系列的图书在市场表现上也值得肯定。
当前,关于数字图像处理开发方面的书籍主要分为两大阵营,即Visual C++(或C/C++)和MATLAB,且二者可谓各有千秋,不分伯仲。但笔者此前的作品却一直专注于Visual C++环境下的数字图像处理技术。所以,在这里笔者也想同各位分享一下二者之于图像处理开发中的异同。
MATLAB很适合做科学研究,借助它提供的各种功能强大的工具箱,图像处理编程将变得非常轻松,代码也更简短。MATLAB中提供的许多现成可用的函数大大简化了实际开发过程,一个显而易见的事实就是用MATLAB进行图像处理编程甚至无须考虑内存的分配与回收这种琐碎的问题。
相对而言,使用Visual C++进行图像处理开发难度较大,需要考虑的问题更多,很多矩阵运算函数都需要自己编写。读入不同格式和类型的图像数据,然后进行解码,这种问题也没有现成的方法。但是,Visual C++在工业开发中则更实用,可移植性、通用性以及效率表现都更优越。
就绝对的初学者而言,我还是建议他们从Visual C++环境入手。MATLAB用起来很简单、很方便,但是它掩盖了太多细节,不利于读者深入理解底层实现,也不利于读者打好基础。不积跬步,无以至千里。最初学习时如果基础不打牢,后续再讲什么创新其实都是纸上谈兵、空中楼阁。在读者对底层实现比较清楚的情况下,进行后续的科学研究时,再去考虑使用MATLAB可能才是明智的选择。
以图像编解码为例。在MATLAB中,只需一个函数就能将图像读入,然后得到一个现成的像素矩阵。在这个过程中,就忽略了很多细节。而在Visual C++中,如果不调用现成的函数库(例如OpenCV),那么就需要自己编写解码函数。这时就不得不去考虑不同图像格式的编码方案和算法,考虑图像文件在存储器上到底是如何存储的等问题。这时才会知道原来图像被写进存储器的时候不是简简单单的一个像素矩阵,原来还有调色板、文件头等内容。
我经常喜欢拿武侠小说《天龙八部》中的一段情节来向读者说明此中的道理,相信读者对这部曾经被多次搬上银幕的金庸作品已经耳熟能详了。书中讲到有个名叫鸠摩智的番僧一心想练就绝世武学,而且他也算是个相当勤奋的人了。但是,他错就错在太过于急功近利,甚至使用道家的小无相功来催动少林绝技。看上去威力无比,而且可以在短时间内“速成”,但实则后患无穷。最终鸠摩智走火入魔,前功尽废,方才大彻大悟。这个故事其实就告诉我们打牢基础是非常重要的,特别是要取得更长足的发展,就更是要对基本原理刨根问底,力求甚解,从而做到庖丁解牛,烂熟于心。
所以,总结起来,笔者撰写本书的目的主要是考虑那些对于Visual C++(或者C/C++)编程不是特别熟悉,而对于MATLAB编程有一定基础,又希望深入学习图像处理技术的读者的实际需求,以期帮助他们深入剖析相关理论,并为他们继续深入研究助一臂之力。
2. 天书VS.儿歌三百首
说到这里,我想告诉读者本书并非一本MATLAB的入门书。更准确地说,本书是一本介绍数字图像处理技术的书,只不过书中的描述语言选择了MATLAB。因此,我希望阅读和使用本书的读者应当具有一定的MATLAB基础。当然,笔者也确信无论你现在处于图像处理学习的哪个层次,本书都会在某种程度上帮到你。之所以这样说,主要是因为本书关于理论部分的描述和讲解都是在畅销系列图书“Visual C++数字图像处理”数度再版后精心锤炼和筛选之后留存的精华部分。这些地方笔者均经过反复雕琢,力求做到深入浅出、翔实全面。
众所周知,数字图像处理的理论基础主要就是数学,而数学本身又是一个极其庞杂的系统,它的分支层出不穷,不计其数。读者现在所要学习的数字图像处理,至少涉及数学中三门主干课程的内容,即高等数学、线性代数和概率论。在本书中,读者会发现这些内容几乎无处不在,以高等数学中的泰勒公式为例,本书中就至少用到过三次以上。除了上述提到的大家在本科阶段就应学过的三门数学课程之外,本书还用到了复变函数、偏微分方程和泛函理论等内容。从这个角度说,数字图像处理对于很多学生而言,无异于“天书”。
霍金也说:“在书中每增加一条公式,读者就会流失一半”。如果你现在手捧着的是这样一部由公式罗列而成的天书,相信很多读者都会望而却步。当然,数学公式亦有数学公式的好处。从数学角度解释图像处理算法的原理,是深入到了算法本质层面的。如果不谈任何公式,而把如何处理一张图片的方法用文字描述的方式告诉读者也不是不可能的,但是这其实只是让读者“知其然,而不知其所以然”。这样的弊端就在于读者想进行更为深入的研究时,几乎难如登天。那么有没有什么方法能够调和这两者之间的矛盾,而把“天书”写得如同“儿歌三百首”一样通俗易懂呢?
笔者一直以把复杂晦涩的理论写得深入浅出、浅显明了为终极目标。但是要做到这一点实非易事,为此笔者也进行了诸多探索。所有数学公式集中爆发的地方必然都是读者学习上的薄弱环节和理解上的峻岭鸿沟。但本书绝非仅仅简单地罗列公式,为了帮助读者打牢根基,融会贯通,在写本书时,笔者主要做了三项工作:首先,给足背景的铺垫,而非凭空丢来一个公式。例如,本书在介绍PM方程时,为了让读者能够真正理解它的原理,笔者是从一个简单的物理现象开始一步步引导读者进行学习的;其次,在给出公式的同时,笔者基本都给出了最为浅显的证明过程,而且力求过程之详细。例如,在率失真理论的介绍中,对于这部分公式的证明,国内教材都是以詹森不等式为基础的,但是读者不禁又困惑了,詹森不等式为什么会成立呢?所以笔者在这些地方完全摒弃了詹森不等式,而是用初等数学中的基本不等式来开展有关证明,这无疑会大大减少读者心中的困惑;最后,在某些时候我们可能需要的是严密的数学证明,而有些时候可能需要的是感性的认识。笔者试图将两者有机地结合在一起,需要严密的时候就尽量严密,需要感性的时候就努力感性。例如,我们在推导欧拉-拉格朗日方程时,其实证明过程并不完全严格,但是从读者对于该公式的理解以及后续学习的可开展性上,这种程度的解释可能才是最佳的方式。
尽管为了能把理论讲得更明白、更透彻,笔者查阅了许多资料,进行了诸多求索,但科技文章写作永远是留有遗憾的艺术。可能本书仍有许多未尽之处,可能本书还不能完全把“天书”降低到“儿歌三百首”那种地步,但笔者相信只要读者能够仔细研读本书,定能有所长进,有所收获。
3. 一些建议
为了使读者充分用好本书,提升自我,笔者也想给各位提点学习图像处理以及使用本书方面的建议。
纸上得来终觉浅,绝知此事要躬行。
数字图像处理绝对是面向应用的技术,因此学习它的第一精要就是绝对不能“纸上谈兵”。特别是好的想法也要通过实践的检验和验证才能有说服力和实用价值。本书提供了涉及的全部算法的完整MATLAB实现代码,而读者在使用时切不可大行“拿来主义”,完全不假思索地照搬照抄。最好是可以亲自动手运行一下,这样既能帮助巩固所学之理论,又能增进动手能力。更重要的是,当读者面对实际的开发问题时心中也更有底气、更自信。当然,要想在编程开发时做到得心应手、游刃有余,必然是要以对理论的深刻认知和绝对领悟为前提的。因此,在面对每一个具体的算法时,读者都应当努力做到知其然,更知其所以然。而不能因一些模棱两可、似是而非的理解就沾沾自喜、自以为是。
合抱之木,生于毫末;九层之台,起于累土。
学习和研究的过程都是一个不断积累的过程。做高深学问当然应该成为每个学子的追求,但是这肯定不能成为你研究的开端。很多人习惯于接到一个问题时,马上查资料看当前学术界解决该问题的最先进方法是什么,然后一头扎进去。学术研究就像是一个接力的过程,即使最先进、最有效的方法也必然是基于前人的成果发展而来的。如果你一开始就钻到所谓的最新方法上,你可能很快就会发现自己的困惑和不解实在太多了,这样往往会搞得自己筋疲力尽、事倍功半。不积跬步,无以致千里;不积小流,无以成江海。因此学习也应该讲究循序渐进,切忌妄图一蹴而就。特别是对于数字图像处理这个领域来说,很多当前流行的技术也都是在一些简单算法的合并重组之后发展而来的。例如SIFT特征检测中就用到了像直方图、高斯滤波等这些基础的算法。更重要的是,了解一个学科或者一门技术,应该设法理清它的发展脉络。要想明白前人的方法有哪些优点,又有哪些缺点,后来的改进方法是从哪个角度出发设计而来的。如果理清了这个脉络,那么你在研究过程中才好把握准方向。这一点会在边缘检测那一章体现得尤为明显。
无冥冥之志者,无昭昭之明;无惛惛之事者,无赫赫之功。
数字图像处理的相关理论都是比较晦涩的、复杂的。对此读者务必要知难而上,挑硬骨头啃。要想后续能够取得一定的成绩,前期就必须劳其筋骨,饿其体肤。最开始可能会感觉很痛苦,但是这样做必然会使后续的道路更顺畅、更平坦。而在这个过程中,读者一是不要半途而废、浅尝辄止;二就是要沉得下心,沉得住气。志向越是高远,脚步就越是要踩稳走实。学习任何知识都不可能是一日之功,长期的积累往往必不可少。所以,不要因为一时不顺而灰心丧气。就像古人所说的:“试玉要烧三日满,辨材须待七年期;向使当初身便死,一生真伪复谁知?”特别是在研究陷入一时的困境时,更要坚持。其实每一次失败往往都是朝成功迈进了一步。而我们之所以会困惑,往往是因为不知道距离成功到底还有多远。但大家始终都应该相信,天道酬勤,付出总会有回报的。
4. 关于本书
白居易说:“文章合为时而著,歌诗合为事而作。”我想不管是写诗还是做文章都要有些现实意义。特别是对于类似数字图像处理这种发展非常迅猛的领域,每天都有新方法和新理论诞生,读者当然不能总是拘泥于最原始、最简单的一些知识。本书考虑到当前研究的一些热门话题,着重在读者深入研究时可能会遇到的重点、难点上花费了较多精力。类似频域变换(包括小波变换)、基于偏微分方程的应用以及图像特征检测等内容,尽管已经取得了长足的发展,但仍然是理论界的热门话题。这些内容的特点是,首先是对于数学要求高,理解起来比较费力;其次是许多读者在进行后续深入研究时往往又需要用到这些知识。因此,这部分内容也是建议读者重点研习的部分。本书在这些内容上花费了大量的笔墨,就是希望能够帮助读者叩开久闭的山门,同时也希望为读者挺进这些方兴未艾的领域披荆斩棘、扫除障碍。
本书在保持系列作品突出实践的特色基础之上,兼有深入浅出、通俗易懂的优点。在此基础上,本书详细地介绍了包括频域变换、几何变换、灰度变换、形态学处理、图像增强、图像分割、小波变换和偏微分方程降噪等十多个数字图像处理领域的核心话题,并配有完整的MATLAB实现代码。可以说,本书更适合期望对相关理论进行系统学习和深入研究的读者。
在本书写作过程中,笔者参考研读了众多先贤以及业界专家的著作,在此谨向他们表示衷心的感谢。其中需要特别提及的是,暗通道图像去雾算法中用到的导向滤波代码来自微软亚洲研究院的何恺明博士;种子填充算法的部分代码,以及SURF特征检测函数代码来自荷兰特温特大学Ir. D. Kroon博士;基于Hough变换的直线检测部分,在不使用系统函数情况下获取的处理结果由美国马里兰大学的Tao Peng所编写之程序得到;图像的双边滤波程序代码和基于全变分的图像去噪代码最初版本分别来自布朗大学的Douglas Lanman 博士和以色列理工学院的Gilboa Guy教授,作者稍有修改。另外,笔者在研究KAZE特征检测算法时,承蒙佐治亚理工学院的Pablo F. Alcantarilla博士不吝赐教,笔者深表感谢。最后笔者还要感谢的人有胡俊、向永歆、吴凯、何鹏,感谢他们在本书撰写过程中提供的无私帮助,以及对作者本人长久以来的大力支持。
欢迎读者就书中的问题同笔者展开交流,具体请访问笔者在CSDN上的博客http://blog.csdn.net/baimafujinji,关于本书的勘误和补遗也将实时发布在此博客上。另外,书中所有示例程序的完整代码也全部可以在此博客上得到,具体请见“MATLAB数字图像处理”专栏。本书所有代码均在MATLAB 8.0版本上测试通过,不同版本的程序在执行代码过程中可能存在差异,这一点请读者留意。此外,附录中还提供了本书中反复被使用到的几个数学知识点的详细介绍和证明过程,建议有深入学习需求的读者参阅。
自知论道需思量,几度无眠一文章。由于时间和能力有限,书中纰漏在所难免,真诚地希望各位读者和专家不吝批评斧正。
代码资源呢