OpenCV-Python学习(十):图像滤波之傅里叶变换

滤波分析又分为 时域分析、频域分析:

  • 时域分析: 直接对信号本身进行分析。
  • 频域分析: 对信号的变化快慢进行分析。

傅里叶变换可把信号从时间域转换到频率域,进而研究信号的频谱结构和变化规律。

图像滤波中空间域相当于信号中的时间域,使用傅里叶变换和逆傅里叶变换可实现空域与频域的相互转换。傅里叶变换的物理意义是将图像的灰度分布函数变换为图像的频率分布函数。图像的频率是表征图像中灰度变化剧烈程度的指标,是灰度在平面空间上的梯度。对于边界点或噪声,其灰度值变化剧烈,是图像中的高频分量


Numpy和OpenCV的傅里叶变换

图像的傅里叶变换流程:

  • 0.先将图片转化为灰度图

  • 1.将空域转化为频域-->傅里叶变换
      Numpy: FFT(Fast Fourier Transform) 快速傅里叶变换
        numpy.fft.fft2()
      OpenCV: DFT(Discrete Fourier Transform) 离散傅里叶变换
        dft(src, dst=None, flags=None, nonzeroRows=None)

        示例: dft = cv2.dft(numpy.float32(gray), flags=cv2.DFT_COMPLEX_OUTPUT)
        src: 转为numpy.float32类型
        flags: 转换的标识符,默认flags=0,表示正向变换。其他标识符如下:
          DFT_INVERSE = 1
          DFT_SCALE = 2
          DFT_ROWS = 4
          DFT_COMPLEX_OUTPUT = 16
          DFT_REAL_OUTPUT = 32
          DFT_COMPLEX_INPUT = 64

  • 2.中心化:将四周低频移动到图像中心
      numpy.fft.fftshift

  • 3.进行滤波操作(包括高频、低频等)

  • 4.去中心化:将低频和高频的位置还原
      numpy.fft.ifftshift()

  • 5.将频域转化为空域-->逆傅里叶变换
      Numpy: numpy.fft.ifft2()
      OpenCV: cv2.idft()

  • 6.二维向量取模(幅值): x + yj ==> \sqrt{x^2 + y^2}
      Numpy: numpy.abs(x + yj)
      OpenCV: cv2.magnitude(x, y)

1.Numpy中的FFT(快速傅里叶变换)
# 1.Numpy中的 FFT(Fast Fourier Transform) 快速傅里叶变换
import numpy
import cv2
import matplotlib.pyplot as plt

img = cv2.imread("image/9.jpg")
# 0.转化为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
rows, cols = gray.shape

# 1.FFT快速傅里叶变换: 空域-->频域
fft = numpy.fft.fft2(gray)  # 参数为灰度图
# 2.中心化: 将低频移动到图像中心
fftshift = numpy.fft.fftshift(fft)

# 获取振幅谱(展示图片用): 20 * numpy.log()是为了将值限制在[0, 255]
magnitude_spectrum = 20 * numpy.log(numpy.abs(fftshift))

# 3.滤波操作之高通滤波(去低频,保高频)
fftshift[rows // 2 - 30:rows // 2 + 30, cols // 2 - 30: cols // 2 + 30] = 0

# 4.去中心化: 将低频和高频的位置还原
ifftshift = numpy.fft.ifftshift(fftshift)
# 5.逆傅里叶变换: 频域-->空域
ifft = numpy.fft.ifft2(ifftshift)
# 6.二维向量取模(幅值)
img_back = numpy.abs(ifft)

# 结合matplotlib展示多张图片
plt.figure(figsize=(10, 10))
plt.subplot(221), plt.imshow(gray, cmap="gray"), plt.title("Input Gray Image")
plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(magnitude_spectrum, cmap="gray"), plt.title("Magnitude Spectrum")
plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(img_back, cmap="gray"), plt.title("Image after HPF")
plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(img_back), plt.title("Result in JET")  # 默认cmap='jet'
plt.xticks([]), plt.yticks([])
plt.show()
2.OpenCV中的DFT(离散傅里叶变换)
# 2.OpenCV中的 DFT(Discrete Fourier Transform) 离散傅里叶变换
import numpy
import cv2
import matplotlib.pyplot as plt

img = cv2.imread("image/9.jpg")
# 0.转化为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
rows, cols = gray.shape

# 1.DFT离散傅里叶变换: 空域-->频域
dft = cv2.dft(src=numpy.float32(gray), flags=cv2.DFT_COMPLEX_OUTPUT)  # src为灰度图,并且是numpy.float32类型
print(dft.shape)
# 2.中心化: 将低频移动到图像中心
fftshift = numpy.fft.fftshift(dft)

# 获取振幅谱(展示图片用): 20 * numpy.log()是为了将值限制在[0, 255]
magnitude_spectrum = 20 * numpy.log(cv2.magnitude(fftshift[:, :, 0], fftshift[:, :, 1]))

# 3.滤波操作之低通滤波(去高频,保低频)
mask = numpy.zeros((rows, cols, 2), dtype=numpy.uint8)
mask[rows // 2 - 30: rows // 2 + 30, cols // 2 - 30: cols // 2 + 30] = 1
fftshift = fftshift * mask

# 4.去中心化: 将低频和高频的位置还原
ifftshift = numpy.fft.ifftshift(fftshift)
# 5.逆傅里叶变换: 频域-->空域
idft = cv2.idft(ifftshift)
# 6.二维向量取模(幅值)
img_back = cv2.magnitude(idft[:, :, 0], idft[:, :, 1])

# 结合matplotlib展示多张图片
plt.figure(figsize=(10, 10))
plt.subplot(221), plt.imshow(gray, cmap="gray"), plt.title("Input Gray Image")
plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(magnitude_spectrum, cmap="gray"), plt.title("Magnitude Spectrum")
plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(img_back, cmap="gray"), plt.title("Image after LPF")
plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(img_back), plt.title("Result in JET")  # 默认cmap='jet'
plt.xticks([]), plt.yticks([])
plt.show()
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。