傅里叶变换
原文地址:http://www.woshicver.com/FifthSection/4_11_%E5%82%85%E9%87%8C%E5%8F%B6%E5%8F%98%E6%8D%A2/
傅里叶变换用于分析各种滤波器的频率特性,对于图像使用2D离散傅里叶变换查找频域;
对于正弦信号,如果幅度在短时间内变化如此之快,则可以说它是高频信号。如果变化缓慢,则为低频信号。
可以用于检测边缘点或者噪声点。
使用numpy中的FFT函数实现傅里叶变换;
opencv中会使用cv.dft() 和cv.idft()等。
numpy中的傅里叶变换
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('C:\\Users\\Yan.Dong5\\Desktop\\empire.jpeg',0)
#傅里叶变换
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
magnitude_spectrum = 20*np.log(np.abs(fshift))
#高通滤波和重建图像,即找到逆DFT,高通滤波是边缘检测操作。
rows,cols = img.shape
crow,ccol = rows//2,cols//2
f_shift = np.fft.ifftshift(fshift)
img_back = np.fft.ifft2(f_shift)
img_back = np.real(img_back)
#绘制图像
plt.subplot(121)
plt.imshow(img,cmap='gray')
plt.title('Input Image')
plt.xticks([])
plt.yticks([])
plt.subplot(122)
plt.imshow(magnitude_spectrum,cmap='gray')
plt.title('magnitude spectrum')
plt.xticks([])
plt.yticks([])
plt.show()
plt.subplot(131),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(img_back, cmap = 'gray')
plt.title('Image after HPF'), plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(img_back)
plt.title('Result in JET'), plt.xticks([]), plt.yticks([])
plt.show()
opencv中的傅里叶变换
OpenCV为此提供了cv.dft()和cv.idft()函数。它返回与前一个相同的结果,但是有两个通道。第一个通道是结果的实部,第二个通道是结果的虚部。输入图像首先应转换为np.float32。
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('C:\\Users\\Yan.Dong5\\Desktop\\empire.jpeg',0)
#傅里叶变换
dft = cv.dft(np.float32(img),flags=cv.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
magnitude_spectrum = 20*np.log(cv.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))
#做DFT的逆变换
#删除图像中的高频内容,将LPF应用到图像中,实际上是模糊了图像
rows,cols = img.shape
#选择最优的大小提升DFT的性能
crow,ccol = cv.getOptimalDFTSize(rows),cv.getOptimalDFTSize(cols)
#创建掩码
mask = np.zeros((rows,cols,2),np.uint8)
mask[crow-30:crow+30,ccol-30:ccol+30]=1
#应用掩码和逆DFT
fshift = dft_shift*mask
f_ishift = np.fft.ifftshift(fshift)
img_back = cv.idft(f_ishift)
img_back = cv.magnitude(img_back[:,:,0],img_back[:,:,1])
#绘制图像
plt.subplot(121)
plt.imshow(img,cmap='gray')
plt.title('Input Image')
plt.xticks([])
plt.yticks([])
plt.subplot(122)
plt.imshow(magnitude_spectrum,cmap='gray')
plt.title('magnitude spectrum')
plt.xticks([])
plt.yticks([])
plt.show()
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img_back, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()
拉普拉斯算子是高通滤波器
每个内核都是HPF或LPF
#拉普拉斯算子是高通滤波器
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
#没有缩放参数的简单均值滤波器
mean_filter = np.ones((3,3))
#创建高斯滤波器
x = cv.getGaussianKernel(5,10)
gaussian = x*x.T
#不同的边缘检测滤波器
#x方向上的scharr
scharr = np.array([[-3,0,3],[-10,0,10],[-3,0,3]])
#x方向上的sobel
sobel_x = np.array([[-1,0,1],[-2,0,2],[-1,0,1]])
#y方向上的sobel
sobel_y = np.array([[-1,-2,-1],[0,0,0],[1,2,1]])
#laplacian变换
laplacian = np.array([[0,1,0],[1,-4,1],[0,1,0]])
filters = [mean_filter,gaussian,laplacian,sobel_x,sobel_y,scharr]
filter_name = ['mean_filter','gaussian','laplacian','sobel_x','sobel_y','scharr_x']
fft_filters = [np.fft.fft2(x) for x in filters]
fft_shift = [np.fft.fftshift(y) for y in fft_filters]
mag_spectrum = [np.log(np.abs(z)+1) for z in fft_shift]
for i in range(6):
plt.subplot(2,3,i+1),plt.imshow(mag_spectrum[i],cmap = 'gray')
plt.title(filter_name[i]), plt.xticks([]), plt.yticks([])
plt.show()