图像增强是指根据特定的需要==突出一幅图像中的某些信息,同时削弱或去除某些不需要的信息==的处理方法。其主要目的是使处理后的图像对某种特定的应用来说,比原始图像更适用。因此,这类处理是为了某种应用目的而去改善图像质量的。处理的结果使图像更适合于人的观察或机器的识别系统。
应该明确的是增强处理并不是增强原始图像的信息,其结果只能增强对某种信息的辨识能力,而同时这种处理有可能损失一些其他信息。正因为如此,我们很难找到一个评价图像增强效果优劣的客观标准,也就没有特别通用模式化的图像增强办法,总是我们根据具体期望的处理效果做出取舍。
图像增强技术基本上可分为两大类:一类是空间域增强,一类是频率域增强。
空间域图像增强与频率域图像增强不是两种截然不同的图像增强技术,实际上在相当程度上说,它们是在不同的领域做同样的事情,是殊途同归的,只是有些滤波更适合在空间域完成,而有些则更适合在频率域中完成。
空间域图像增强技术主要包括直方图修正、灰度变换增强、图像平滑化以及图像锐化等。在增强过程中可以采用单一方法处理,但更多实际情况是需要采用几种方法联合处理,才能达到预期的增强效果(永远不要指望某个单一的图像处理方法可以解决全部问题)。
前面所学的通过灰度变换改善图像外观的方法,以及直方图修正技术(即直方图均衡化和直方图规定化)都是图像增强的有效手段,这些方法的共同点的变换是直接针对像素灰度值的,与该像素所处的邻域无关,而空间域增强则是基于图像中每一个小范围(邻域)内的像素进行灰度变换运算,某个点变换后的灰度由该点邻域内的那些店的灰度值共同决定,因此空间域增强也称为邻域运算或邻域滤波。空间域变换可使用下式描述:
g ( x , y ) = T [ f ( x , y ) ] g(x,y)=T[f(x,y)] g(x,y)=T[f(x,y)]
滤波是信号处理中的一个概念,是将信号中特定波段频率滤除的操作,在数字信号处理中通常采用傅里叶变换及其逆变换实现。
对图像中的每一点 (x,y),重复下面的操作:
上述过程就称为邻域处理或空间域滤波。一幅数字图像可以看成一个二维函数 f(x,y),而 x-y 平面表明了空间位置信息,称为空间域,基于 x-y 空间邻域的滤波操作叫做空间域滤波。如果对于邻域中的像素计算为线性运算,则又称为线性空间域滤波,否则称为非线性空间域滤波。
上图展示了一个 3 × 3 的**模板(又称为滤波器、模板、掩模、核或窗口)**进行空间滤波的过程。
滤波过程就是在图像 f(x,y) 中逐点地移动模板,使模板中心和点 (x,y) 重合,在每一个点 (x,y) 处滤波器在该点的响应根据模板的具体内容并通过预先定义的关系来计算,一般来说模板中的非 0 元素指出了邻域处理的范围,只有那些当模板中心与点 (x,y) 重合时,图像 f 中和模板中非 0 像素重合的像素参与了决定点 (x,y) 像素值的操作,在线性空间域滤波中模板的系数则给出了一种加权模式,即 (x,y) 处的响应由模板系数与模板下面区域的相应 f 的像素值的乘积之和给出。对于上图,此刻对于模板对的响应 R 为:
R = w ( − 1 , − 1 ) f ( x − 1 , y − 1 ) + w ( − 1 , 0 ) f ( x − 1 , y ) + . . . + w ( 0 , 0 ) f ( x , y ) + w ( 1 , 0 ) f ( x + 1 , y ) + w ( 1 , 1 ) f ( x + 1 , y + 1 ) R=w(-1,-1)f(x-1,y-1)+w(-1,0)f(x-1,y)+...+w(0,0)f(x,y)+w(1,0)f(x+1,y)+w(1,1)f(x+1,y+1) R=w(−1,−1)f(x−1,y−1)+w(−1,0)f(x−1,y)+...+w(0,0)f(x,y)+w(1,0)f(x+1,y)+w(1,1)f(x+1,y+1)
更一般的情况,对于一个大小为 m × n 的模板,其中 m = 2a + 1,n = 2b + 1,a、b 均为正整数,即模板长与宽均为基数,且可能的最小尺寸为 3 × 3(偶数尺寸的模板由于其不具备对称性因而很少被使用,而 1 × 1 大小的模板的操作不考虑邻域信息,退化为图像点运算),可以将滤波操作形式化表示为:
g ( x , y ) = ∑ s = − a a ∑ t = − b b w ( s , t ) f ( x + s , y + t ) g(x,y)=\sum^a_{s=-a}\sum^b_{t=-b}w(s,t)f(x+s,y+t) g(x,y)=s=−a∑at=−b∑bw(s,t)f(x+s,y+t)
对于大小为 M × N 的图像 f(0…M-1,0…N-1),对 x = 0,1,2,…,M-1 和 y = 0,1,2,…,N-1 依次应用公式,从而完成了对于图像 f 的所有像素的处理,得到新图像 g。
执行滤波操作要注意的一点是当模板位于图像边缘时,模板的某些元素很可能会位于图像之外的情况,这时需要对于在边缘附近执行滤波操作单独处理,以避免引用到本不属于图像的无意义的值。
以下 3 种策略都可以用来解决边界问题:
处理上面介绍的滤波过程之外,还有一种称为卷积的滤波过程。上面给出的滤波公式实际上是一种相关,而卷积的形式表示略有不同:
g ( x , y ) = ∑ s = − a a ∑ t = − b b w ( − s , − t ) f ( x + s , y + t ) g(x,y)=\sum_{s=-a}^a\sum_{t=-b}^bw(-s,-t)f(x+s,y+t) g(x,y)=s=−a∑at=−b∑bw(−s,−t)f(x+s,y+t)
尽管差别细微,但有本质不同,卷积时模板是相对其中心点做镜像后再对 f 位于模板下的子图像做加权和的,或者说在做加权和之前模板先要以其中心点为原点旋转 180°。如果忽略了这一细微差别将导致完全错误的结果,只有当模板本身是关于中心点对称时相关和卷积的结果才会相同。
Matlab 中与滤波相关的函数主要有 imfilter 和 fspecial。Imfilter 完成滤波操作,而 fspecial 可以为我们创建一些预定义的二维滤波器,直接供 imfilter 函数使用。
1、滤波函数 imfilter 的原型如下:
g = imfilter(f,w,option1,option2,...)
参数说明:
f 是要进行滤波操作的图像;
w 是滤波操作所使用的模板,为一个二维数组;
option1,option2,… 是可选项,具体可以包含以下选项。
边界选项:主要针对上面提到的问题:
合法值 | 含义 |
---|---|
X(X 代表一个具体的数字) | 用固定数组 X 填充虚拟边界,默认情况是用 0 填充 |
‘symmetric’ | 填充虚拟边界的内容通过对靠近原图像边缘像素相对于原图像边缘做镜像得到 |
‘replicate’ | 填充虚拟边界的内容总是重复与它最近的边缘像素 |
‘circular’ | 认为原图像模式具有周期性,从而周期性地填充虚拟边界的内容 |
采用第一种方式固定值填充虚拟边界的问题是在边缘附近会产生梯度,采用后面三种方式填充可让边缘显得平滑。
尺寸选项:由于滤波中填充了边界,有必要指出输出图像 g 的大小,如表:
合法值 | 含义 |
---|---|
‘same’ | 输出图像 g 与输入图像 f 尺寸相同 |
‘full’ | 输出图像 g 的尺寸为填充虚拟边界后的图像 f’ 的尺寸,因为大于输入图像 f 的尺寸 |
模式选项:指明滤波过程是相关还是卷积,如下:
合法值 | 含义 |
---|---|
‘corr’ | 滤波过程为相关 |
‘conv’ | 滤波过程为卷积 |
返回值:
举例:读入图像,用模板:
w = 1 / 9 ∗ [ 1 1 1 1 1 1 1 1 1 ] w=1/9*\begin{bmatrix}1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \\\end{bmatrix} w=1/9∗⎣⎡111111111⎦⎤
对 f 进行相关滤波,采用重复的边界填充方式。
% 读入图像,用模板对 f 进行过滤,采用重复的边界填充方式
f = imread('you.jpg');
figure;
subplot(1,2,1);imshow(f);
w = [1 1 1;1 1 1;1 1 1] / 9; % 滤波模板
g = imfilter(f,w,'corr','replicate'); % 滤波
subplot(1,2,2);imshow(g);
结果如下:
2、可创建预定义的二维滤波器的 fspecial 函数的常见调用格式为:
h = fspecial(type,parameters)
参数说明:
type:指定了滤波器的类型;
合法值 | 功能描述 |
---|---|
‘average’ | 平均模板 |
‘disk’ | 圆形邻域的平均模板 |
‘gaussian’ | 高斯模板 |
‘laplacian’ | 拉普拉斯模板 |
‘log’ | 高斯-拉普拉斯模板 |
‘prewitt’ | Prewitt 水平边缘检测算子 |
‘sobel’ | Sobel 水平边缘检测算子 |
可选输入 parameters 是和选定的滤波器类型 type 相关的配置参数,如尺寸和标准差等。如果不提供,则函数使用该类型的默认参数设置。
返回值:
下面结合一些代表性的情况具体说明:
h = fspecial(‘average’,hsize) 返回一个大小为 hsize 的平均模板滤波器 h。参数 hsize 可以是一个含有 2 个分量的向量,指明 h 的行和列的数目;也可以仅为一个正整数,此时对应于模板为方阵的情况。hsize 的默认值为 [3 3]。
h = fspecial(‘disk’,radius) 返回一个半径为 radius 的圆形平均模板,h 为一个 (2radius + 1) * (2radius + 1) 的方阵。半径 radius 的默认值为 5;
h = fspecial(‘sobel’) 返回一个加强水平边缘的竖直梯度算子。
h = [ 1 2 1 0 0 0 − 1 − 2 − 1 ] h=\begin{bmatrix}1 & 2 & 1 \\ 0 & 0 & 0 \\ -1 & -2 & -1\end{bmatrix} h=⎣⎡10−120−210−1⎦⎤
如果需要检测竖直边缘,则使用 h’。
图像平滑是一种可以减少和抑制图像噪声的使用数字图像处理技术。在空间域中一般可以采用邻域平均来达到平滑的目的。
从上面的实验前后效果可以看出滤波后的图 g 有平滑或者说模糊的效果,这完全是模板 w 作用的结果。上面的例子中的 w 提供了一种平均加权模式,首先在以点 (x,y) 为中心 3 × 3 邻域内的点都参与了决定在新图像 g 中 (x,y) 点像素值的运算;而且所有系数都为 1,表示它们在参与决定 g(x,y) 值的过程中贡献(权重)都相同;最后前面的系数是要保证整个模板元素和为 1,这里应为 1/9,这样就能让新图像同原始图像保持在一个灰度范围内(如 [0,255])。
这样的 w 叫做平均模板,是用于图像平滑的模板中的一种,相当于一种局部平均。更一般的平均模板为:
w = 1 ( 2 k + 1 ) 2 [ 1 1 . . . 1 1 1 . . . 1 . . . 1 1 . . . 1 ] ( 2 k + 1 ) × ( 2 k + 1 ) w=\frac{1}{(2k+1)^2}\begin{bmatrix}1 & 1 & ... & 1 \\ 1 & 1 & ... & 1 \\ . \\ . \\ . \\ 1 & 1 & ... & 1\end{bmatrix}_{(2k+1)\times(2k+1)} w=(2k+1)21⎣⎢⎢⎢⎢⎢⎢⎡11...1111.........111⎦⎥⎥⎥⎥⎥⎥⎤(2k+1)×(2k+1)
工作原理
一般来说,图像具有局部连续特性,即相邻像素的数值相近,而噪声的存在使得在噪声点处产生灰度跳跃,但一般我们可以合理地假设偶尔出现的噪声影响并没有改变图像局部连续的性质,例如如下的局部图像 f_sub,灰色底纹标识的为噪声点,在图像中表现为亮区中的 2 个暗点。
f _ s u b = 200 215 212 208 196 198 5 202 199 221 199 207 202 201 211 203 218 210 0 198 200 215 212 208 205 f\_sub= \\ 200 \quad 215 \quad 212 \quad 208 \quad 196 \\ 198 \quad {\color{Red}5} \quad 202 \quad 199 \quad 221 \\ 199 \quad 207 \quad 202 \quad 201 \quad 211 \\ 203 \quad 218 \quad 210 \quad {\color{Red}0} \quad 198 \\ 200 \quad 215 \quad 212 \quad 208 \quad 205 f_sub=20021521220819619852021992211992072022012112032182100198200215212208205
对 f 用 3 × 3 的平均模板进行平滑滤波后,得到的平滑后图像 g_sub 为:
g _ s u b = 181 184 186 206 205 180 182 183 206 207 181 183 184 206 208 206 208 186 182 181 207 210 189 183 180 g\_sub= \\ 181 \quad 184 \quad 186 \quad 206 \quad 205 \\ 180 \quad {\color{Red}182} \quad 183 \quad 206 \quad 207 \\ 181 \quad 183 \quad 184 \quad 206 \quad 208 \\ 206 \quad 208 \quad 186 \quad {\color{Red}182} \quad 181 \\ 207 \quad 210 \quad 189 \quad 183 \quad 180 g_sub=181184186206205180182183206207181183184206208206208186182181207210189183180
Matlab 实现
利用 imfilter 和 fspeical,并以不同尺寸的平均模板实现平均平滑的 Matlab 示例代码如下:
% 不同尺寸平均模板的平均平滑效果
I = imread('you.jpg');
figure;
subplot(1,4,1);
imshow(I);
h = fspecial('average',3); % 3×3 平均模板
I3 = imfilter(I,h,'corr','replicate'); % 相关滤波,重复填充边界
subplot(1,4,2);imshow(I3);
h = fspecial('average',5); % 5 × 5 平均模板
I5 = imfilter(I,h,'corr','replicate');
subplot(1,4,3);imshow(I5);
h = fspecial('average',7); % 7 × 7 平均模板
I7 = imfilter(I,h,'corr','replicate');
subplot(1,4,4);imshow(I7);
运行结果:
理论基础
平均平滑对于邻域内的像素一视同仁,为了减少平滑处理中的模糊,得到更自然的平滑效果,很自然地想到了==适当加大模板中心点的权重,随着远离中心点,权重迅速减小,从而可以确保中心点看起来更接近于与它距离更近的点,基于这样的考虑得到的模板即为高斯模板==。
常用的 3 × 3 的高斯模板如下:
w = 1 / 16 × [ 1 2 1 2 4 2 1 2 1 ] w=1/16\times \begin{bmatrix}1 & 2 & 1 \\ 2 & 4 & 2 \\ 1 & 2 & 1\end{bmatrix} w=1/16×⎣⎡121242121⎦⎤
高斯模板名字的由来是二维高斯函数,即我们熟悉的二维正态分布密度函数,一个均值为 0,方差为 σ2 的二维高斯函数为:
φ ( x , y ) = 1 2 π σ 2 e x p ( − ( x 2 + y 2 ) 2 σ 2 ) \varphi(x,y)=\frac{1}{2\pi\sigma^2}exp(-\frac{(x^2+y^2)}{2\sigma^2}) φ(x,y)=2πσ21exp(−2σ2(x2+y2))
下图给出了 σ = 1 时二维高斯函数的三维示意图形:
高斯模板正是将连续的二维高斯函数的离散化表示,因此任意大小的高斯模板都可以通过建立一个 (2k+1) × (2k+1) 的矩阵 M 得到,其 (i,j) 位置的元素值可由下式确定:
M ( i , j ) = 1 2 π σ 2 e x p ( − ( ( i − k − 1 ) 2 + ( j − k − 1 ) 2 ) 2 σ 2 ) M(i,j)=\frac{1}{2\pi\sigma^2}exp(-\frac{((i-k-1)^2+(j-k-1)^2)}{2\sigma^2}) M(i,j)=2πσ21exp(−2σ2((i−k−1)2+(j−k−1)2))
σ 选择的小技巧
当标准差 σ 取不同的值时,二维高斯函数的形状会有很大的变化,因而在实际应用中选择合适的 σ 值非常重要;如果 σ 过小,偏离中心的像素权重将会非常小,相当于加权和响应基本不考虑邻域像素的作用,这样滤波操作就退化成图像的点运算,无法起到平滑噪声的作用;相反如果 σ 过大,而邻域相对较小,这样在邻域内高斯模板将退化成平均模板;只有当 σ 取合适的值时才能得到一个像素值的较好估计。Matlab 中 σ 的默认值为 0.5,在实际应用中,通常对 3 × 3 的模板取 σ 为 0.8 左右,对于更大的模板可以适当增大 σ 的值。
Matlab 实现
采用不同的 σ 实现高斯平滑的 Matlab 代码:
% 采用不同的 σ 实现高斯平滑
I = imread('you.jpg');
figure;
subplot(2,3,1);
imshow(I);
title('原图');
h3_5 = fspecial('gaussian',3,0.5); % sigma = 0.5 的 3 × 3 高斯模板
I3_5 = imfilter(I,h3_5); % 高斯平滑
subplot(2,3,2);imshow(I3_5);
title('sigma = 0.5 的 3 × 3 高斯模板');
h3_8 = fspecial('gaussian',3,0.8); % sigma = 0.8 的 3 × 3 高斯模板
I3_8 = imfilter(I,h3_8);
subplot(2,3,3);imshow(I3_8);
title('sigma = 0.8 的 3 × 3 高斯模板');
h3_18 = fspecial('gaussian',3,1.8); % sigma = 1.8 的 3 × 3 高斯模板,接近于平均模板
I3_18 = imfilter(I,h3_18);
subplot(2,3,4);imshow(I3_18);
title('sigma = 1.8 的 3 × 3 高斯模板,接近于平均模板');
h5_8 = fspecial('gaussian',5,0.8); % sigma = 0.8 的 5 × 5 高斯模板
I5_8 = imfilter(I,h5_8);
subplot(2,3,5);imshow(I5_8);
imwrite(I5_8,'you5_8.bmp');
title('sigma = 0.8 的 5 × 5 高斯模板');
h7_12 = fspecial('gaussian',7,1.2); % sigma = 1.2 的 7 × 7 高斯模板
I7_12 = imfilter(I,h7_12);
subplot(2,3,6);imshow(I7_12);
imwrite(I7_12,'you7_12.bmp');
title('sigma = 1.2 的 7 × 7 高斯模板');
利用平均模板的平滑在消除噪声的同时也使图像变得模糊,高斯平滑在一定程度上缓解了这些现象,但由于平滑滤波机理可知这种模糊是不可避免的。这当然是我们所不希望的,于是想到选择性地进行平滑,即只在噪声局部区域进行平滑,而在无噪声局部区域不进行平滑,将模糊的影响降到最小,这就是自适应滤波的思想。
那么怎样判断该局部区域是包含噪声的需要平滑的区域还是无明显噪声的不需要平滑的区域呢?这主要基于噪声的性质来考虑,噪声的存在会使得在噪声点处产生灰度跳跃,从而使噪声点局部区域灰度跨度较大。因此可以选择下面的 2 个标准中的 1 个作为局部区域存在噪声的判断。
局部区域最大值与最小值之差大于某一阈值 T,即:
m a x ( R ) − m i n ( R ) > T , 其 中 R 代 表 该 局 部 区 域 max(R)-min(R)>T,其中 R 代表该局部区域 max(R)−min(R)>T,其中R代表该局部区域
局部区域方差大于某一阈值 T,即:
D ( R ) > T , D ( R ) 表 示 区 域 R 中 像 素 的 方 差 D(R)>T,D(R)表示区域 R 中像素的方差 D(R)>T,D(R)表示区域R中像素的方差
自适应算法的实现逻辑如下:
逐步扫描图像:
对每一个像素,以该像素作为中心,计算其周围区域 R 的统计特征,如最大值、最小值和方差等;
如果区域 R 的特征满足选定的噪声判据:
根据选定的模板计算邻域加权和作为该点的响应;
否则:
不处理该点;
中值滤波本质上是一种统计排序滤波器。对于原图像中某点 (i,j),中值滤波以该点为中心的邻域内的所有像素的统计排序中值作为 (i,j) 点的响应。
中值不同于均值,是指排序队列中位于中间位置的元素的值,例如,采用 3 × 3 中值滤波器,某点 (i,j) 的 8 个邻域的一系列像素值为 12、18、18、11、23、22、13、25、118,统计排序结果为 11、12、13、18、18、22、23、25、118。排在中间位置(第 5 位)的 18 即作为 (i,j) 点中值滤波的响应 g(i,j)。显然,中值滤波不是线性滤波器。
中值滤波对于某些类型的随机噪声具有非常理想的降噪能力,对于线性平滑滤波而言,在处理的像素邻域之内包含噪声点时,噪声的存在总会或多或少地影响该点的像素值的计算,(对于高斯平滑影响程度同噪声点到中心点的距离成正比),但在中值滤波中噪声点则常常是直接被忽略掉的;而且同线性平滑滤波器相比,中值滤波在降噪同时引起的模糊效应较低。中值滤波的一种典型应用是消除椒盐噪声。
噪声模型
Matlab 中添加噪声的语句是:
J = imnoise(I,type,parameters);
参数说明
I 为原图像;
可选参数 type 指定了噪声类型,常用的噪声类型如下:
合法取值 | 功能描述 |
---|---|
‘gaussian’ | 高斯白噪声:如果一个噪声,它的幅度分布服从高斯分布,则称之为高斯噪声。而如果它的功率谱密度又是均匀分布的,则称它为高斯白噪声 |
‘salt & pepper’ | 椒盐噪声因其在图像中的表现形式而得名,黑点如同胡椒,白点如同椒盐。椒盐噪声是由图像传感器,传输信道,解码处理等产生的黑白相间的亮暗点噪声。椒盐噪声往往由图像切割引起 |
返回值
注:使用 imnoise 添加高斯噪声时,相当于对原图像中每一个像素叠加一个从均值为 m、方差为 v 的高斯分布产生的随机样本值。
中值滤波的 Matlab 实现
Matlab 提供了 medfilt2 函数实现中值滤波,原型为:
I2 = medfilt2(I1,[m,n]);
参数说明
返回值
下面的程序分别给出了对于一幅受椒盐噪声污染的图像,平均平滑、高斯平滑和中值滤波的处理效果图:
% 分别给出了对于一幅受椒盐噪声污染的图像,平均平滑、高斯平滑和中值滤波的处理效果图
I = imread('you_2.bmp');
I = im2double(I); % 转换数据类型为 double
figure;
subplot(3,2,1);
imshow(I);title('原图');
J = imnoise(I,'salt & pepper'); % 为图像叠加椒盐噪声
subplot(3,2,2);imshow(J);title('为图像叠加椒盐噪声');
w = [1 2 1;
2 4 2;
1 2 1] / 16;
J1 = imfilter(J,w,'corr','replicate'); % 高斯平滑
subplot(3,2,3);imshow(J1);title('高斯平滑去噪');
w = [1 1 1;
1 1 1;
1 1 1] / 9;
J2 = imfilter(J,w,'corr','replicate'); % 平均平滑
subplot(3,2,4);imshow(J2);title('平均平滑去噪');
J3 = medfilt2(J,[3,3]); % 中值滤波
subplot(3,2,5);imshow(J3);title('中值滤波去噪');
与线性平滑滤波考虑邻域中每个像素的作用不同,中值滤波在每个 n × n 邻域内都会忽略掉那些相对于邻域内大部分其余像素更亮或更暗,并且所占区域小于像素总数一半 (n2/2) 的像素的影响,而实际上满足这样条件被忽略掉的像素往往是噪声。
注:作为一种非线性滤波,中值滤波有可能会改变图像的性质,因而一般不适用于像军事图像处理、医学图像处理等领域。
图像的锐化的目的是使模糊的图像变得清晰起来。
图像锐化主要用于增强图像的灰度跳变部分,这一点与图像平滑对灰度跳变的抑制正好相反,事实上从平滑与锐化的两种运算算子上也就说明这一点,线性平滑都是基于对图像邻域的加权求和或者说积分运算的,而锐化则通过其逆运算导数(梯度)或者说有限差分来实现的。
在讨论平滑的时候我们提到了噪声和边缘都会使图像产生灰度跳变。同样的,在锐化处理中如何区分开噪声和边缘仍然是我们要面临的一个课题,只是在平滑中要平滑的是噪声,希望处理不要涉及边缘;而在锐化中要锐化的对象是边缘,希望不要涉及噪声。
梯度的定义:
对于连续二维函数 f(x,y),其在点 (x,y) 处的梯度是下面的二维列向量:
∇ f = [ G x G y ] = [ ∂ f ∂ x ∂ f ∂ y ] \nabla f = \begin{bmatrix}G_x \\ G_y\end{bmatrix}=\begin{bmatrix}\frac{\partial f}{\partial x} \\ \frac{\partial f}{\partial y} \end{bmatrix} ∇f=[GxGy]=[∂x∂f∂y∂f]
式中:
∂ f ∂ x = lim ϵ → 0 f ( x + ϵ , y ) − f ( x , y ) ϵ \frac{\partial f}{\partial x}=\lim_{\epsilon \rightarrow 0}\frac{f(x+\epsilon,y) - f(x,y)}{\epsilon} ∂x∂f=ϵ→0limϵf(x+ϵ,y)−f(x,y)∂ f ∂ y = lim ϵ → 0 f ( x , y + ϵ ) − f ( x , y ) ϵ \frac{\partial f}{\partial y}=\lim_{\epsilon \rightarrow 0}\frac{f(x,y +\epsilon) - f(x,y)}{\epsilon} ∂y∂f=ϵ→0limϵf(x,y+ϵ)−f(x,y)
梯度的方向就是函数 f(x,y) 最大变化率的方向。
梯度的幅值作为变化率大小的度量,其值为
∣ ∇ f ( x , y ) ∣ = ( ∂ f ∂ x ) 2 + ( ∂ f ∂ y ) 2 |\nabla f(x,y)|=\sqrt{(\frac{\partial f}{\partial x})^2+(\frac{\partial f}{\partial y})^2} ∣∇f(x,y)∣=(∂x∂f)2+(∂y∂f)2
对于二维离散函数 f(i,j),可以用有限差分作为梯度幅值的一个近似:
∣ ∇ f ( i , j ) ∣ = ( f ( i + 1 , j ) − f ( i , j ) ) 2 + ( f ( i , j + 1 ) − f ( i , j ) ) 2 |\nabla f(i,j)|=\sqrt{(f(i+1,j)-f(i,j))^2+(f(i,j+1)-f(i,j))^2} ∣∇f(i,j)∣=(f(i+1,j)−f(i,j))2+(f(i,j+1)−f(i,j))2
尽管梯度和幅值两者有着本质的区别,但在数字图像处理中提到梯度时,往往不加区分,即将上式的梯度幅值称为梯度。
上式中包含平方和开方,不方便计算,因此可近似为绝对值的形式:
∣ ∇ f ( i , j ) ∣ = ∣ ( f ( i + 1 , j ) − f ( i , j ) ) ∣ + ∣ ( f ( i , j + 1 ) − f ( i , j ) ) ∣ |\nabla f(i,j)|=|(f(i+1,j)-f(i,j))|+|(f(i,j+1)-f(i,j))| ∣∇f(i,j)∣=∣(f(i+1,j)−f(i,j))∣+∣(f(i,j+1)−f(i,j))∣
而在实际使用中,经常被采用的是另外一种近似梯度——Robert 交叉梯度:
∣ ∇ f ( i , j ) ∣ = ∣ ( f ( i + 1 , j + 1 ) − f ( i , j ) ) ∣ + ∣ ( f ( i , j + 1 ) − f ( i + 1 , j ) ) ∣ |\nabla f(i,j)|=|(f(i+1,j+1)-f(i,j))|+|(f(i,j+1)-f(i+1,j))| ∣∇f(i,j)∣=∣(f(i+1,j+1)−f(i,j))∣+∣(f(i,j+1)−f(i+1,j))∣
Robert 交叉梯度
Robert 交叉梯度对应的模板为:
w 1 = [ − 1 0 0 1 ] w 2 = [ 0 − 1 1 0 ] w1=\begin{bmatrix}-1 & 0 \\ 0 & 1\end{bmatrix} \quad\quad\quad\quad w2=\begin{bmatrix}0 & -1 \\ 1 & 0\end{bmatrix} w1=[−1001]w2=[01−10]
式中:w1 对接近 +45° 边缘有较强的响应;w2 对接近 -45° 边缘有较强的响应。
例 基于 Robert 交叉梯度的图像锐化
有了之前的滤波的知识,只要以 w1 和 w2 为模板,对原图像 (a) 进行滤波就可得到 G1 和 G2,而根据公式 (21)最终的 Robert 交叉图像 (b)为
G = ∣ G 1 ∣ + ∣ G 2 ∣ G = |G1|+|G2| G=∣G1∣+∣G2∣
在进行锐化滤波之前,我们要将图像类型从 unit8 转换为 double,这是因为锐化模板的负系数常常使得输出产生负值,如果采用无符号的 unit8 型,则负值就会被截断。
在调用函数 imfilter 时,还要注意不要使用默认的填充方式,因为 Matlab 默认会在滤波时进行 “0” 填充,这会导致图像在边界处产生一个人为的灰度跳变,从而在梯度图像中产生高响应,而这些人为为高响应值的存在将导致对图像中真正的边缘和其他我们关心的细节的响应在输出梯度图像中被压缩在一个很窄的灰度范围,同时也影响显示的效果。我们采用了 replicate 的重复填充方式,也可采用 symmetric 的对称填充方式。
% 基于 Robert 交叉梯度的图像锐化
I = imread('brain1.png');
figure;
subplot(2,2,1);imshow(I);title('原图');
I = double(I); % 转换为 double 类型,这样可以保存负值,否则 unit8 型会把负值裁掉
w1 = [-1 0;0 1];
w2 = [0 -1;1 0];
G1 = imfilter(I,w1,'corr','replicate'); % 以重复方式填充边界
G2 = imfilter(I,w2,'corr','replicate');
G = abs(G1) + abs(G2); % 计算 Robert 梯度
subplot(2,2,2);imshow(G,[]);title(' Robert 交叉梯度图');
subplot(2,2,3);imshow(abs(G1),[]);title(' w1 滤波过滤后去绝对值并重新标定');
subplot(2,2,4);imshow(abs(G2),[]);title(' w2 滤波过滤后去绝对值并重新标定');
Sobel 梯度
因为滤波时我们总是喜欢奇数尺寸的模板,因而一种计算 Sobel 梯度的 Sobel 模板更加常用。
w 1 = [ − 1 − 2 − 1 0 0 0 1 2 1 ] w 2 = [ − 1 0 1 − 2 0 2 − 1 0 1 ] w1=\begin{bmatrix}-1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1\end{bmatrix} \quad\quad\quad\quad w2=\begin{bmatrix}-1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1\end{bmatrix} w1=⎣⎡−101−202−101⎦⎤w2=⎣⎡−1−2−1000121⎦⎤
其中 w1 对水平边缘有较大响应的竖直梯度;w2 为对竖直边缘有较大影响的水平梯度。
下面的程序计算了一幅图像的竖直和水平梯度,它们的和可以作为完整的 Sobel 梯度。
% 基于 Sobel 梯度的图像锐化
I = imread('brain1.png');
w1 = fspecial('sobel'); % 得到水平 Sobel 模板
w1
w2 = w1'; % 转置得到竖直 Sobel 模板
w2
G1 = imfilter(I,w1); % 水平 Sobel 梯度
G2 = imfilter(I,w2); % 竖直 Sobel 梯度
G = abs(G1) + abs(G2); % Sobel 梯度
figure;
subplot(1,3,1);imshow(G1,[]);title('Sobel 梯度图像');
subplot(1,3,2);imshow(G2,[]);title('w1 滤波过滤后去绝对值并重新标定');
subplot(1,3,3);imshow(G,[]);title('w2 滤波过滤后去绝对值并重新标定');
还可以直接利用 Matlab 梯度函数 gradient 计算 Sobel 梯度,程序如下:
% 利用 gradient 计算 Sobel 梯度
I = imread('brain1.png');
figure;
subplot(2,3,1);imshow(I);title('原图');
I = double(I); % 计算梯度前要转换为 double
[Gx Gy] = gradient(I); % 计算 x,y 方向梯度
G = abs(Gx) + abs(Gy);
subplot(2,3,2);imshow(G);
subplot(2,3,4);imshow(G,[]);title('整体梯度图像');
subplot(2,3,5);imshow(Gx,[]);title('x 方向梯度图像(突出偏竖直方向的边缘)');
subplot(2,3,6);imshow(Gy,[]);title('y 方向梯度图像(突出偏水平方向的边缘)');
应用广泛的二阶微分的拉普拉斯算子。
理论基础
二维函数 f(x,y) 的二阶微分(拉普拉斯算子)定义为:
∇ f ( x , y ) = ∂ 2 f ∂ x 2 + ∂ 2 f ∂ y 2 \nabla f(x,y) =\frac{\partial ^2 f}{\partial x^2} + \frac{\partial ^2 f}{\partial y^2} ∇f(x,y)=∂x2∂2f+∂y2∂2f
对于离散的二维图像 f(i,j),可以用下式作为对二阶偏微分的近似:
∂ 2 f ∂ x 2 = ( f ( i + 1 , j ) − f ( i , j ) ) − ( f ( i , j ) − f ( i − 1 , j ) ) = f ( i + 1 , j ) + f ( i − 1 , j ) − 2 f ( i , j ) \frac{\partial ^2 f}{\partial x^2}=(f(i+1,j)-f(i,j))-(f(i,j)-f(i-1,j))=f(i+1,j)+f(i-1,j)-2f(i,j) ∂x2∂2f=(f(i+1,j)−f(i,j))−(f(i,j)−f(i−1,j))=f(i+1,j)+f(i−1,j)−2f(i,j)∂ 2 f ∂ y 2 = ( f ( i , j + 1 ) − f ( i , j ) ) − ( f ( i , j ) − f ( i , j − 1 ) ) = f ( i , j + 1 ) + f ( i , j − 1 ) − 2 f ( i , j ) \frac{\partial ^2 f}{\partial y^2}=(f(i,j+1)-f(i,j))-(f(i,j)-f(i,j-1))=f(i,j+1)+f(i,j-1)-2f(i,j) ∂y2∂2f=(f(i,j+1)−f(i,j))−(f(i,j)−f(i,j−1))=f(i,j+1)+f(i,j−1)−2f(i,j)
就得到了用于图像锐化的拉普拉斯算子:
∇ 2 f = [ f ( i + 1 , j ) + f ( i − 1 , j ) + f ( i , j + 1 ) + f ( i , j − 1 ) ] − 4 f ( i , j ) \nabla ^2 f = [f(i+1,j)+f(i-1,j)+f(i,j+1)+f(i,j-1)]-4f(i,j) ∇2f=[f(i+1,j)+f(i−1,j)+f(i,j+1)+f(i,j−1)]−4f(i,j)
对应的滤波模板如下:
W 1 = [ 0 1 0 1 − 4 1 0 1 0 ] W1=\begin{bmatrix}0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0\end{bmatrix} W1=⎣⎡0101−41010⎦⎤
因为在锐化过程增强中,绝对值相同的正值和负值实际上表示相同的响应,故也等同于使用如下的模板 W2:
W 2 = [ 0 − 1 0 − 1 − 4 − 1 0 − 1 0 ] W2=\begin{bmatrix}0 & -1 & 0 \\ -1 & -4 & -1 \\ 0 & -1 & 0\end{bmatrix} W2=⎣⎡0−10−1−4−10−10⎦⎤
分析拉普拉斯模板结构,可知这种模板对于 90° 的旋转是各向同性的,所谓对于某角度各向同性是指把原图像旋转该角度后再进行滤波与先对原图像滤波再旋转该角度的结果相同。这说明拉普拉斯算子对于接近水平和接近竖直方向的边缘都有很好的增强,从而避免了我们在使用梯度算子时要进行两次滤波的麻烦。更进一步,我们还可以得到如下对于 45° 旋转各向同性的滤波器。
W 3 = [ 1 1 1 1 8 1 1 1 1 ] W 4 = [ − 1 − 1 − 1 − 1 8 − 1 − 1 − 1 − 1 ] W3=\begin{bmatrix}1 & 1 & 1 \\ 1 & 8 & 1 \\ 1 & 1 & 1\end{bmatrix} \quad\quad\quad W4=\begin{bmatrix}-1 & -1 & -1 \\ -1 & 8 & -1 \\ -1 & -1 & -1\end{bmatrix} W3=⎣⎡111181111⎦⎤W4=⎣⎡−1−1−1−18−1−1−1−1⎦⎤
沿着高斯平滑模板的思想,根据到中心点的距离给模板周边的点赋予不同的权重,还可得到如下的模板 W5:
W 5 = [ 1 4 1 4 − 20 4 1 4 1 ] W5=\begin{bmatrix}1 & 4 & 1 \\ 4 & -20 & 4 \\ 1 & 4 & 1\end{bmatrix} W5=⎣⎡1414−204141⎦⎤
Matlab 实现
分别使用上述的 3 种拉普拉斯模板的 Matlab 滤波程序:
% 分别使用 3 种拉普拉斯模板的 Matlab 滤波
I = imread('brain1.png');
figure;subplot(2,2,1);imshow(I);title('原图像');
I = double(I);
W1 = [0 -1 0;-1 4 -1;0 -1 0];
L1 = imfilter(I,W1,'corr','replicate');
W3 = [-1 -1 -1;-1 8 -1;-1 -1 -1];
L2 = imfilter(I,W3,'corr','replicate');
subplot(2,2,2);imshow(abs(L1),[]);title('利用 W1 模板拉普拉斯锐化');
subplot(2,2,3);imshow(abs(L2),[]);title('利用 W3 模板拉普拉斯锐化');
W5 = [1 4 1;4 -20 4;1 4 1];
L3 = imfilter(I,W5,'corr','replicate');
subplot(2,2,4);imshow(abs(L3),[]);title('利用 W5 模板拉普拉斯锐化');
拉普拉斯似乎对一些离散点有较强的响应。当然由于噪声也是离散点,因此这个性质有时是我们所不希望的。