图像滤波用于去除噪声和图像平滑,OpenCV 提供了多种滤波器:
1.1. 均值滤波:
python
import cv2
# 读取图像
image = cv2.imread("example.jpg")
# 均值滤波
blurred_image = cv2.blur(image, (5, 5)) # (5, 5) 是滤波核的大小
滤波核大小的影响:
- 滤波核需要设定为奇数,确保有中心点
- 滤波核变大
-
- 平滑效果增强:更大的滤波核会考虑更多的邻域像素,从而导致更强的平滑效果。图像中的噪声和高频信息(如边缘、纹理)会被更有效地去除,图像整体看起来更加模糊。
- 计算时间增加:滤波核越大,需要处理的像素数量越多,计算时间也会相应增加。
- 细节丢失增加:较大的滤波核可能会导致图像细节(如物体的边缘和纹理)的丢失。这是因为在计算均值时,更多的像素被考虑进去,而这些像素可能包含图像中的关键细节。
- 滤波核变小
-
- 平滑效果减弱:较小的滤波核只能覆盖较小的邻域像素,因此平滑效果相对较弱。图像中的噪声和高频信息可能无法被完全去除,但图像的细节能够得到更好的保留。
- 计算时间减少:较小的滤波核需要处理的像素数量较少,计算时间也会相应减少。
- 细节保留更好:较小的滤波核能够更好地保留图像中的细节,因为只有较少的像素被用于计算均值,从而避免了过度平滑导致的细节丢失。
- **总结:**如果需要移除大量噪声并获得更平滑的图像,可以使用较大的滤波核。如果需要保留更多细节并稍微减少噪声,则应选择较小的滤波核。
python
#函数:对比均值滤波不同滤波核结果
@staticmethod
def TestBlur():
image=cv2.imread("Fu.jpg")
# image=cvTest.add_salt_and_pepper_noise(cv2.imread("Cat.jpg"))
blurred_3x3=cv2.blur(image,(3,3))
blurred_5x5=cv2.blur(image,(5,5))
blurred_7x7=cv2.blur(image,(7,7))
# 显示结果
plt.figure(figsize=(12, 6))
plt.subplot(221), plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)), plt.title('Original Image')
plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(cv2.cvtColor(blurred_3x3, cv2.COLOR_BGR2RGB)), plt.title('Blur 3x3')
plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(cv2.cvtColor(blurred_5x5, cv2.COLOR_BGR2RGB)), plt.title('Blur 5x5')
plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(cv2.cvtColor(blurred_7x7, cv2.COLOR_BGR2RGB)), plt.title('Blur 7x7')
plt.xticks([]), plt.yticks([])
plt.show()

1.2. 中值滤波
python
# 中值滤波
median_filtered = cv2.medianBlur(image, 5) # 5 是滤波核的大小
滤波核大小的影响:
- 滤波核变大
-
- 去噪能力增强 :较大的滤波核能够覆盖更多的像素,因此能更好地去除图像中的噪声,特别是对于那些孤立的噪声点(如椒盐噪声)。例如,使用
ksize=5
的滤波核可以更有效地去除椒盐噪声。 - 计算时间增加:随着滤波核的增大,需要排序的像素数量增多,计算时间也会相应增加。
- 细节丢失增加:较大的滤波核可能会导致图像细节的丢失,因为排序后取中值的过程会使图像的某些边缘或纹理变得模糊。例如,对于图像中的细小文字或线条,使用较大的滤波核可能会使这些细节变得不清晰。
- 去噪能力增强 :较大的滤波核能够覆盖更多的像素,因此能更好地去除图像中的噪声,特别是对于那些孤立的噪声点(如椒盐噪声)。例如,使用
- 滤波核变小
-
- 去噪能力减弱 :较小的滤波核只能覆盖较少的像素,因此对噪声的去除效果相对较弱。例如,使用
ksize=3
的滤波核对于去除大量的椒盐噪声可能效果不佳。 - 计算时间减少:较小的滤波核需要处理的像素数量较少,因此计算时间会相应减少。
- 细节保留更好:较小的滤波核能够更好地保留图像中的细节,因为排序后取中值的过程对像素值的影响较小。例如,对于图像中的边缘和纹理,使用较小的滤波核可以更好地保留它们。
- 去噪能力减弱 :较小的滤波核只能覆盖较少的像素,因此对噪声的去除效果相对较弱。例如,使用
总结:
- 滤波核变大:去噪能力增强,计算时间增加,细节丢失增加。
- 滤波核变小:去噪能力减弱,计算时间减少,细节保留更好。
python
#模拟椒盐噪声
@staticmethod
def add_salt_and_pepper_noise(image, salt_prob=0.02, pepper_prob=0.02):
noisy_image = np.copy(image)
total_pixels = image.size
# 计算盐和胡椒的数量
num_salt = np.ceil(salt_prob * total_pixels)
num_pepper = np.ceil(pepper_prob * total_pixels)
# 添加盐噪声
for _ in range(int(num_salt)):
x_coord = np.random.randint(0, image.shape[1])
y_coord = np.random.randint(0, image.shape[0])
noisy_image[y_coord, x_coord] = 255
# 添加胡椒噪声
for _ in range(int(num_pepper)):
x_coord = np.random.randint(0, image.shape[1])
y_coord = np.random.randint(0, image.shape[0])
noisy_image[y_coord, x_coord] = 0
return noisy_image
#函数:对比 中值滤波不同核去噪效果
@staticmethod
def TestMedioBlur():
#读取图像
image = cv2.imread("Cat.jpg")
# 添加椒盐噪声
noisy_image = cvTest.add_salt_and_pepper_noise(image) # 假设已添加椒盐噪声的图像
# 应用不同大小的中值滤波
filtered_3 = cv2.medianBlur(noisy_image, 3)
filtered_5 = cv2.medianBlur(noisy_image, 5)
filtered_7 = cv2.medianBlur(noisy_image, 7)
# 显示结果
plt.figure(figsize=(12, 6))
plt.subplot(221), plt.imshow(cv2.cvtColor(noisy_image, cv2.COLOR_BGR2RGB)), plt.title('Noisy Image')
plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(cv2.cvtColor(filtered_3, cv2.COLOR_BGR2RGB)), plt.title('Median Filter 3x3')
plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(cv2.cvtColor(filtered_5, cv2.COLOR_BGR2RGB)), plt.title('Median Filter 5x5')
plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(cv2.cvtColor(filtered_7, cv2.COLOR_BGR2RGB)), plt.title('Median Filter 7x7')
plt.xticks([]), plt.yticks([])
plt.show()

1.3. 高斯滤波
python
# 高斯滤波
gaussian_filtered = cv2.GaussianBlur(image, (5, 5), 0) # (5, 5) 是滤波核的大小,0 是标准差
函数参数:
cv2.GaussianBlur(image, ksize, sigmaX, sigmaY=0, borderType=BORDER_DEFAULT)
是 OpenCV 中用于高斯滤波的函数。其参数如下:
- image:输入图像。
- ksize:滤波核的大小,为
(width, height)
格式的元组,必须是正奇数(如(5, 5)
)。表示滤波窗口的宽度和高度。 - sigmaX:X 方向的标准差,控制高斯核在水平方向上的平滑程度。如果设置为 0,则会根据
ksize
自动计算。 - sigmaY:Y 方向的标准差,控制高斯核在垂直方向上的平滑程度。如果设置为 0,则会使用与
sigmaX
相同的值。 - borderType:边界处理方式,默认为
BORDER_DEFAULT
,表示使用默认的边界处理方法。
工作原理:
高斯滤波是一种基于高斯函数的平滑滤波技术,用于去除图像中的噪声。其基本思想是:
- 对于图像中的每一个像素,考虑以其为中心的一个
ksize × ksize
的邻域。 - 使用高斯函数计算该邻域内每个像素的权重 ,权重值随着距离中心像素的距离增加而减小。
- 将邻域内所有像素的加权平均值作为该像素的新值。
高斯函数的公式为: G (x ,y )=2π σ 21e −2σ 2x 2+y 2 其中,σ 是标准差,控制高斯核的宽度。
滤波核大小的影响:
- 滤波核变大
-
- 平滑效果增强 :较大的滤波核会覆盖更多的像素,因此能更有效地去除图像中的噪声,特别是高频噪声(如高斯噪声)。图像会变得更加平滑,但边缘和细节可能会变得模糊。例如,使用
ksize=(11, 11)
的滤波核可以显著减少噪声,但图像的细节会丢失较多。 - 计算时间增加:随着滤波核的增大,需要处理的像素数量增多,计算时间也会相应增加。
- 细节丢失增加:较大的滤波核可能会导致图像细节的丢失,因为高斯核的权重分布使得远离中心的像素对结果的影响减小,从而导致图像的边缘和纹理变得模糊。
- 平滑效果增强 :较大的滤波核会覆盖更多的像素,因此能更有效地去除图像中的噪声,特别是高频噪声(如高斯噪声)。图像会变得更加平滑,但边缘和细节可能会变得模糊。例如,使用
- 滤波核变小
-
- 平滑效果减弱 :较小的滤波核只能覆盖较少的像素,因此对噪声的去除效果相对较弱。图像中的高频噪声可能无法被完全去除,但图像的细节能够得到更好的保留。例如,使用
ksize=(3, 3)
的滤波核可以轻微减少噪声,同时保留较多的图像细节。 - 计算时间减少:较小的滤波核需要处理的像素数量较少,因此计算时间会相应减少。
- 细节保留更好:较小的滤波核能够更好地保留图像中的细节,因为高斯核的权重分布使得邻域内的像素对结果的影响较大,从而避免了过度平滑导致的细节丢失。
- 平滑效果减弱 :较小的滤波核只能覆盖较少的像素,因此对噪声的去除效果相对较弱。图像中的高频噪声可能无法被完全去除,但图像的细节能够得到更好的保留。例如,使用
标准差的影响:
- sigmaX****和 sigmaY****变大
-
- 平滑效果增强 :较大的标准差 会使高斯核的权重分布更加平缓,从而导致更强的平滑效果 。图像中的噪声会被更有效地去除 ,但图像的细节和边缘可能会变得更加模糊 。例如,使用
sigmaX=10
和sigmaY=10
会显著平滑图像,但可能会导致图像的边缘和纹理变得不清晰。 - 计算时间增加:较大的标准差会增加高斯核的计算复杂度,从而导致计算时间增加。
- 平滑效果增强 :较大的标准差 会使高斯核的权重分布更加平缓,从而导致更强的平滑效果 。图像中的噪声会被更有效地去除 ,但图像的细节和边缘可能会变得更加模糊 。例如,使用
- sigmaX****和 sigmaY****变小
-
- 平滑效果减弱 :较小的标准差会使高斯核的权重分布更加集中,从而导致较弱的平滑效果。图像中的噪声可能无法被完全去除,但图像的细节能够得到更好的保留。例如,使用
sigmaX=1
和sigmaY=1
可以轻微减少噪声,同时保留较多的图像细节。 - 计算时间减少:较小的标准差会减少高斯核的计算复杂度,从而导致计算时间减少。
- 平滑效果减弱 :较小的标准差会使高斯核的权重分布更加集中,从而导致较弱的平滑效果。图像中的噪声可能无法被完全去除,但图像的细节能够得到更好的保留。例如,使用
python
def add_gaussian_noise(image, mean=0, sigma=25):
"""
添加高斯噪声到图像。
参数:
image: 输入图像 (灰度或彩色)
mean: 高斯噪声的均值,默认为0
sigma: 高斯噪声的标准差,默认为25
返回:
noisy_image: 添加了高斯噪声后的图像
"""
# Ensure the image is in float32 format and normalized to [0, 1]
if len(image.shape) == 2:
row, col = image.shape
ch = 1
img = image.astype(np.float32) / 255.0
else:
row, col, ch = image.shape
img = image.astype(np.float32) / 255.0
# Generate Gaussian noise
gauss = np.random.normal(mean, sigma / 255.0, (row, col, ch))
gauss = gauss.reshape(row, col, ch)
# Add the Gaussian noise to the image
noisy_image = img + gauss
# Clip the values to stay within [0, 1] range and convert back to uint8
noisy_image = np.clip(noisy_image, 0, 1)
noisy_image = (noisy_image * 255).astype(np.uint8)
return noisy_image
@staticmethod
def TestGauss():
# 读取图像
image = cv2.imread("Cat.jpg")
# 添加高斯噪声
noisy_image = cvTest.add_gaussian_noise(image)
# 应用不同大小的高斯滤波
filtered_3 = cv2.GaussianBlur(noisy_image, (3, 3), 1)
filtered_5 = cv2.GaussianBlur(noisy_image, (5, 5), 2)
filtered_11 = cv2.GaussianBlur(noisy_image, (11, 11), 5)
# 显示结果
plt.figure(figsize=(12, 6))
plt.subplot(221), plt.imshow(cv2.cvtColor(noisy_image, cv2.COLOR_BGR2RGB)), plt.title('Noisy Image')
plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(cv2.cvtColor(filtered_3, cv2.COLOR_BGR2RGB)), plt.title('Gaussian Filter 3x3')
plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(cv2.cvtColor(filtered_5, cv2.COLOR_BGR2RGB)), plt.title('Gaussian Filter 5x5')
plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(cv2.cvtColor(filtered_11, cv2.COLOR_BGR2RGB)), plt.title('Gaussian Filter 11x11')
plt.xticks([]), plt.yticks([])
plt.show()

总结:
- 滤波核变大:平滑效果增强,计算时间增加,细节丢失增加。
- 滤波核变小:平滑效果减弱,计算时间减少,细节保留更好。
- 标准差变大:平滑效果增强,计算时间增加,细节丢失增加。
- 标准差变小:平滑效果减弱,计算时间减少,细节保留更好。
1.4. 双边滤波
python
# 双边滤波
bilateral_filtered = cv2.bilateralFilter(image, 9, 75, 75) # 9 是滤波核的大小,75 是色彩空间的标准差,75 是坐标空间的标准差
函数参数:
cv2.bilateralFilter(image, d, sigmaColor, sigmaSpace, borderType=BORDER_DEFAULT)
是 OpenCV 中用于双边滤波的函数。其参数如下:
- image:输入图像。
- d:滤波器的直径,表示滤波窗口的大小。必须是正奇数(如 5、9、15 等)。如果设置为负值,则会根据
sigmaSpace
自动计算。 - sigmaColor:颜色空间的标准差,控制像素值相似度的影响范围。值越大,颜色相似的像素对滤波结果的影响越大。
- sigmaSpace:坐标空间的标准差,控制像素空间距离的影响范围。值越大,空间距离较远的像素对滤波结果的影响越大。
- borderType:边界处理方式,默认为
BORDER_DEFAULT
,表示使用默认的边界处理方法。
工作原理:
双边滤波是一种非线性的滤波方法,结合了图像的空间邻近度和像素值相似度,达到保边去噪的目的。其基本思想是:
- 对于图像中的每一个像素,考虑以其为中心的一个
d × d
的邻域。 - 使用两个高斯函数计算该邻域内每个像素的权重:
-
- 空间域高斯函数:权重随着距离中心像素的空间距离增加而减小。
- 值域高斯函数:权重随着像素值与中心像素值的差值增加而减小。
- 将邻域内所有像素的加权平均值作为该像素的新值。
由于其内部仍然使用了高斯滤波,所以d的影响与sigma的影响与高斯滤波的相同,总结如下:
- 滤波核变大:平滑效果增强,计算时间增加,细节丢失增加。
- 滤波核变小:平滑效果减弱,计算时间减少,细节保留更好。
- sigmaColor****变大:颜色相似度影响增强,平滑效果增强,细节丢失增加。
- sigmaColor****变小:颜色相似度影响减弱,平滑效果减弱,细节保留更好。
- sigmaSpace****变大:空间距离影响增强,平滑效果增强,细节丢失增加。
- sigmaSpace****变小:空间距离影响减弱,平滑效果减弱,细节保留更好。
对比代码如下:
python
@staticmethod
def TestBilateralFilter():
# 读取图像
image = cv2.imread("Cat.jpg")
# 添加高斯噪声
noisy_image = cvTest.add_gaussian_noise(image) # 假设已添加高斯噪声的图像
# 应用不同参数的双边滤波
filtered_5 = cv2.bilateralFilter(noisy_image, 5, 50, 50)
filtered_9 = cv2.bilateralFilter(noisy_image, 9, 100, 100)
filtered_15 = cv2.bilateralFilter(noisy_image, 15, 150, 150)
# 显示结果
plt.figure(figsize=(12, 6))
plt.subplot(221), plt.imshow(cv2.cvtColor(noisy_image, cv2.COLOR_BGR2RGB)), plt.title('Noisy Image')
plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(cv2.cvtColor(filtered_5, cv2.COLOR_BGR2RGB)), plt.title('Bilateral Filter 5')
plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(cv2.cvtColor(filtered_9, cv2.COLOR_BGR2RGB)), plt.title('Bilateral Filter 9')
plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(cv2.cvtColor(filtered_15, cv2.COLOR_BGR2RGB)), plt.title('Bilateral Filter 15')
plt.xticks([]), plt.yticks([])
plt.show()

1.5. 高通滤波
1.5.1. OpenCV中的实现有三种方式:
- Sobel 算子 :用于计算图像的梯度,实现高通滤波。使用函数
cv2.Sobel()
。 - Laplacian 算子 :用于检测图像中的二阶导数,实现高通滤波。使用函数
cv2.Laplacian()
。 - 自定义高通滤波器 :通过定义自定义的卷积核,使用函数
cv2.filter2D()
实现高通滤波。
Sobel 算子
- Sobel 算子是一种用于计算图像梯度的微分算子。它通过计算图像在水平和垂直方向上的梯度来实现高通滤波。
- 其核心思想是利用卷积核与图像进行卷积运算,从而检测图像中的边缘和轮廓。
- Sobel 算子由两个方向的卷积核组成,分别用于检测水平和垂直方向的梯度。
- 边缘在梯度幅值较高的区域。
水平方向卷积核:

,
垂直方向卷积核:

作用:
- Sobel 算子主要用于边缘检测和图像增强。通过计算图像的梯度,可以突出图像中的边缘和轮廓,从而增强图像的细节。
实现方式:
使用函数 cv2.Sobel()
:
python
cv2.Sobel(
src, # 输入图像
ddepth, # 输出图像的深度,通常设置为 cv2.CV_64F
dx, # 表示对x方向求导
dy, # 表示对y方向求导
ksize=3, # 卷积核的大小,可以是 1、3、5 或 7
scale=1, # 比例因子 求导结果放大缩小 X 法 增大>1 减少 <1
delta=0, # 偏移量 求导结果整体+ -
borderType=cv2.BORDER_DEFAULT # 边界扩展方式 定义图像边界的处理方式,以避免在卷积过程中超出图像范围。 一般默认即可
)
应用
- 边缘检测:结合水平和垂直方向的梯度,计算图像的梯度幅值和方向。
- 图像增强:通过增强图像的梯度,使边缘更加明显。
例子:
有一个圆形和方形,
- 分别使用sobel算子计算x方向与y方向的梯度
- 将结果(Numpy数组)转化为图片数据范围(Uint8)
- 通过结果可以很清晰的观察到sobel算子的功能
python
@staticmethod
def TestSobel():
# 高通滤波(使用 Sobel 算子)
image=cv2.imread("Cicle.jpg")
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
sobelx = cv2.Sobel(gray_image, cv2.CV_64F, 1, 0, ksize=3) # x 方向
sobely = cv2.Sobel(gray_image, cv2.CV_64F, 0, 1, ksize=3) # y 方向
sobelx_img=cv2.convertScaleAbs(sobelx)
sobely_img=cv2.convertScaleAbs(sobely)
soble_combine=cv2.magnitude(sobelx,sobely)
soble_combine=cv2.convertScaleAbs(soble_combine)
# 显示结果
plt.figure(figsize=(12, 6))
plt.subplot(221), plt.imshow(cv2.cvtColor(gray_image, cv2.COLOR_BGR2RGB)), plt.title('Gray Image')
plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(cv2.cvtColor(sobelx_img, cv2.COLOR_BGR2RGB)), plt.title('sobelx Image')
plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(cv2.cvtColor(sobely_img, cv2.COLOR_BGR2RGB)), plt.title('sobely Image')
plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(cv2.cvtColor(soble_combine, cv2.COLOR_BGR2RGB)), plt.title('soble_combine Image')
plt.xticks([]), plt.yticks([])
plt.show()
结果:

原理理解:
我们自定义一个3*3的图像(Numpy数组),我们分别计算出sobelx和sobely的结果并输出
python
@staticmethod
def LearnSobel():
# 创建一个 3x3 的灰度图像
gray_image = np.array([
[100, 150, 200],
[100, 150, 200],
[100, 150, 200]
], dtype=np.uint8)
#查看其按照Sobel算子默认边界扩展类型扩展结果
# border_image=cv2.copyMakeBorder(gray_image,1,1,1,1,cv2.BORDER_DEFAULT)
# print("Border Image:")
print(border_image)
print("Original Image:")
print(gray_image)
# 使用 Sobel 算子计算 x 和 y 方向梯度
sobelx = cv2.Sobel(gray_image, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(gray_image, cv2.CV_64F, 0, 1, ksize=3)
# 打印结果
print("\nSobel X Gradient:")
print(sobelx)
print("\nSobel Y Gradient:")
print(sobely)
可以看到输出结果如下:
python
Original Image:
[[100 150 200]
[100 150 200]
[100 150 200]]
Sobel X Gradient:
[[ 0. 400. 0.]
[ 0. 400. 0.]
[ 0. 400. 0.]]
Sobel Y Gradient:
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Sobel默认卷积核为:
python
SobelX:
[[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]]
SobelY:
[[1, 2, 1],
[0, 0, 0],
[-1, -2, -1]]
中心像素点X方向梯度计算(使用Sobel算子):
以(2,2)的像素为例计算SobleX

- 逐行计算:
-
- 第一行:
(-100 + 0 + 200) = 100
- 第二行:
(-200 + 0 + 400) = 200
- 第三行:
(-100 + 0 + 200) = 100
- 第一行:
- 总和:
100 + 200 + 100 = 400
,得到:

边缘像素点X方向梯度计算:
在cv2.sobel内部会先按照设定的borderType=cv2.BORDER_DEFAULT(最开始函数介绍已介绍),扩展函数,然后再以原图像像素为中心的3*3范围的数组与SobelX卷积核计算得出该像素的梯度值。
我们可以自己计算扩展函数看一下:
python
# 创建一个 3x3 的灰度图像
gray_image = np.array([
[100, 150, 200],
[100, 150, 200],
[100, 150, 200]
], dtype=np.uint8)
border_image=cv2.copyMakeBorder(gray_image,1,1,1,1,cv2.BORDER_DEFAULT)
print("Border Image:")
print(border_image)
输出结果为
python
Border Image:
[[150 100 150 200 150]
[150 100 150 200 150]
[150 100 150 200 150]
[150 100 150 200 150]
[150 100 150 200 150]]
这样计算原图像中(1,1)的像素的x方向的梯度则使用:

Laplacian 算子
原理
- Laplacian 算子是一种基于二阶导数的微分算子,用于检测图像中的突变。
- 它通过计算图像的二阶导数来实现高通滤波,能够有效地检测图像中的边缘和细节。
Laplacian 算子的卷积核通常为:

作用
- Laplacian 算子主要用于边缘检测和图像锐化。通过增强图像的二阶导数,可以突出图像中的边缘和轮廓,从而达到锐化图像的效果。
Laplacian 算子检测边缘的过程:
- 计算二阶导数:通过卷积运算将 Laplacian 卷积核与图像进行卷积,得到图像的二阶导数近似值。
- 检测零交叉点:在边缘附近,二阶导数通常会过零点。因此,可以通过检测 Laplacian 响应中的零交叉点来确定边缘的位置。
- 衡量边缘强度:Laplacian 响应的绝对值大小可以衡量边缘的强度。绝对值越大,说明边缘越明显。
实现方式:
使用函数 cv2.Laplacian()
:
python
cv2.Laplacian(
src, # 输入图像
ddepth, # 输出图像的深度,通常设置为 cv2.CV_64F
ksize=1, # 卷积核的大小,可以是 1、3、5 或 7
scale=1, # 比例因子
delta=0, # 偏移量
borderType=cv2.BORDER_DEFAULT # 边界扩展方式
)
应用:
- 边缘检测:通过检测图像的二阶导数来突出边缘。
- 图像锐化:增强图像的细节和清晰度。
示例代码:
python
@staticmethod
def TestLaplacian():
image_gray=cv2.imread("Department.jfif",cv2.IMREAD_GRAYSCALE)
gaussi_image_gray=cv2.GaussianBlur(image_gray,(3,3),0)
#直接 laplacian 滤波
laplacianImage=cv2.Laplacian(image_gray,cv2.CV_64F)
laplacianImage=cv2.convertScaleAbs(laplacianImage)
#高斯滤波平滑处理后再
laplacianImage_gaussi=cv2.Laplacian(image_gray,cv2.CV_64F)
laplacianImage_gaussi=cv2.convertScaleAbs(laplacianImage_gaussi)
plt.figure(figsize=(12,6))
plt.subplot(131),plt.imshow(cv2.cvtColor(image_gray, cv2.COLOR_BGR2RGB)),plt.title("Original Image"),plt.xticks([]),plt.yticks([])
plt.subplot(132),plt.imshow(cv2.cvtColor(laplacianImage,cv2.COLOR_BGR2RGB) ),plt.title("laplacian Image"),plt.xticks([]),plt.yticks([])
plt.subplot(133),plt.imshow(cv2.cvtColor(laplacianImage_gaussi,cv2.COLOR_BGR2RGB) ),plt.title("laplacian Image_gaussi "),plt.xticks([]),plt.yticks([])
plt.show()
不用照片的结果:


自定义高通滤波器
原理
- 自定义高通滤波器通过定义特定的卷积核来实现高通滤波。用户可以根据需求设计不同的卷积核,以达到不同的滤波效果。
- 卷积核的设计通常基于高斯函数或其他数学函数,以实现对特定频率的增强或抑制。
作用
- 自定义高通滤波器可用于实现特定的图像增强效果,如锐化、边缘检测和细节提取等。
实现方式
使用函数 cv2.filter2D()
:
python
cv2.filter2D(
src, # 输入图像
ddepth, # 输出图像的深度,通常设置为 cv2.CV_64F
kernel, # 自定义的卷积核
borderType=cv2.BORDER_DEFAULT # 边界扩展方式
)
应用
- 锐化:通过设计增强高频分量的卷积核,实现图像的锐化效果。
- 边缘检测:通过设计检测特定方向边缘的卷积核,实现图像的边缘检测。
示例代码
python
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图像
image = cv2.imread("example.jpg", cv2.IMREAD_GRAYSCALE)
# 定义自定义高通滤波器卷积核
kernel = np.array([
[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]
])
# 应用高通滤波
high_pass_filtered = cv2.filter2D(image, -1, kernel)
1.5.2. 总结
- Sobel 算子:适用于边缘检测和图像增强,能够计算图像的梯度。
- Laplacian 算子:适用于边缘检测和图像锐化,能够检测图像的二阶导数。
- 自定义高通滤波器:具有高度的灵活性,可根据需求设计特定的滤波器,可以自己改卷积核,实现各种图像处理效果, 需要学习顶层算法原理。
1.6. 低通滤波
在openCV中,常见的低通滤波实现方式就是上述已说明的滤波:
- 均值滤波
- 中值滤波
- 高斯滤波
- 双边滤波
详见上述内容