《数字图像处理-OpenCV/Python》连载:空间滤波之高斯滤波器
本书京东 优惠购书链接 https://item.jd.com/14098452.html
本书CSDN 独家连载专栏 https://blog.csdn.net/youcans/category_12418787.html
第 11 章 傅里叶变换与频域滤波
空间图像滤波是图像与滤波器核的卷积,而空间卷积的傅里叶变换是频域中相应变换的乘积。因此,频域图像滤波是通过频域滤波器(传递函数)与图像的傅里叶变换相乘得到的。频域中的滤波概念更加直观,滤波器设计也更容易。
本章内容概要
- 学习二维离散傅里叶变换的实现方法,介绍快速傅里叶变换的原理。
- 学习频域滤波的基本步骤,以及构造滤波器传递函数的基本方法。
- 学习常用的频域滤波器,如理想滤波器、高斯滤波器、巴特沃斯滤波器。
- 介绍低通、高通、带通、带阻滤波器的关系,构造选择性滤波器。
- 认识和比较空间滤波与频域滤波。
11.3 频域滤波的基本步骤
傅里叶变换的目的是将图像从空间域转换到频域,在频域内进行图像处理。
空间取样和频率间隔是相互对应的,频域中的样本间隔与空间样本间隔及样本数量的乘积成反比。空间滤波器和频域滤波器也是相互对应的,二者能形成如下的傅里叶变换对。
因此,计算两个函数的空间卷积,可以直接在空间域计算,也可以在频域计算。先计算每个函数的傅里叶变换,再将两个变换相乘,最后进行傅里叶逆变换转换回空间域。
频域图像滤波首先要对原始图像 f(x,y)做傅里叶变换 F(u,v) ;然后用滤波器传递函数 H(u,v) 对傅里叶变换的频谱进行处理,做傅里叶逆变换返回空间域,得到滤波图像 g(x,y)。具体变换过程如下。
(1) 对原始图像 f(x,y) 进行傅里叶变换和中心化,得到 F(u,v) 。
(2) 将图像的傅里叶变换 F(u,v) 与滤波器传递函数 H(u,v) 相乘,得到滤波频谱 G(u,v) 。
(3) 对 G(u,v) 进行逆中心化和傅里叶逆变换,得到滤波图像 g(x,y)。
使用尺寸最优扩充的快速傅里叶变换时,还包括变换前的图像扩充和变换后的图像裁剪。
【例程1104】频域图像滤波的基本步骤
本例程以理想低通滤波器为例,示范频域图像滤波的基本步骤。
设计低通滤波器的过程,是构造二维掩模图像的过程。简单地,构造一个中心开窗的遮罩图像,在黑色图像的中心区域设有白色窗口,就构成了一个低通滤波器。
# 【1104】频域图像滤波的基本步骤
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
def ideaLPF(height, width, radius=10): # 理想低通滤波器
u, v = np.mgrid[-1:1:2.0/height, -1:1:2.0/width]
Dist = cv.magnitude(u, v)
D0 = radius/height # 滤波器半径
kernel = np.zeros((height, width), np.uint8)
kernel[Dist <= D0] = 1
return kernel
if __name__ == '__main__':
# img = cv.imread("../images/Fig0515a.tif", flags=0) # 读取为灰度图像
img = cv.imread("../images/Fig1101.png", flags=0) # 读取灰度图像
height, width = img.shape[:2] # (688,688)
# (1) 对图像进行傅里叶变换,并将低频分量移动到中心
imgFloat = img.astype(np.float32) # 将图像转换成 float32
dft = cv.dft(imgFloat, flags=cv.DFT_COMPLEX_OUTPUT) # (512,512,2)
dftShift = np.fft.fftshift(dft) # (512,512,2)
r = [30, 60, 90] # 低通滤波器的半径
plt.figure(figsize=(9, 6))
for i in range(3):
# (2) 构造低通滤波器
mask = ideaLPF(height, width, r[i]) # 理想低通滤波器
maskDual = cv.merge([mask, mask]) # 拼接为两个通道:(h,w,2)
# maskAmp = cv.magnitude(mask, mask) # 幅度谱
# (3) 修改傅里叶变换实现频域图像滤波
dftMask = dftShift * maskDual # 两个通道分别为实部和虚部
# (4) 逆中心化后进行傅里叶逆变换
iShift = np.fft.ifftshift(dftMask) # 将低频逆转换回图像四角
iDft = cv.idft(iShift) # 傅里叶逆变换
iDftMag = cv.magnitude(iDft[:,:,0], iDft[:,:,1]) # 重建图像
imgLPF = np.uint8(cv.normalize(iDftMag, None, 0, 255, cv.NORM_MINMAX))
plt.subplot(2,3,i+1), plt.title("Mask (r={})".format(r[i]))
plt.axis('off'), plt.imshow(mask, cmap='gray')
plt.subplot(2,3,i+4), plt.title("LPF image (r={})".format(r[i]))
plt.axis('off'), plt.imshow(imgLPF, cmap='gray')
print(img.shape, dft.shape, maskDual.shape)
plt.tight_layout()
plt.show()
运行结果:
程序说明:
(1) OpenCV中的傅里叶变换结果保存为实部和虚部两个通道,dft的形状为(h,w,2)。因此要把单通道滤波器mask拼接为两个通道的maskDual,才能将dft与maskDual相乘。
(2) 傅里叶变换和傅里叶逆变换的结果都包括实部和虚部,使用函数cv.magnitude转换为幅度谱才能得到显示图像。
(3) 函数cv.dft的可选参数较多,在设置转换类型标志时不能省略关键字flags。
(4) 运行结果,频域滤波之理想低通滤波器如图11-2所示。从图中可以发现,低通滤波器的截止频率越小,保留的低频信息越少,滤除的高频信息越多,图像越模糊。这与空间域低通滤波的结果是一致的。
(5) 注意,滤波器传递函数与图像傅里叶变换进行乘法运算时,不能使用函数cv.multiply,因其是饱和运算。
图11-2 频域滤波之理想低通滤波器
版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/135705738)
Copyright 2024 youcans, XUPT
Crated:2024-01-20
《数字图像处理-OpenCV/Python》 独家连载专栏 : https://blog.csdn.net/youcans/category_12418787.html