傅里叶变换
傅里叶变换(Fourier Transform):通过数学的方法反向分解复杂的信号,使之成为一个个简单的正弦信号。傅里叶变换不再以时域去看待事物,而是以频域去研究事物 分类:连续傅里叶变换和离散傅里叶变换 图像处理:2D离散傅里叶变换(DFT)
|
- 时域和频域(图片来源,如有侵权,联系删除)
- 时域和频域的详细介绍
1. numpy中的图像傅里叶变换
二维傅里叶频率转换:np.fft.fft2() 结果偏移:np.fft.fftshift() 二维傅里叶逆变换(将图像还原):np.fft.ifft2() |
- 傅里叶变换
- np.fft.fft2(a, s=None, axes=(-2, -1), norm=None)
- 傅里叶逆变换
- np.fft.ifft2(a, s=None, axes=(-2, -1), norm=None)
参数 | 含义 | 作用 |
---|---|---|
a | 数组 | 图像转换时(直接输入灰度图像) |
s | 整数序列 | 输出图片(数组)的形状 (s[0] x轴, s[1] y轴)的数值 |
axes | 计算FFT的轴 | 一个元素序列意味着执行一维FFT |
norm | 规范化模式(转换方向) | “backward”,“ortho” or “forward”(“向后”,“正交”,“向前”) |
- np.fft.fftshift(x, axes=None)
参数 | 含义 |
---|---|
x | 输入数组(图像处理时为经过傅里叶转换的频域幅度图数组) |
axes | 计算的轴(int或者shape元组) |
- 实验代码
# 使用numpy进行图像的傅里叶变换
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('../picture/14.jpg', 0)
print(img.shape)
# 进行傅里叶变换(返回值:复数数组)
ff = np.fft.fft2(img)
# 将低频部分移到图像中央,便于观察
fshift = np.fft.fftshift(ff)
# 转换为(0-255)的图像值
img_fft = 20*np.log(np.abs(fshift))
# 傅里叶逆变换(将图像还原)
iff = np.fft.ifft2(fshift)
img_ifft = np.abs(iff)
plt.figure(figsize=(15,8), dpi=100)
plt.subplot(131),plt.imshow(img, cmap = 'gray')
plt.title('img'), plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(img_fft, cmap = 'gray')
plt.title('Fourier'), plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(img_ifft, cmap = 'gray')
plt.title('i_Fourier'), plt.xticks([]), plt.yticks([])
plt.show()
- 运行结果
2. OpenCV傅里叶变换
在原图中进行(低频,高频)滤波不易操作,通过傅里叶变换映射到频谱中之后更易于对图像的操作(提高速度和效率) 傅里叶变换的作用:图像的傅里叶降噪、JPEG图像压缩技术、模式识别等 高频:变化剧烈的灰度分量(边界轮廓线) 低频:变化缓慢的灰度分量(不易区分且较为相近的区域) |
- cv2.dft(src[, dst[, flags[, nonzeroRows]]])
- cv2.idft(src[, dst[, flags[, nonzeroRows]]])
参数 | 含义 |
---|---|
src | 输入图片(数组) |
dst | 输出结果(可选) |
flags | 转换标志 |
- flags
-
- DFT_COMPLEX_OUTPUT:得到一个复数形式的矩阵;
-
- DFT_REAL_OUTPUT:只输出复数的实部;
-
- DFT_INVERSE:进行傅里叶逆变换;
-
- DFT_SCALE:是否除以 MxN (M 行 N 列的图片,共有有 MxN 个像素点);
-
- DFT_ROWS:输入矩阵的每一行进行傅里叶变换或者逆变换。
- cv2.magnitude(x, y[, magnitude])
傅里叶变换的双通道结果转换为 0 到 255 的范围
参数 | 含义 |
---|---|
x | 浮点型 X 坐标值,实部 |
y | 浮点型 Y 坐标值,虚部 |
- 实验代码
# OpenCV中的图像傅里叶变换
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('../picture/14.jpg',0)
print("图像数据类型:", img.dtype)
# 需要现将图片转换为float32
img_float32 = np.float32(img)
print("转换后数据类型:", img_float32.dtype)
# 进行傅里叶变换
dft = cv.dft(img_float32, flags = cv.DFT_COMPLEX_OUTPUT)
# 将低频部分移到中央
dft_shift = np.fft.fftshift(dft)
# 转换为图像数据类型(0-255)
img_log = 20*np.log(cv.magnitude(dft_shift[:, :, 0],dft_shift[:, :, 1]))
rows, cols = img.shape
# 中心位置
rows_half, cols_half = int(rows/2), int(cols/2)
"""
低通滤波处理
"""
# 低频掩膜生成(低通滤波)
mask_bom = np.zeros((rows, cols ,2), dtype= np.uint8)
mask_bom[rows_half - 30:rows_half + 30,cols_half - 30:cols_half + 30] = 1
# 进行滤波处理
fshift_bom = dft_shift * mask_bom
# 傅里叶逆变换
iimg = cv.idft(np.fft.ifftshift(fshift_bom))
iimg = cv.magnitude(iimg[:, :, 0], iimg[:, :, 1])
"""
高通滤波处理
"""
# 高通掩膜生产
mask_top = np.ones((rows, cols, 2), np.uint8)
mask_top[rows_half - 30:rows_half + 30, cols_half - 30:cols_half + 30] = 0
fshift_top = dft_shift * mask_top
img_back = cv.idft(np.fft.ifftshift(fshift_top))
img_back = cv.magnitude(img_back[:, :, 0],img_back[:, :, 1])
plt.figure(figsize = ( 10, 8), dpi = 100)
plt.subplot(221), plt.imshow(img, cmap= 'gray')
plt.title('Image'), plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(img_log, cmap= 'gray')
plt.title('Magnitude'), plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(iimg, cmap= 'gray')
plt.title('Magni'), plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(img_back, cmap= 'gray')
plt.title('Back'), plt.xticks([]), plt.yticks([])
plt.show()
- 运行结果