一幅原始图像在获取和传输过程中会受到各种噪声的干扰,使图像质量下降,对分析图像不利。反映到画面上,主要有两种典型的噪声。一种是幅值基本相同,但出现的位置很随机的椒盐噪声。另一种则每一点都存在,但幅值随机分布的随机噪声。为了抑制噪声、改善图像质量,要对图像进行平滑处理。
图像常常被强度随机信号(也称为噪声)所污染。一些常见的噪声有椒盐噪声(Salt & Pepper)噪声、脉冲噪声、高斯噪声等。
图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏直接影响到后续图像处理和分析的有效性和可靠性。
由于成像系统、传输介质和记录设备等的不完善,数字图像在其形成、传输记录过程中往往会受到多种噪声的 污染。这些噪声在图像上表现为一引起较强视觉效果的孤立像素点或像素块。一般噪声信号与要研究的对象不相关,它以无用的信息形式出现,扰乱图像的可观察信息。对于数字图像信号,噪声表现为或大或小的极值,这些极值通过加减作用于图像像素的真实灰度值上,在图像上造成亮暗点干扰,极大降低了图像质量,影响图像复原、分割、特征提取、图像识别等后继工作的进行。要构造一种有效抑制噪声的滤波器必须考虑两个基本问题,能有效的去除目标和背景中的噪声,同时能很好的保护图像目标的形状、大小及特定的几何和拓扑结构特征。
消除图像中的噪声成分叫作图像的平滑化或滤波操作。信号或图像的能量大部分集中在幅度谱的低频和中频段是很常见的,而在较高频段,感兴趣的信息经常被噪声淹没。因此一个能降低高频成分幅度的滤波器就能够减弱噪声的影响。
图像滤波的目的
对滤波处理的要求
平滑滤波是低频增强的空间域滤波技术,其目的
根据空间类型可将滤波器分为:
频率滤波 需要先进行傅里叶变换至频域处理,然后再反变换回空间域还原图像。
空域滤波 直接对图像数据做空间变换达到滤波的目的。它是一种领域运算,即输出图像中任何像素的值都是通过采用一定的算法,根据输入图像中对应像素周围一定领域内像素的值得来的。
空间域的平滑滤波一般采用简单平均法进行,就是求临近像素点的平均亮度值。邻域的大小与平滑的效果直接相关,邻域越大平滑的效果越好,但邻域过大,平滑会是边缘信息损失的越大,从而使输出的图像变得模糊,因此需合理选择邻域的大小。
一个滤波器就是在选定的领域像素上执行预定义好的操作产生新的像素,并用新的像素替换掉原来像素形成新的图像。
一个空间滤波器包括两个部分:
通常可以将滤波器称之为核(kernel)、模板(template)或者窗口(window)。
根据预定义的操作,可以将滤波器分为:
根据滤波器最终对图像造成的影响,可以将滤波器分为:
中值滤波在噪声密度不是很大的情况下(根据经验,噪声出现的概率小于0.2),效果不错。但是当概率出现的概率较高时,常规的中值滤波器的效果就不是很好了。增大滤波器窗口的大小,虽然在一定程度上能解决该问题,但是会给图像造成较大的模糊。
常规的中值滤波器的窗口尺寸是固定大小不变的,就不能同时兼顾去燥和保护图像的细节。在滤波的过程中,动态的改变滤波器的窗口尺寸大小,这就是自适应中值滤波器Adaptive Median Filter。
均值滤波器可以归为低通滤波器,是一种线性滤波器,其输出为领域模板内的像素的简单平均值,主要用于图像的模糊和降噪。均值滤波器使用滤波器窗口内的像素的平均灰度值代替图像的像素值,这样会降低图像中的尖锐变化。均值滤波器在降低噪声的同时,会模糊图像的边缘。均值滤波器会过滤掉图像中的“不相关”细节,其中“不相关”细节指的是与滤波器模板尺寸相比较小的像素区域。
根据均值计算方法的不同,均值滤波器有以下几种:
高斯滤波器是一种线性滤波器,能够有效的抑制噪声,平滑图像。其作用原理和均值滤波器类似,都是取滤波器窗口内的像素的均值作为输出。其窗口模板的系数和均值滤波器不同,均值滤波器的模板系数都是相同的为1,而高斯滤波器的模板系数,则随着距离模板中心的增大而系数减小。所以高斯滤波器相比于均值滤波器对图像的模糊程度较小。
高斯滤波器和高斯分布(正态分布)是有一定的关系,一个二维的高斯函数如下:
h ( x , y ) = e − x 2 + y 2 2 σ 2 h(x,y) = e ^ {- \frac{x^2 + y^2}{2\sigma ^ 2}} h(x,y)=e−2σ2x2+y2
其中 ( x , y ) (x,y) (x,y)为点坐标,在图像处理中可认为是整数; σ \sigma σ 是标准差。计算高斯滤波器的模板,需要对高斯函数进行离散化,得到的高斯函数值作为模板的系数。
例如:要计算一个 3 × 3 3 \times 3 3×3的高斯滤波器模板,以模板的中心位置为坐标原点进行取样。假定中心的坐标是(0,0),那么距离它最近的8个点的坐标如下:
这样将各个位置的坐标带入到高斯函数中,得到的值就是模板的系数。对于窗口模板的大小为 ( 2 k + 1 ) × ( 2 k + 1 ) (2k+1)\times(2k+1) (2k+1)×(2k+1),模板中各个元素值的计算公式如下:
H i , j = 1 2 π σ 2 e − ( i − k ) 2 + ( j − k ) 2 2 σ 2 H_{i,j} = \frac{1}{2\pi \sigma ^ 2}e ^{-\frac{(i - k )^2 + (j - k )^2}{2 \sigma ^ 2}} Hi,j=2πσ21e−2σ2(i−k)2+(j−k)2
小数形式, σ = 0.8 \sigma=0.8 σ=0.8, 3 ∗ 3 3*3 3∗3的权重矩阵为:
这9个点的权重总和等于0.912599,如果只计算这个9个点的加权平均,还需要让它们的权重之和等于1,因此上面的9个值都分别除以0.912599,得到最终的权重矩阵为:
整数形式的,则需进行归一化,将模板左上角的值归一化为1, σ = 0.8 \sigma=0.8 σ=0.8, 3 ∗ 3 3*3 3∗3的权重矩阵为:
使用整数模板时,需要在模板的前面加上一个系数,系数为 1 ∑ ( i , j ) ∈ w w i , j \frac{1}{\sum_{(i,j) \in {w}}w_{i,j}} ∑(i,j)∈wwi,j1,也就是模板系数和的倒数。
3 ∗ 3 3*3 3∗3 和 5 ∗ 5 5*5 5∗5邻域的高斯模板:
void generateGaussianTemplate(double window[][3], int ksize, double sigma)
{
static const double pi = 3.1415926;
int center = ksize / 2; // 模板的中心位置,也就是坐标的原点
double x2, y2;
double sum = 0.0;
printf("Gaussian Matrix:\n");
for (int i = 0; i < ksize; i++)
{
x2 = pow(i - center, 2);
for (int j = 0; j < ksize; j++)
{
y2 = pow(j - center, 2);
double g = exp(-(x2 + y2) / (2 * sigma * sigma));
g /= 2 * pi * sigma * sigma;
window[i][j] = g;
printf("%f ", window[i][j]);
sum += window[i][j];
}
printf("\n");
}
printf("Norm Gaussian Matrix:\n");
for (int i = 0; i < ksize; i++)
{
for (int j = 0; j < ksize; j++)
{
printf("%lf ", window[i][j] / sum);
}
printf("\n");
}
double k = 1 / window[0][0]; // 将左上角的系数归一化为1
printf("Norm Left Gaussian Matrix:\n");
for (int i = 0; i < ksize; i++)
{
for (int j = 0; j < ksize; j++)
{
printf("%f ", window[i][j]*k);
}
printf("\n");
}
}
int main()
{
double window[3][3] = { 0 };
int ksize = 3;
double sigma = 0.8;
generateGaussianTemplate(window, ksize, sigma);
return 0;
}
双边滤波是一种非线性滤波器,可以达到保持边缘、降噪平滑的效果。和其他滤波器原理一样,双边滤波也是采用加权平均的方法,用周边像素亮度值的加权平均代表某个像素的强度,所用的加权平均基于高斯分布。最重要的是,双边滤波的权重不仅考虑了像素的欧氏距离(如普通的高斯低通滤波,只考虑了位置对中心像素的影响),还考虑了像素范围域中的辐射差异(例如卷积核中像素与中心像素之间相似程度、颜色强度、深度距离等),在计算中心像素的时候同时考虑着两个权重。
双边滤波有两个权重域的概念:空间域(spatial domain S)和像素域(range domain R),这个是它跟高斯滤波等方法的最大不同点。
高斯滤波:
双边滤波:
双边滤波的核函数是空间域核和像素范围域核的综合结果:在图像的平坦区域,像素值变化很小,对应的像素范围域权重接近于1,此时空间域权重起主要作用,相当于进行高斯模糊;在图像的边缘区域,像素变化很大 ,像素范围域权重变大,从而保持了边缘的信息。
双边滤波器使用二维高斯函数生成距离模板,使用一维高斯函数生成值域模板。
距离模板系数的生成公式如下:
d ( i , j , k , l ) = e x p ( − ( i − k ) 2 + ( j − l ) 2 2 σ d 2 ) d(i,j,k,l) = exp(-\frac{(i-k)^2 + (j -l)^2}{2\sigma_d^2}) d(i,j,k,l)=exp(−2σd2(i−k)2+(j−l)2)
其中, ( k , l ) (k,l) (k,l)为模板窗口的中心坐标; ( i , j ) (i,j) (i,j)为模板窗口的其他系数的坐标; σ d \sigma_{d} σd为高斯函数的标准差。使用该公式生成的滤波器模板和高斯滤波器使用的模板是没有区别的。
值域模板系数的生成公式如下:
r ( i , j , k , l ) = e x p ( − ∣ ∣ f ( i , j ) − f ( k , l ) ∣ ∣ 2 2 σ r 2 ) r(i,j,k,l)= exp(-\frac{||f(i,j)-f(k,l)||^2}{2\sigma_r^2}) r(i,j,k,l)=exp(−2σr2∣∣f(i,j)−f(k,l)∣∣2)
其中,函数 f ( x , y ) f(x,y) f(x,y)表示要处理的图像, f ( x , y ) f(x,y) f(x,y)表示图像在点 ( x , y ) (x,y) (x,y)处的像素值; ( k , l ) (k,l) (k,l)为模板窗口的中心坐标; ( i , j ) (i,j) (i,j)为模板窗口的其他系数的坐标; σ r \sigma_{r} σr为高斯函数的标准差。
将上述两个模板相乘就得到了双边滤波器的模板:
w ( i , j , k , l ) = d ( i , j , k , l ) ∗ r ( i , j , k , l ) = e x p ( − ( i − k ) 2 + ( j − l ) 2 2 σ d 2 − ∣ ∣ f ( i , j ) − f ( k , l ) ∣ ∣ 2 2 σ r 2 ) w(i,j,k,l) = d(i,j,k,l) * r(i,j,k,l) = exp(-\frac{(i-k)^2 + (j -l)^2}{2\sigma_d^2}-\frac{||f(i,j)-f(k,l)||^2}{2\sigma_r^2}) w(i,j,k,l)=d(i,j,k,l)∗r(i,j,k,l)=exp(−2σd2(i−k)2+(j−l)2−2σr2∣∣f(i,j)−f(k,l)∣∣2)
前面介绍的滤波器都属于平滑滤波器(低通滤波器),用来平滑图像和抑制噪声的;而锐化空间滤波器恰恰相反,主要用来增强图像的突变信息,图像的细节和边缘信息。平滑滤波器主要是使用领域的均值(或中值)来代替模板中心的像素,削弱和邻域间的差别,以达到平滑图像和抑制噪声的目的;相反,锐化滤波器则使用邻域的微分作为算子,增大邻域间像素的差值,使图像的突变部分变的更加明显。
图像的锐化也就是增强图像的突变部分,对图像中恒定区域中,突变的开始点与结束点(台阶和斜坡突变)及沿着灰度斜坡处的微分的性质。微分是对函数局部变化率的一种表示,一阶微分性质:
二阶微分是一阶微分的导数,有以下几个性质:
从以上图像灰度的一阶和二阶微分的性质可以看出,在灰度值变化的地方,一阶微分和二阶微分的值都不为0;在灰度恒定的地方,微分值都为0,不论是使用一阶微分还是二阶微分都可以得到图像灰度的变化值。
图像可以看作是二维离散函数,对于图像的一阶微分其计算公式如下:
在x方向: ∂ f ∂ x = f ( x + 1 ) − f ( x ) \frac{\partial f} {\partial x} = f(x + 1) - f(x) ∂x∂f=f(x+1)−f(x)
在y方向: ∂ f ∂ y = f ( y + 1 ) − f ( y ) \frac{\partial f} {\partial y} = f(y + 1) - f(y) ∂y∂f=f(y+1)−f(y)
对于二阶微分有:
在x方向: ∂ 2 f ∂ x 2 = f ( x + 1 ) + f ( x − 1 ) − 2 f ( x ) \frac{\partial^2 f} {\partial x^2} = f(x + 1) + f(x - 1) - 2 f(x) ∂x2∂2f=f(x+1)+f(x−1)−2f(x)
在y方向: ∂ 2 f ∂ y 2 = f ( y + 1 ) + f ( y − 1 ) − 2 f ( y ) \frac{\partial^2 f} {\partial y^2} = f(y + 1) + f(y - 1) -2 f(y) ∂y2∂2f=f(y+1)+f(y−1)−2f(y)
对于图像的边缘来说,通常会形成一个斜坡过度。一阶微分在斜坡处的值不为0,那么用其得到的边缘较粗;而二阶微分在斜坡处的值为0,但在斜坡两端值不为0,且值的符号不一样,这样二阶微分得到的是一个由0分开的一个像素宽的双边源。也就是说,二阶微分在增强图像细节方面比一阶微分好的多,并且在计算上也要比一阶微分方便。
在图像处理中的一阶微分通常使用梯度的幅值来实现。对于图像 f ( x , y ) f(x,y) f(x,y), f f f在坐标 ( x , y ) (x,y) (x,y)处的梯度是一个列向量
∇ f = g r a d ( f ) = [ g x g y ] = [ ∂ f ∂ x ∂ f ∂ y ] \nabla f = grad(f) = \left[ \begin{array}{c} g_x \\ g_y \end{array} \right] = \left[\begin{array}{c} \frac{\partial f} {\partial x} \\ \frac{\partial f} {\partial y} \end{array} \right] ∇f=grad(f)=[gxgy]=[∂x∂f∂y∂f]
该向量表示图像中的像素点在 ( x , y ) (x,y) (x,y)处灰度值的最大变化率的方向。
向量 ∇ f \nabla f ∇f的幅值就是图像 f ( x , y ) f(x,y) f(x,y)的梯度图,记为 M ( x , y ) M(x,y) M(x,y)
M ( x , y ) = m a g ( ∇ f ) = g x 2 + g y 2 M(x,y) = mag(\nabla f) = \sqrt{g_x^2 + g_y^2} M(x,y)=mag(∇f)=gx2+gy2
M ( x , y ) M(x,y) M(x,y)是和原图像 f ( x , y ) f(x,y) f(x,y)同大小的图像。由于求平方的根运算比较费时,通常可以使用绝对值的和来近似。
M ( x , y ) ≈ ∣ g x ∣ + ∣ g y ∣ M(x,y) \approx \mid g_x \mid + \mid g_y \mid M(x,y)≈∣gx∣+∣gy∣
从上面可以看出,要得到图像的梯度图,有以下步骤:
图像是以离散的形式存储的,通常用差分来计算图像的微分。
根据梯度的定义
g x = f ( x + 1 , y ) − f ( x , y ) g y = f ( x , y + 1 ) − f ( x , y ) g_x = f(x+1,y) - f(x,y) \\ g_y = f(x,y+1) - f(x,y) gx=f(x+1,y)−f(x,y)gy=f(x,y+1)−f(x,y)
可以得到模板 [ − 1 1 ] \left[ \begin{array}{c} -1 & 1\end{array}\right] [−11]和 [ − 1 1 ] \left[ \begin{array}{c} -1 \\ 1\end{array}\right] [−11]。
使用该方法计算的图像的梯度只是考虑单个像素的差值,并没有利用到图像的像素的邻域特性。
Robert交叉算子
Robert梯度算子利用对角方向相邻两像素之差作为衡量标准,计算方法如下:
g x = f ( x + 1 , y + 1 ) − f ( x , y ) g_x = f(x+1,y+1)-f(x,y) gx=f(x+1,y+1)−f(x,y)
g y = f ( x , y + 1 ) − f ( x + 1 , y ) g_y = f(x,y+1)-f(x+1,y) gy=f(x,y+1)−f(x+1,y)
M ( x , y ) = ∣ g x ∣ + ∣ g y ∣ M(x,y) = \mid g_x \mid + \mid g_y \mid M(x,y)=∣gx∣+∣gy∣
可以得到模板
[ − 1 0 0 1 ] a n d [ 0 − 1 1 0 ] \left[ \begin{array}{cc} -1 & 0 \\ 0 & 1 \end{array} \right] and \left[ \begin{array}{cc} 0 & -1 \\ 1 & 0 \end{array} \right] [−1001]and[01−10]
Prewitt算子
prewitt算子结合了差分运算与邻域平均的方法。其卷积模板如下:
[ − 1 − 1 − 1 0 0 0 1 1 1 ] 和 [ − 1 0 1 − 1 0 1 − 1 0 1 ] \left[ \begin{array}{ccc} -1 & -1 & -1 \\ 0 & 0 & 0 \\ 1 & 1 & 1 \end{array} \right] 和 \left[ \begin{array}{ccc} -1 & 0 & 1 \\ -1 & 0 & 1 \\ -1 & 0 & 1 \end{array} \right] ⎣⎡−101−101−101⎦⎤和⎣⎡−1−1−1000111⎦⎤
Sobel算子
sobel算子与prewitt算子类似,但考虑了相邻不同像素点的影响程度是不同的,所以采用加权平均,卷积模板如下:
[ − 1 − 2 − 1 0 0 0 1 2 1 ] 和 [ − 1 0 1 − 2 0 2 − 1 0 1 ] \left[ \begin{array}{ccc} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{array} \right] 和 \left[ \begin{array}{ccc} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{array} \right] ⎣⎡−101−202−101⎦⎤和⎣⎡−1−2−1000121⎦⎤
第一个模板,第三行和第一行的差近似x方向的偏微分;第二个模板,第三列和第一列的差近似y方向的偏微分,而且模板的所有系数只和为0,表示恒定灰度区域的响应为0,Sobel得到的边缘较粗。
Canny算子是一个具有滤波、增强、检测的多阶段的优化算子。
Canny边缘检测算法:
链接边缘的具体步骤如下:
[1] 图像处理基础(2):自适应中值滤波器(基于OpenCV实现)
[2] 图像处理基础(3):均值滤波器及其变种
[3] 线性滤波、非线性滤波区别
[4] openCV学习笔记(二十) —— 图像滤波 —— 线性滤波(方框滤波、均值滤波、高斯滤波)
[5] 【OpenCV学习笔记】之图像平滑(线性/非线性滤波器)
[6] 【数字图像处理】七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解
[7] 关于平滑处理及图像滤波与滤波器
[8] 图像卷积与滤波的一些知识点
[9] 高斯模糊的原理是什么,怎样在界面中实现?
[10] python的N个小功能(高斯模糊原理及实践)
[11] 图像处理基础(4):高斯滤波器详解
[12] Bilateral Filters(双边滤波算法)原理及实现
[13] 图像处理基础(5):双边滤波器
[16] 图像处理基础(6):锐化空间滤波器
[17] 边缘检测算法
[18] Canny边缘检测(转)