前言
在信息化时代,图像已成为人们获取信息、沟通交流的重要载体。随着科技的飞速发展,图像处理技术在医疗、安防、航天、教育等领域发挥着越来越重要的作用。然而,在实际应用中,图像往往受到噪声、模糊等质量问题的困扰,这些问题严重影响了图像的视觉效果和后续处理。为此,图像滤波技术应运而生,它旨在改善图像质量,为图像的进一步分析和应用奠定基础。本文将围绕图像滤波这一主题,介绍其基本原理、常见算法及其在实际应用中的重要作用。
一、简介:
由于图像采集、处理、传输等过程不可避免的会受到噪声的污染,妨碍人们对图像理解及分析处理。常见的图像噪声有高斯噪声、椒盐噪声等,为了对这些噪声进行处理,常常使用图像滤波技术,图像滤波按照目的划分可以分为两种,平滑滤波和锐化滤波。
平滑滤波,能减弱或消除图像中的高频分量,但不影响低频分量。因为高频分量对应图像中的区域边缘等灰度值具有较大、较快变化的部分,平滑滤波将这些分量绿区可减少局部灰度的起伏,使图像变得比较平滑。实际应用中,平滑滤波即可以用来消除噪声,又可以用在提取较大的目标前过滤去除较小的细节或将目标内的小间断连接起来。
锐化滤波,能减弱或消除图像中的低频分量,但不影响高频分量。因为低频分量对应图像中灰度值缓慢变化的区域,因而与图像的整体特性如整体对比度和平均灰度值等有关。锐化滤波将这些分量滤去可使图像反差增加,边缘明显。实际应用中,锐化滤波可用于增强图像中被模糊的细节或景物的边缘。
二、图像滤波实现:
要想实现图像滤波,首先要了解一下图像卷积,平滑滤波和锐化滤波都是通过图像卷积实现的,卷积运算就是对于图像 f(x,y) 中的每个像素,将其作为中心像素,计算它及其邻域像素和卷积核 w(a,b)对应位置元素的乘积,然后把结果相加到一起,得到的值就作为该中心像素的新值,这样就完成了一次卷积运算。然后将kernel向下或向左平移一位继续计算每个像素的新值,直到遍历完整个图像。
注意:
在图像滤波中,处理边缘中心像素时,若周围像素不足,可采用两种方法:一是忽略边缘像素的计算,对大图像影响较小;二是通过插值增加边缘像素,这是卷积操作中的常用方法。处理结果超出0-255范围时,应将其限制在该范围内。
在opencv中使用result = cv.filter2D(src, ddepth, kernel, dst=None, anchor=None, delta=None, borderType=None)进行图像卷积。
参数说明
src: 输入图像,可以是灰度图像或者彩色图像。
ddepth: 目标图像的所需深度,如果设置为 -1,则输出图像将与输入图像具有相同的深度。
kernel: 卷积核(滤波器),是一个二维数组,表示滤波器的权重。
dst: 输出图像,可以是一个预先分配的图像,如果不指定,则函数会自动分配。
anchor: 卷积核的锚点位置,默认值为 (-1, -1),表示锚点位于核中心。
delta: 可选值,用于添加到滤波结果中的值,可以在滤波后进行微调。
borderType: 边界类型,用于处理图像边界,默认值为 cv.BORDER_DEFAULT。
举例:
import cv2
import numpy as np
path = r"E:\PS\sky2.jpg"
img = cv2.resize(cv2.imread(path), (640,480))
kernel = np.array([[0, -1, 0],
[-1, 5, -1], # 锐化
[0, -1, 0]])
dst = cv2.filter2D(img, -1, kernel) # 图像卷积 -1代表和输入图一样
cv2.imshow("img",img)
cv2.imshow("dst",dst)
cv2.waitKey(0)
效果:
要想实现图像的卷积首先要根据图像的特征定义不同的卷积核,加大了使用的难度,opencv将几种常用的卷积操作进行封装,以此实现了不同的功能函数,下面介绍几个常用的滤波方法更多的滤波请看这里。
2.1 均值滤波:
均值滤波是典型的线性滤波算法,在图像中应用比较多,原理是以该像素点周围的八个像素点取平均操作,然后替代该像素点,均值滤波的特点是算法简单,计算速度快,缺点是去噪声的同时去除了很多细节部分,将图像变得模糊。opencv实现:dst = cv2.blur(src, ksize, dst=None, anchor=None, borderType=None)
参数说明
src: 输入图像,可以是灰度图像或者彩色图像。
ksize: 滤波核的大小。核的大小由宽度 和高度指定,它们都必须是正奇数。
dst: 输出图像,可以是一个预先分配的图像,如果不指定,则函数会自动分配。
anchor: 锚点位置,默认值为 (-1, -1),表示锚点位于核中心。
borderType: 边界类型,用于处理图像边界,默认值为 cv2.BORDER_DEFAULT。
特点:
- 简单性和高效性:均值滤波器的设计和实现非常简单,只需使用一个固定大小的卷积核,其中所有系数相等,这使得其计算效率较高,适合快速处理图像。
- 平滑效果:均值滤波通过对像素邻域内的平均值进行替换,能有效减少图像中的随机噪声,使图像整体看起来更加平滑。
2.2 高斯滤波:
高斯滤波是一种基于高斯分布的线性滤波器,它在图像处理中用于减少图像噪声和模糊图像。高斯滤波器通过对图像的每个像素点及其邻域内的像素点应用高斯权重函数进行加权平均,从而实现平滑效果。由于高斯函数具有很好的性质,如对称性和可分离性,因此高斯滤波器在图像处理中非常流行。
高斯滤波有以下几个特点:
- 权重分配:高斯滤波器为邻域内的每个像素分配不同的权重,中心像素权重最大,越远离中心权重越小。
- 可分离性:二维高斯函数可以分解为两个一维高斯函数的乘积,这意味着可以先沿着一个方向进行滤波,然后再沿着另一个方向滤波,从而减少计算量。
- 减少噪声:高斯滤波能有效减少高斯噪声,即随机分布的噪声。
其opencv函数为dst = cv2.GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)
src: 输入图像,可以是灰度图像或者彩色图像。
ksize: 高斯核的大小。核的大小由宽度和高度指定,它们都必须是正奇数。如果设置为 (0, 0),则函数会根据 sigmaX 和 sigmaY 自动计算核的大小。
sigmaX: X 方向的高斯核标准差。较大的值会导致更广泛的模糊效果。如果这个值是 0,那么它就会从 ksize 计算得出。
dst: 输出图像,可以是一个预先分配的图像,如果不指定,则函数会自动分配。
sigmaY: Y 方向的高斯核标准差。如果这个值是 0,则默认等于 sigmaX。
borderType: 边界类型,用于处理图像边界,默认值为 cv2.BORDER_DEFAULT。
2.3 中值滤波:
中值滤波是一种常用的图像处理技术,它通过计算图像中每个像素点及其邻域内像素的中值,并用这个中值替换原始像素值,从而实现图像平滑和去除噪声的目的。中值滤波特别适用于去除图像中的椒盐噪声,即随机分布的白点和黑点。
特点:
- 去除椒盐噪声:中值滤波非常有效于去除图像中的椒盐噪声,这是因为噪声像素通常与其邻域内的像素值差异较大,而中值滤波会将这些异常值替换为中值,从而消除噪声。
- 边缘保持:与均值滤波不同,中值滤波在平滑图像的同时,能够较好地保持图像的边缘和细节。这是因为中值滤波不依赖于邻域像素的加权平均,而是直接选择中值,这使得边缘像素不会被过度模糊。
- 非线性和不变性:中值滤波是一种非线性滤波技术,它对输入信号的变化不敏感,具有一定的鲁棒性。此外,中值滤波不会改变图像的亮度均值,因此对于图像的整体亮度保持不变。
opencv函数为dst = cv2.medianBlur(src, ksize)
src: 输入图像,可以是灰度图像或者彩色图像。
ksize: 滤波核的大小,它必须是大于1的正奇数。滤波核的大小决定了邻域的大小,即考虑多少个周围的像素来计算中值。
代码
# 1.60 彩色图像的直方图匹配
import cv2
import numpy as np
path = r"E:\PS\1700898802715.png"
img = cv2.resize(cv2.imread(path), (256,256)) # 读取图片并压缩
blur = cv2.blur(img,(5, 5)) # 均值滤波
gas = cv2.GaussianBlur(img, (5, 5), 1.5) # 高斯滤波
mid = cv2.medianBlur(img, 5) # 中值滤波
cv2.imshow("ori",img)
cv2.imshow("mid",mid)
cv2.imshow("blur",blur)
cv2.imshow("gas",gas)
cv2.waitKey(0)
效果:
2.4 锐化滤波:
图像锐化处理旨在通过增强图像的对比度来提升其清晰度,这一过程涉及对图像模糊的根本原因进行分析和针对性的增强策略。图像模糊通常是由于图像数据经过平均或积分运算导致的细节丢失,因此,图像锐化处理的核心在于通过微分运算来恢复这些细节,从而使图像变得更加清晰。
拉普拉斯算子是基于图像邻域内像素灰度差异的计算原理,它是一种基于二阶微分的图像邻域增强算法。该算子的基本原理是:当邻域中心像素的灰度低于其邻域内其他像素的平均灰度时,中心像素的灰度值应相应降低;反之,当中心像素的灰度高于邻域平均灰度时,其灰度值应相应提高。这一过程有助于突出图像的边缘和细节,从而实现图像的锐化。
在算法的实现过程中,通常通过对邻域中心像素进行四方向或八方向的梯度计算,并将梯度值相加以判断中心像素与邻域内其他像素的灰度关系。随后,根据梯度运算的结果对中心像素的灰度进行调整,以达到图像锐化的目的。通过这种方式,拉普拉斯算子能够有效地增强图像的对比度,提升图像的视觉效果。
opencv实现
dst = cv.Laplacian(src, ddepth, ksize=None, scale=None, delta=None, dst=None, borderType=None)
src: 输入图像,可以是灰度图像或者彩色图像。
ddepth: 输出图像的深度,如果设置为 -1,则输出图像将与输入图像具有相同的深度。
ksize: 卷积核的大小,它必须是正奇数。如果设置为 None,则默认为 3。
scale: 缩放因子,用于调整输出图像的值域范围。如果设置为 None,则默认为 1。
delta: 可选值,用于添加到滤波结果中的值,可以在滤波后进行微调。
dst: 输出图像,可以是一个预先分配的图像,如果不指定,则函数会自动分配。
borderType: 边界类型,用于处理图像边界,默认值为 cv.BORDER_DEFAULT
代码:
# 1.60 彩色图像的直方图匹配
import cv2
import numpy as np
# 1.78:图像锐化:拉普拉斯算子 (Laplacian)
img = cv2.imread(r"E:\PS\shadow1.jpg")
# 使用 cv2.Laplacian 实现 Laplace 卷积算子
imgLaplace = cv2.Laplacian(img, -1, ksize=3) #拉普拉斯获取细节
imgRecovery = cv2.add(img, imgLaplace) # 细节和原图叠加
cv2.imshow("lap",imgLaplace)
cv2.imshow("imgRecovery",imgRecovery)
cv2.waitKey(0)
效果: