本帖最后由 fjexzl 于 2017-8-22 10:52 编辑
由于图像在形成﹑传输﹑接收和处理的过程中,不可避免的会存在一些干扰,如成像传感器噪声、相片颗粒噪声以及传输过程中的通道传输误差等,导致图像上会出现一些随机的、离散的和孤立的像素点,即图像噪声。噪声的存在无疑会恶化图像质量,使图像模糊,甚至淹没目标特征,给后续分析带来困难。因此去除噪声,恢复原始图像是图像处理中的一个很重要的内容。消除图像噪声的工作也被称为图像平滑或图像滤波。 图像滤波的方法有很多,一般来说主要分为空域滤波和频域滤波两类。空域滤波直接对图像的像素进行处理,主要是通过模板对邻域操作来达到滤波的目的,一般又可以分为线性滤波和非线性滤波两种。频域滤波是将图像从空域进行傅里叶变换成频谱域,通过检测和研究图像频谱特性来进行滤波处理,然后再将处理的频谱经傅里叶逆变换恢复图像于空间域。频域滤波数学过程复杂,而且计算量大,因此常用空间域滤波。在选用图像滤波方法时,有两个基本要求:一是提高图像清晰辨识度;二是不能破坏图像中的轮廓和边缘的细节信息。 图片中的噪声通常都是高斯白噪声或者椒盐噪声,因此对图像的去噪过程也就是消除这两类噪声的过程。消除高斯白噪声或者椒盐噪声从原理上讲使用的都是低通滤波的方波。低通滤波在消除图像噪声的同时,也会消除图像中有用的高频信息。因此,图像去噪方法本质上其实是在去除噪声和保留高频信息之间的一种权衡。 (1) 线性滤波 线性滤波的基本原理是对图像中每个像素的灰度值用其邻域均值代替,即针对待处理的当前像素点,选择一个模板,该模板由其临近的若干像素点组成,求模板中的所有像素灰度的均值,再把该均值赋予当前的像素点。假设一幅含有N*N个像素点的图像f(x,y)经线性滤波后得到g(x,y),则g(x,y)由下面公式决定: 式中,x,y=0,1,2,…, N-1;S是点(x,y)邻域中除了其自身的点的坐标集合,M是集合内坐标点的总数。 上述公式表明,经线性滤波后的图像g(x,y)中每个像素的灰度值均由其邻域内像素点的灰度平均值决定。邻域可以用模板来描述,模板通常取正方形﹑十字形﹑圆形或线形。滤波过程就是在图像f(x,y)上逐点移动模板,使模板中心和点(x,y)重合,模板在点(x,y)处的响应根据上述公式来确定。对于图像边界点,由于缺乏完整的邻域,可通过对边界进行对称延拓﹑周期延拓或补零延拓,也可以忽略图像边界区域,不进行处理。 在实际应用中,由于偶数尺寸的模板不具有对称性,因而很少被使用,基本上使用的都是奇数尺寸的模板,如3×3模板,5×5模板等(值得注意的是,由于1×1模板退化成点运算,因此应用较少)。典型的3×3低通滤波模板有: 其中,后两个模板增加了在模板中心像素或4邻域像素的权重,可更好地近似具有高斯概率分布的噪声特性。 但是线性滤波的效果并不是很理想。假设图片噪声是加性的且在空间上不相关的高斯噪声,其期望值为0,方差为 ,h是未被干扰的图像,含有噪声的图像f在点(i,j)处为: f(i, j) = h(i, j) + n(i, j) 经线性滤波后的图像g为:
由该公式可知,线性滤波后图像的噪声方差变为原来的1/M, 噪声方差变小,说明图像噪声强度被削弱,即噪声得到了抑制。但同时还应该看到,线性滤波也削弱了图像信号,尤其是可能使图像中待检测区域边界变得模糊,或细节对比度变差,并且随着邻域增大,图像模糊程度也变大。 OpenCV中均值模板可以用cv2.blur和cv2.boxFilter,模板大小m*n是可以设置的,测试脚本如下: - import cv2
- import matplotlib.pyplot as plt
- img = cv2.imread('messi.jpg',0)
- blur = cv2.blur(img,(5,5))
- plt.subplot(1,2,1),plt.imshow(img,'gray'),plt.title('ORIGINAL')
- plt.subplot(1,2,2),plt.imshow(blur,'gray'),plt.title('BLUR')
- plt.show()
复制代码
运行效果:
(2) 非线性滤波 由于线性滤波具有低通特性,在去除噪声的同时也会使图像变得模糊,因此很多时候得到的图像质量很难令人满意。非线性滤波则在一定程度上能克服线性滤波的这一缺点,它在去除噪声的同时能最大限度地保持图像信号的高频细节,使图像清晰逼真,因而得到了广泛的研究和应用。中值滤波作为一种比较经典的非线性滤波方法,由Turky在1971年提出,算法简单,易于理解实现,而且具有去噪复原效果好的特点。 中值滤波的基本思想是将图像中每个点邻域内的像素点灰度进行排序,取排序后的中值作为该点的像素灰度值。中值的定义如下:对于任意序列x1,x2,x3,...,xn,将其按从小到大排序则序列中值y为: y = Med(x1, x2, x3, ..., xn) 在中值滤波时需要设定邻域,即滑动窗口。滤波窗口的形状和尺寸对滤波效果影响很大,不同的图像内容和不同的应用要求,往往需要采用不同的形状和尺寸。常用的中值滤波窗口有线状﹑方形﹑十字形﹑圆形等。设矩阵表示数字图像的各点灰度值,那么经过窗口的中值滤波可定义为 式中,A(i,j)表示点(i,j)的滑动窗口,它含有n个像素。一般来说,窗口内的各点对输出的作用是相同的,如果希望强调中间点或距离中间点最近的几个点的作用,可以采用加权中值滤波法。 中值滤波的重要特性: ①非线性。对于序列f(r),g(r),有:
②对尖峰性干扰抑制效果好,既保持边缘的陡度又能去掉干扰。
OpenCV调用中值滤波器的方法与调用其他滤波器的方法类似,如下: result = cv2.medianBlur(img,5) 函数返回处理结果,第一个参数是待处理图像,第二个参数是孔径的尺寸,一个大于1的奇数。比如这里是5,中值滤波器就会使用5×5的范围来计算。即对像素的中心值及其5×5邻域组成了一个数值集,对其进行处理计算,当前像素被其中值替换掉。如果在某个像素周围有白色或黑色的像素,这些白色或黑色的像素不会选择作为中值(最大或最小值不用),而是被替换为邻域值。 测试脚本如下: - import cv2
- import numpy as np
- import matplotlib.pyplot as plt
- img = cv2.imread('messi.jpg',0)
- for i in range(2000):
- temp_x = np.random.randint(0,img.shape[0])
- temp_y = np.random.randint(0,img.shape[1])
- img[temp_x][temp_y] = 255
- med = cv2.medianBlur(img,5)
- plt.subplot(1,2,1),plt.imshow(img,'gray'),plt.title('ORIGINAL')
- plt.subplot(1,2,2),plt.imshow(med,'gray'),plt.title('Median')
- plt.show()
复制代码
运行效果如下:
小记: 本节介绍了机器视觉领域内常用的两种图像滤波原理,更多的方法大家可以自行查阅相关资料。接下来会继续介绍图像处理的相关知识,敬请期待。
|