傅里叶变换
理论基础
时间域与频域相互转换来看信号
使用Numpy实现傅里叶变换
numpy.fft.fft2
- 实现傅里叶变换
- 返回一个复数数组(complex ndarray)
numpy.fft.fftshift
- 将零频率分量移到频谱中心
20*np.log(np.abs(fshift))
- 设置频谱的范围
操作小记
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", 0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
result = 20 * np.log(np.abs(fshift))
plt.subplot(121)
plt.imshow(img, cmap='gray')
plt.title('ori')
plt.axis('off')
plt.subplot(122)
plt.imshow(result, cmap='gray')
plt.title('res')
plt.axis('off')
plt.show()
效果
注意:
- 傅里叶得到低频、高频信息,针对低频、高频处理能够实现不同的目的
- 傅里叶过程是可逆的,图像进过傅里叶变换、逆傅里叶变换后,能够恢复到原始图像
- 在频域对图像进行处理,在频域的处理会反映在逆变换图像上
numpy实现逆傅里叶变换
numpy.fft.ifft2
- 实现逆傅里叶变换,返回一个复数数组(complex ndarray)
numpy.fft.ifftshift
fftshift
函数的逆函数
iimg = np.abs(逆傅里叶变换结果)
- 设置值的范围
操作小记
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", 0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('ori'), plt.axis('off')
plt.subplot(122), plt.imshow(iimg, cmap='gray')
plt.title('iimg'), plt.axis('off')
plt.show()
效果
高通滤波演示
低频、高频
- 低频对应图像内变化缓慢的灰度分量。例如,在一幅大草原的图像中,低频对应着广袤的颜色趋于一致的草原
- 高频对应图像内变化越来越快的灰度分量,是由灰度的尖锐过渡造成的。例如,在一幅大草原的图像中,其中狮子的边缘等信息
- 衰减高频而通过低频,低频滤波器,将模糊一幅图像
- 衰减低频而通过高频,高通滤波器,将增强尖锐的细节,但是会导致图像的对比度降低
滤波
- 接受(通过)或者拒绝一定频率的分量
- 通过低频的滤波器称为低通滤波器
- 通过高频的滤波器称为高通滤波器
频域滤波
- 修改傅里叶变换以达到特殊目的,然后计算IDFT返回到图像域
- 特殊目的:图像增强、图像去噪、边缘检测、特征提取、压缩、加密等
操作小记
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", 0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
rows,cols = img.shape
crow,ccol = int(rows/2), int(cols/2)
fshift[crow-30:crow+30, ccol-30:ccol+30] = 0
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('img'), plt.axis('off')
plt.subplot(122), plt.imshow(iimg, cmap='gray')
plt.title('iimg'), plt.axis('off')
plt.show()
效果
OpenCV实现傅里叶变换
返回结果=cv2.dft(原始图像, 转换标识)
- 返回结果
- 是双通道的
- 第1个通道是结果的实数部分
- 第2个通道是结果的虚数部分
- 原始图像
- 输入图像是首先转换成
np.float32
格式 np.float32(img)
- 输入图像是首先转换成
- 转换标识
flags=cv2.DFT_COMPLEX_OUTPUT
- 输出一个复数阵列
返回值=cv2.magnitude(参数1, 参数2)
:计算幅值
- 参数1:浮点型X坐标值,也就是实部
- 参数2:浮点型Y坐标值,也就是虚部
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", 0)
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)
res = 20 * np.log(cv2.magnitude(dftShift[:, :, 0], dftShift[:, :, 1]))
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('img'), plt.axis('off')
plt.subplot(122), plt.imshow(res, cmap='gray')
plt.title('res'), plt.axis('off')
plt.show()
效果
OpenCV实现逆傅里叶变换
返回结果=cv2.idft(原始数据)
- 返回结果:取决于原始数据的类型和大小
- 原始数据:实数或者复数均可
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", 0)
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)
ishift = np.fft.ifftshift(dftShift)
ilmg = cv2.idft(ishift)
ilmg = cv2.magnitude(ilmg[:, :, 0], ilmg[:, :, 1])
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('img'), plt.axis('off')
plt.subplot(122), plt.imshow(ilmg, cmap='gray')
plt.title('inverse'), plt.axis('off')
plt.show()
效果
低通滤波示例
操作小记
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", 0)
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)
rows, cols = img.shape
crow, ccol = int(rows/2), int(cols/2)
mask = np.zeros((rows, cols, 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1
fShift = dftShift*mask
ishift = np.fft.ifftshift(fShift)
ilmg = cv2.idft(ishift)
ilmg = cv2.magnitude(ilmg[:, :, 0], ilmg[:, :, 1])
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('img'), plt.axis('off')
plt.subplot(122), plt.imshow(ilmg, cmap='gray')
plt.title('res'), plt.axis('off')
plt.show()
效果