数字图像处理:频率域滤波
笔者相关内容笔记:
1.傅里叶变换与图像处理
2.傅利叶变换在图像处理的应用
1.1 频率域滤波总体流程
1.2 DFT/IDFT
DFT的例子
1.3 常见频率域滤波器
过滤高频信息,保留低频信息,则图像模糊
过滤低频信息,保留高频信息,则显示图像细节
1.3.1 理想低通滤波器
1.3.2 Butterworth低通滤波器
1.3.3 Gauss低通滤波器
1.3.4 理想高通滤波器
1.3.5 Butterworth高通滤波器
1.3.6 Gauss高通滤波器
1.4 代码实现
(1)对一副图像进行缩放,显示原始图像和缩放后的图像,分别对其进行傅里 叶变换,显示变换后结果;
import matplotlib.pyplot as plt
import cv2 as cv
import numpy as np# 读取一幅图像(以灰度模式)
img_dir = r'D:\Document\Experiment\data\image1.jpg' # 图像路径
gray = cv.imread(img_dir, 0) # 读取图像,0表示以灰度图像模式读取# 对图像进行缩放
rows, cols = gray.shape[:2] # 获取原图像的行和列数
resize_gray = cv.resize(gray, (int(cols * 0.6), int(rows * 0.6))) # 将图像缩放到原来的60%# 显示原始图像和缩放后的图像
plt.figure(figsize=(10, 5)) # 创建一个10x5英寸的图形窗口
plt.subplot(1, 2, 1) # 创建一个1行2列的子图,并选择第1个
plt.title("gray") # 设置子图的标题
plt.imshow(gray, cmap='gray') # 显示原始灰度图像plt.subplot(1, 2, 2) # 选择第2个子图
plt.title("Resize_gray") # 设置子图的标题
plt.imshow(resize_gray, cmap='gray') # 显示缩放后的灰度图像plt.show() # 显示所有子图# 对原图像进行傅立叶变换
dft = cv.dft(np.float32(gray), flags=cv.DFT_COMPLEX_OUTPUT) # 计算图像的离散傅里叶变换
dft_shift = np.fft.fftshift(dft) # 将零频率分量移动到频谱中心
mag, angle = cv.cartToPolar(dft_shift[:, :, 0], dft_shift[:, :, 1]) # 从复数形式转换为极坐标形式,获取幅度和相位
mag = 20 * np.log(mag) # 对幅度进行对数缩放,以便更好地可视化# 对缩放后的图像进行傅立叶变换
resize_dft = cv.dft(np.float32(resize_gray), flags=cv.DFT_COMPLEX_OUTPUT) # 计算缩放图像的傅里叶变换
resize_dft_shift = np.fft.fftshift(resize_dft) # 将零频率分量移动到频谱中心
resize_mag, angle = cv.cartToPolar(resize_dft_shift[:, :, 0], resize_dft_shift[:, :, 1]) # 从复数形式转换为极坐标形式
resize_mag = 20 * np.log(resize_mag) # 对幅度进行对数缩放# 显示原图和缩放后图像的傅立叶变换结果
plt.figure(figsize=(10, 5)) # 创建一个新的图形窗口
plt.subplot(1, 2, 1) # 创建1行2列的子图,选择第1个
plt.title("DFT") # 设置子图的标题
plt.imshow(mag, cmap='gray') # 显示原图的傅里叶变换结果plt.subplot(1, 2, 2) # 选择第2个子图
plt.title("Resize_DFT") # 设置子图的标题
plt.imshow(resize_mag, cmap='gray') # 显示缩放图像的傅里叶变换结果plt.show() # 显示所有子图
分析原图的傅里叶频谱和缩放后的傅里叶频谱的对应关系
当图像缩小时,频谱的幅度分布会有所变化,尤其是高频成分的能量可能会被削弱,导致模糊。在频域中,频谱的中心部分代表低频信息,而边缘部分代表高频信息。因此,缩放后,频谱的范围也会随之缩小。
(2)对一副图像进行旋转,显示原始图像和旋转后的图像,分别对其进行傅里 叶变换,显示变换后结果;
import matplotlib.pyplot as plt
import cv2 as cv
import numpy as np# 读取一幅图像(以灰度模式)
img_dir = r'D:\Document\Experiment\data\image1.jpg' # 图像路径
gray = cv.imread(img_dir, 0) # 读取图像,0表示以灰度图像模式读取# 对图像进行旋转
rows, cols = gray.shape[:2] # 获取原图像的行和列数
# 获取旋转矩阵,中心点为图像中心,旋转角度为45度,缩放因子为1
rot_matrix = cv.getRotationMatrix2D((cols / 2, rows / 2), 45, 1)
# 使用仿射变换对图像进行旋转
rotated_gray = cv.warpAffine(gray, rot_matrix, (cols, rows))# 显示原始图像和旋转后的图像
plt.figure(figsize=(10, 5)) # 创建一个10x5英寸的图形窗口
plt.subplot(1, 2, 1) # 创建一个1行2列的子图,并选择第1个
plt.title("gray") # 设置子图的标题
plt.imshow(gray, cmap='gray') # 显示原始灰度图像plt.subplot(1, 2, 2) # 选择第2个子图
plt.title("Rotated_gray") # 设置子图的标题
plt.imshow(rotated_gray, cmap='gray') # 显示旋转后的灰度图像plt.show() # 显示所有子图# 对原图像进行傅立叶变换
dft = cv.dft(np.float32(gray), flags=cv.DFT_COMPLEX_OUTPUT) # 计算图像的离散傅里叶变换
dft_shift = np.fft.fftshift(dft) # 将零频率分量移动到频谱中心
mag, angle = cv.cartToPolar(dft_shift[:, :, 0], dft_shift[:, :, 1]) # 从复数形式转换为极坐标形式,获取幅度和相位
mag = 20 * np.log(mag) # 对幅度进行对数缩放,以便更好地可视化# 对旋转后的图像进行傅立叶变换
rotated_dft = cv.dft(np.float32(rotated_gray), flags=cv.DFT_COMPLEX_OUTPUT) # 计算旋转图像的傅里叶变换
rotated_dft_shift = np.fft.fftshift(rotated_dft) # 将零频率分量移动到频谱中心
rotated_mag, angle = cv.cartToPolar(rotated_dft_shift[:, :, 0], rotated_dft_shift[:, :, 1]) # 从复数形式转换为极坐标形式
rotated_mag = 20 * np.log(rotated_mag) # 对幅度进行对数缩放# 显示原图和旋转后图像的傅立叶变换结果
plt.figure(figsize=(10, 5)) # 创建一个新的图形窗口
plt.subplot(1, 2, 1) # 创建1行2列的子图,选择第1个
plt.title("DFT") # 设置子图的标题
plt.imshow(mag, cmap='gray') # 显示原图的傅里叶变换结果plt.subplot(1, 2, 2) # 选择第2个子图
plt.title("Rotated_DFT") # 设置子图的标题
plt.imshow(rotated_mag, cmap='gray') # 显示旋转图像的傅里叶变换结果plt.show() # 显示所有子图
分析原图的傅里叶频谱和旋转后的傅里叶频谱的对应关系;
在旋转操作中,频谱的中心(表示低频成分)仍然保持在原来的位置,但高频成分的分布会发生变化。具体来说,旋转图像后的频谱在相位上可能会有明显的变化,反映出旋转方向和角度。
(3)读取图像进行傅里叶变换,之后使用Gauss高通滤波器进行滤波,最后逆傅里叶变换恢复图像
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt# 1. 读取一幅图像(以灰度模式)
img_dir = r'D:\Document\Experiment\data\image1.jpg' # 图像路径
gray = cv.imread(img_dir, 0) # 读取图像,0表示以灰度图像模式读取# 2. 进行傅里叶变换
# 使用 np.fft.fft2 进行二维傅里叶变换,并使用 np.fft.fftshift 将频率搬移到中心
dft = np.fft.fft2(gray)
dft_shift = np.fft.fftshift(dft) # 将低频部分移动到中心# 3. 构建高斯高通滤波器
rows, cols = gray.shape
crow, ccol = rows // 2 , cols // 2 # 中心位置# 创建一个与图像尺寸相同的掩膜,初始值为1
mask = np.ones((rows, cols), np.float32)# 高斯高通滤波器:创建一个高斯核,大小为 rows x cols,中心值为 0
sigma = 50 # 控制滤波器的大小
for i in range(rows):for j in range(cols):distance = np.sqrt((i - crow)**2 + (j - ccol)**2)mask[i, j] = 1 - np.exp(-(distance**2) / (2 * (sigma**2)))# 4. 对频域图像应用滤波器
filtered_dft_shift = dft_shift * mask# 5. 进行逆傅里叶变换以恢复图像
# 使用 np.fft.ifftshift 将频率搬移回去
f_ishift = np.fft.ifftshift(filtered_dft_shift)
# 逆傅里叶变换
img_back = np.fft.ifft2(f_ishift)
# 取绝对值,得到实际图像
img_back = np.abs(img_back)# 6. 显示图像
plt.figure(figsize=(12, 8))# 原始图像
plt.subplot(221), plt.imshow(gray, cmap='gray')
plt.title('Original Image'), plt.axis('off')# 傅里叶变换后的频谱图
magnitude_spectrum = 20 * np.log(np.abs(dft_shift))
plt.subplot(222), plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Fourier Transform (Magnitude Spectrum)'), plt.axis('off')# 经过高斯高通滤波后的频谱图
filtered_magnitude_spectrum = 20 * np.log(np.abs(filtered_dft_shift))
plt.subplot(223), plt.imshow(filtered_magnitude_spectrum, cmap='gray')
plt.title('Filtered Spectrum (Gaussian High-pass)'), plt.axis('off')# 恢复后的图像
plt.subplot(224), plt.imshow(img_back, cmap='gray')
plt.title('Recovered Image (After Inverse FFT)'), plt.axis('off')plt.tight_layout()
plt.show()