图像处理之滤波

发布于:2024-12-18 ⋅ 阅读:(109) ⋅ 点赞:(0)

中值滤波、均值滤波、高斯滤波和双边滤波是常见的图像处理技术,主要用于去噪和图像平滑。低通滤波和高通滤波用于处理图像中的频率成分。它们的主要区别在于它们所允许通过的频率范围。滤波、卷积、去噪、模糊、提取特征是一个意思。

卷积就是两个矩阵的乘法,相同位置的两个元素相乘并加起来:
在这里插入图片描述
矩阵B叫滤波器或卷积核,卷积后得到的矩阵称为特征图。这就是去噪、提取特征的过程。

1. 均值滤波 (Mean Filtering)
原理: 均值滤波通过计算滤波窗口内所有像素的平均值来替代中心像素的值。它是线性滤波的一种。
优点:
实现简单,计算效率高。
能够有效去除均匀分布的噪声(如高斯噪声)。
缺点:
会导致图像模糊,细节丢失,尤其是在边缘和纹理丰富的区域。
对脉冲噪声(如盐和胡椒噪声)效果不佳。

2. 中值滤波 (Median Filtering)
原理: 中值滤波通过计算滤波窗口内所有像素的中值来替代中心像素的值。它是一种非线性滤波器。
优点:
在去除脉冲噪声(如盐和胡椒噪声)时效果显著,能够更好地保护边缘和细节。
相对于均值滤波,对于图像细节的保留更好。
缺点:
计算复杂度高于均值滤波,处理速度较慢。
当滤波窗口尺寸增大时,可能导致模糊,尤其是在噪声较少时,表现接近均值滤波。

3. 高斯滤波 (Gaussian Filtering)
原理: 高斯滤波使用高斯函数作为权重,对滤波窗口内的像素进行加权平均。靠近中心的像素权重更高,远离中心的像素权重较低。
优点:
能够平滑图像,同时保留边缘信息,适用于去除高斯噪声。
具有良好的数学性质,便于理论分析和实现。
缺点:
仍然会造成一定程度的模糊,尤其是在强噪声条件下。
对于脉冲噪声的去除效果不如中值滤波。

4. 双边滤波 (Bilateral Filtering)
原理: 双边滤波结合了空间距离和像素值的相似性,既考虑像素的空间位置,又考虑像素的颜色差异,从而在平滑图像的同时保留边缘信息。
优点:
能够有效去除噪声,同时保留图像的边缘和细节,是一种非常有效的图像平滑方法。
对于非均匀噪声和细节保护效果良好。
缺点:
计算复杂度高,处理速度较慢,尤其是在大图像上。
参数选择(如空间和颜色标准差)对结果影响较大,需要调试。

5 均值迁移滤波(Mean Shift Filtering)
是一种非线性的平滑技术,最初用于图像 segmentation 和目标跟踪。它通过在特征空间中寻找均值移动,从而帮助去除噪声,同时保护图像中重要的结构和边缘。
优点:
能有效去除噪声,同时保留图像的边缘信息。
适用于多种类型的噪声。
缺点:
计算复杂度相对较高,可能较慢。

在细节信息保护方面:
中值滤波在处理脉冲噪声时效果最佳,能够有效保留边缘。
均值滤波适合处理均匀噪声,但容易导致模糊。
高斯滤波在去除高斯噪声时表现良好,但仍会造成模糊。
双边滤波是最优选择之一,能够在去噪的同时保留边缘和细节,但计算代价较高。

在选择滤波方法时,需根据具体的应用场景和噪声类型来决定使用哪种滤波器。

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像
image = cv2.imread('1.png')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)  # 转换为 RGB 格式

# 均值滤波
mean_filtered = cv2.blur(image, (5, 5))

# 中值滤波
median_filtered = cv2.medianBlur(image, 5)

# 高斯滤波
gaussian_filtered = cv2.GaussianBlur(image, (5, 5), 0)

# 均值迁移滤波
meanshift_filtered = cv2.pyrMeanShiftFiltering(image, sp=20, sr=20)

# 显示所有结果
plt.subplot(1, 5, 1)
plt.title('Original ')
plt.imshow(image)
plt.axis('off')

plt.subplot(1, 5, 2)
plt.title('Mean Filtered')
plt.imshow(mean_filtered)
plt.axis('off')

plt.subplot(1, 5, 3)
plt.title('Median Filtered')
plt.imshow(median_filtered)
plt.axis('off')

plt.subplot(1, 5, 4)
plt.title('Gaussian Filtered')
plt.imshow(gaussian_filtered)
plt.axis('off')

plt.subplot(1, 5, 5)
plt.title('Mean Shift Filtered')
plt.imshow(meanshift_filtered)
plt.axis('off')

plt.tight_layout()
plt.show()

低通滤波 (Low-Pass Filtering)
定义: 低通滤波器允许低频信号通过,而抑制高频信号。它通常用于去除图像噪声和细节,使得图像更平滑。
应用: 主要用于图像平滑、去噪等场景。例如,在图像处理应用中,应用低通滤波可以减少细节,从而保留更平滑的视觉效果。

高通滤波 (High-Pass Filtering)
定义: 高通滤波器允许高频信号通过,而抑制低频信号。它通常用于增强图像边缘和细节。
应用: 主要用于图像增强,可以帮助加强图像中的边缘和细节。

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像并转换为灰度图像
img_man = cv2.imread('f:/ai/groceries.jpg', 0)
plt.figure(figsize=(12, 6))

# 显示原图
plt.subplot(1, 3, 1)
plt.imshow(img_man, cmap='gray')
plt.title('Original Image')
plt.axis('off')

# -------------------------------低通滤波
# 低通滤波
rows, cols = img_man.shape
crow, ccol = rows // 2, cols // 2  # 中心点

# 创建低通滤波器掩膜
lowpass_mask = np.zeros((rows, cols), np.uint8)
r = 30  # 半径
cv2.circle(lowpass_mask, (ccol, crow), r, 1, thickness=-1)  # 在中心画一个圆形

# 进行傅里叶变换,并应用低通掩膜
f1 = np.fft.fft2(img_man)
f1shift = np.fft.fftshift(f1)
f1low = f1shift * lowpass_mask  # 应用低通滤波

# 逆变换回到空间域
f2low = np.fft.ifftshift(f1low)
img_lowpass = np.fft.ifft2(f2low)
img_lowpass = np.abs(img_lowpass)  # 取幅值

# 归一化
img_lowpass = (img_lowpass - np.min(img_lowpass)) / (np.max(img_lowpass) - np.min(img_lowpass))

# 显示低通滤波结果
plt.subplot(1, 3, 2)
plt.imshow(img_lowpass, cmap='gray')
plt.title('Low Pass Filtered')
plt.axis('off')

# --------------------------------高通滤波
# 高通滤波
# 创建高通滤波器掩膜
highpass_mask = np.ones((rows, cols), np.uint8)
cv2.circle(highpass_mask, (ccol, crow), r, 0, thickness=-1)  # 在中心画一个圆形,值为0表示低频

# 进行傅里叶变换,并应用高通掩膜
f1high = f1shift * highpass_mask  # 应用高通滤波

# 逆变换回到空间域
f2high = np.fft.ifftshift(f1high)
img_highpass = np.fft.ifft2(f2high)
img_highpass = np.abs(img_highpass)  # 取幅值

# 归一化
img_highpass = (img_highpass - np.min(img_highpass)) / (np.max(img_highpass) - np.min(img_highpass))

# 显示高通滤波结果
plt.subplot(1, 3, 3)
plt.imshow(img_highpass, cmap='gray')
plt.title('High Pass Filtered')
plt.axis('off')

# 显示所有结果
plt.tight_layout()
plt.show()

在这里插入图片描述

代码说明
1、图像读取: 使用 cv2.imread() 读取图像并转换为灰度图。
2、低通滤波:
创建一个低通掩膜(mask),使用 cv2.circle() 在掩膜中创建一个圆形区域,该区域中的值设置为 1,表示保留。
对图像进行傅里叶变换
应用低通掩膜
进行逆变换
取反变换结果的幅值,并进行归一化处理
3、高通滤波:
创建一个高通掩膜(mask),通过在掩膜中心填充一个圆形(值为 0),这个掩膜只保留高频成分(图像的边缘和细节),掩膜中心的 值被设置为 0。以抑制低频成分。
进行傅里叶变换: np.fft.fft2(img_man) 计算图像的二维傅里叶变换,频域变换将图像的空间信息转化为频率信息。
应用高通掩膜:将掩膜应用到频域图像上,去除低频信息。
逆变换: 使用 np.fft.ifftshift() 和 np.fft.ifft2() 进行逆变换,恢复回空间域。
处理复数输出: 反变换后,结果是复数,因此使用 np.abs() 来获取复数的幅度。
进行归一化处理
4结果显示: 将原图、低通滤波后的结果和高通滤波后的结果一起显示。

使用 Scharr 和拉普拉斯算子来进行边缘检测

# -*- coding: utf-8 -*-
import cv2
import numpy as np

img = cv2.imread('f:/ai/groceries.jpg')

# 沙尔算子y方向边缘
d1 = cv2.Scharr(img, cv2.CV_64F, 1, 0)
# 沙尔算子x方向边缘
d2 = cv2.Scharr(img, cv2.CV_64F, 0, 1)

# dst = d1 + d2
dst = cv2.add(d1, d2)

# 拉普拉斯
ldst = cv2.Laplacian(img, cv2.CV_64F, ksize=5)

cv2.imshow('img', img)
cv2.imshow('d1', d1)
cv2.imshow('d2', d2)
cv2.imshow('dst', dst)

cv2.imshow('Laplacian', ldst)

key = cv2.waitKey(0) & 0xff
if key == ord('q'):
    cv2.destroyAllWindows()

网站公告

今日签到

点亮在社区的每一天
去签到