写在前面的话
数字图像处理系列的学习笔记是作者结合上海大学计算机学院《数字图像处理》课程的学习所做的笔记,使用参考书籍为《冈萨雷斯数字图像处理(第二版)(MATLAB版)》,同时学习过程中会参考网络学习资源。对于数字图像处理的学习不可能仅仅依靠作者所写的这一系列笔记,而是需要花时间和精力学习,本文只可作参考和交流之用。由于涉及此学科不久,在学习过程中难免存在错误,请读者不吝赐教。
数字图像处理绪论
数字图像处理(DIP)的研究目标和处理对象:
DIP的研究目标是获取信息,处理对象是数据。信息是图像或任意一种对象的具有价值的属性,而数据是信息的符号化载体。
*在人所接受的信息中约有60%来自视觉,20%来自听觉,剩余20%来自触觉、嗅觉、味觉(当然第六感未纳入考虑啦)。这一数据来源未加详察,只是通过这一或真或假的数据可以看出视觉信息对于人类信息获取的重要性。
图像、数字图像、数字图像处理
图像是可以使人产生视觉感知的实体,数字图像是图像在计算机内的存在形式,数字图像处理则是通过计算机或其他信息技术对数字图像进行处理,从而实现预期目的。
*数字图像处理并非只局限于可见光谱范围,从伽马射线到无线电波的整个波段,只要能够使用成像机器获取图像并转换成数字图像,都可使用DIP技术进行处理。
MATLAB在DIP中的作用
“MATLAB一切皆矩阵”,MATLAB提供了强大的数值计算功能,在MATLAB中将图像作为矩阵处理。除了基本的工具,MATLAB补充了许多针对特定应用需求的工具箱,图像处理工具箱(Image Processing Toolbox)就是其中之一。
对于MATLAB的应用,只要有C语言的良好基础,就能得心应手。
DIP中MATLAB的学习
作者建议首先有C语言基础,不需特意学习MATLAB,在使用中慢慢积累就很有效。
图像工程(宏观视角看DIP)
图像工程有三个层次:图像处理(像素级处理)、图像分析(从像素到关于目标的描述数据)、图像理解(图像中有什么目标、目标间有什么关系、图像是什么场景、如何应用场景等)。
图像处理的内容
- 图像增强:增强有用信息,减少干扰信息,改善视觉质量。
- 几何处理:放缩、旋转、配准等。
- 图像复原:模糊图像复原等。
- 图像重建:由截面的投影,重建该截面(如CT技术)。
- 图像编码:JPEG等,主要考虑压缩。
- 模式识别:文字、指纹、人脸识别等。
图像处理与计算机图形学
图形虽然是图像的一种,但图像处理更倾向于处理来源于现实的图像(采样而得),而计算机图形学中的图形是由一组数学公式描述得到的。因此图像处理与计算机图形学是独立的学科方向,偶有交集。
图像的数字化
图像数字化过程描述为:采样、量化、编码。
采样一般是等距采样,在图像上构造直角坐标系xOy,对图像的横纵坐标进行等距划分后获得像素点(其实是一个个小方格[ia/N,(i+1)a/n)*[jb/M,(j+1)b/M))。
量化是在像素点内取一个代表值作为像素值。
编码采用PCM编码(脉码调制)。
*PCM是按照既定规则将时间连续、取值连续的模拟信号转换为时间离散、取值离散的数字信号。
空域与频域
空域和频域是数字图像处理的两个方面,有的问题在空域处理简单,有的在频域更方便。关于空域和频域的详细说明可以点击链接。
MATLAB基础
命令行、编辑器、工作区、当前文件夹
在MATLAB窗口中,除了有Windows窗口常见的标题栏、菜单栏、工具栏之外,还有
数据类、运算符、流控制
在面向过程的程序设计语言中,数据类型、运算符和流程控制是必须面对的,但是都基本与C一致,可以在使用过程中需要用到时再查询。
*MATLAB提供的数据类型除了常见的基本数据类型外,还有函数句柄、单元数组和结构,后文将会逐一展开。
索引技术
索引在各种程序设计语言中都存在,但是在MATLAB中显得尤为重要,因为MATLAB的一切都是矩阵,对矩阵的操作离不开索引。按照任意一本教材使用几次就会熟悉索引了。
MATLAB函数定义
MATLAB函数(M函数)标准格式如下:
- 函数定义行
- H1行(概要信息行)
- 帮助文本
- 函数体
- 注释
根据标准格式定义一个示例函数(定义于eg_sum.m文件中)如下:
function [ s ] = eg_sum( n )
%Calculate the sum of numbers from 1 to n.
%This function is a simple example of function definition. It is used to calculate the sum of a series of numbers from 1 to n.
s=0;
for i=1:n
s=s+i;
end
end
函数句柄(Function Handle)
函数句柄使用函数句柄运算符@来创建。函数句柄的本质是调用函数的所有信息,将这些信息通过函数句柄变量存储起来,在后续调用时直接使用函数句柄来调用,可以省去在众多函数信息中查询目的函数信息的时间。在一个程序高频使用的函数,如果使用函数句柄来存储其调用信息,则可以起到优化程序性能的作用。
函数句柄有两类,一类是命名函数句柄(又称简单函数句柄),另一类是匿名函数句柄(类似于C宏定义)。
命名函数句柄示例:使用函数句柄f来存储sin函数的调用信息
f=@sin;
f(pi/4);
匿名函数句柄示例:使用函数句柄f来存储表达式y=x.^2的调用信息,@(x)中的x给出了输入参数列表
f=@(x) y=x.^2;
f(3);
或:
f=@() sin(pi/4);
单元矩阵
单元矩阵其实就是将多个类型不限的变量组合到一起,运算符是花括号{},但是作者认为并不常用,故省略了。但是有一个细节值得一提,单元矩阵创建时是将内容变量创建了一个副本,因此改变原变量并不能改变单元矩阵。
结构
类似于C结构体,使用点运算符.取元素。
计时器策略
计时器一般是为了测量程序的运行时间,是效率的量化表现。MATLAB有专门用来计时的函数,也可以自己制作计时器。
- 使用clock()函数获取当前时间,在首尾各获取一次,差值即为用时。
- 使用tic()、toc()函数配对使用来计时。
- 使用timeit()函数来计时,具体用法请自行查阅。
程序基本优化
MATLAB程序的基本优化策略有两种:预分配和向量化循环。
预分配如其字面意思,即在矩阵使用之前做一次初始化,主要是在循环过程中动态变化矩阵尺寸时。MATLAB明明可以自动修正矩阵的尺寸,为什么非要在使用前初始化呢?原因很简单,看似是自动修正矩阵尺寸,其实背后的实现较为复杂,至少要重新申请空间和赋值原数组,这些操作的实现会耗费大量时间。
向量化循环在旧版本的MATLAB中使用较多,而且效果显著。其原理是使用矩阵运算符、索引技术、库函数来完全消除循环。比如使用A=A>threshold;这条语句代替for循环判断,从而提高效率。但是在新版本的MATLAB中,已经能够自动编译for循环来加速,因此向量化循环已经不需要程序员来考虑了。