傅里叶变换
![](https://i-blog.csdnimg.cn/blog_migrate/b171c505264b3c8d2a4d4bd8320622f1.png)
详细介绍可参考(6 条消息) 傅里叶变换 - 搜索结果 - 知乎 (zhihu.com)
作用:将时域问题转化为频率问题,更好处理
滤波
步骤:
图片转化为频率域(借助cv2.dft(img, flags))
转化后的频率域中,频率为0的部分一般在左上角,将低频率区域放到中心区域,方便后期的利用掩码来滤波。(np.fft.fftshift(x, axis))
构造mask掩码作为滤波器使用
滤波
频率域转换回图片,低频率从中心转换回到左上角(cv2.idft(img),np.fft.ifftshift()、cv2.magnitude)
频域变换
![](https://i-blog.csdnimg.cn/blog_migrate/423a4d56b7abfb98358809067f5aacd7.png)
import cv2
import matplotlib.pyplot as plt
import numpy as np
def cv_show(name,image):
cv2.imshow(name,image)
cv2.waitKey()
cv2.destroyAllWindows()
img=cv2.imread('D:/BaiduNetdiskDownload/opencv/lena.png',0)
img_float32 = np.float32(img)
#DFT
dft=cv2.dft(img_float32,flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift=np.fft.fftshift(dft)
magnitude_spectrum_1=20*np.log(cv2.magnitude(dft[:,:,0],dft[:,:,1]))
magnitude_spectrum_2=20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))
plt.subplot(121),plt.imshow(magnitude_spectrum_1,cmap='gray'),plt.title("1")
plt.subplot(122),plt.imshow(magnitude_spectrum_2,cmap='gray'),plt.title("2")
plt.show()
![](https://i-blog.csdnimg.cn/blog_migrate/e8fcdbaa9b730d0027da7ea1bd326d3c.png)
API
参考原文链接:https://blog.csdn.net/dgvv4/article/details/121655105
cv2.dft(img, flags)
傅里叶变化函数
img:代表输入图像,opencv中输入图像必须转换成np.float32类型
flags:转换标识,通常为cv2.DFT_COMPLEX_OUTPUT,其他值如下:
![](https://i-blog.csdnimg.cn/blog_migrate/bbe12df6d2ae4ce08e639742b41a104d.png)
np.fft.fftshift(x, axis)
x: 数组,代表输入的频谱图数据
axis: 可选,指定需要移动的轴。默认移动所有的轴返回位移之后的数组。
使用傅里叶变换后,在得到的频谱图中,频率为0的部分会在左上角,为了计算方便,我们通常将频率为0的部分转换到频谱图中心位置
cv2.magnitude(x, y)
x:数组类型,表示浮点型的x轴坐标,也就是实部
y:数组类型,表示浮点型的y轴坐标,也就是虚部
返回值为:x和y的平方和开根,
由于cv2.dft()返回的结果是双通道的(实部和虚部),通常需要转换成图像格式[0,255],才能正常显示频谱图。公式为:
20*np.log(cv2.magnitude(x, y))
cv2.idft(img)
傅里叶逆变换
img:代表输入处理后的频谱图像
在使用cv2.dft()获得频谱图时,将低频点从边缘移动到图像中间,现在要逆变换,得把低频点还原到原始位置,使用函数: np.fft.ifftshift(处理后的频谱图) ,之后才能将频谱图转变回空间图像。
注意,逆变换后的结果是包含实部和虚部的,仍需要使用cv2.magnitude函数进行处理
低通滤波示例
import cv2
import matplotlib.pyplot as plt
import numpy as np
def cv_show(name,image):
cv2.imshow(name,image)
cv2.waitKey()
cv2.destroyAllWindows()
img=cv2.imread('D:/BaiduNetdiskDownload/opencv/lena.png',0)
img_float32 = np.float32(img)
#低通滤波
w,h=img.shape
w_center,h_center=int(w/2),int(h/2)#中心位置
mask=np.zeros((w,h,2),np.uint8)
mask[w_center-30:w_center+30,h_center-20:h_center+20]=1
#DFT
dft=cv2.dft(img_float32,flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift=np.fft.fftshift(dft)
#IDFT
fshift=dft_shift*mask
f_ishift=np.fft.ifftshift(fshift)
img_back =cv2.idft(f_ishift)
img_back=cv2.magnitude(img_back[:,:,0],img_back[:,:,1])#将复数变回来
plt.subplot(121),plt.imshow(img,cmap='gray'),plt.title('Input image')
plt.subplot(122),plt.imshow(img_back,cmap='gray'),plt.title('Result')
plt.show()
![](https://i-blog.csdnimg.cn/blog_migrate/d27b556d2935eb62e00a08498d4886f9.png)
高通滤波示例
import cv2
import matplotlib.pyplot as plt
import numpy as np
def cv_show(name,image):
cv2.imshow(name,image)
cv2.waitKey()
cv2.destroyAllWindows()
img=cv2.imread('D:/BaiduNetdiskDownload/opencv/lena.png',0)
img_float32 = np.float32(img)
#高通滤波
w,h=img.shape
w_center,h_center=int(w/2),int(h/2)#中心位置
mask=np.ones((w,h,2),np.uint8)
mask[w_center-30:w_center+30,h_center-20:h_center+20]=0
#DFT
dft=cv2.dft(img_float32,flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift=np.fft.fftshift(dft)
#IDFT
fshift=dft_shift*mask
f_ishift=np.fft.ifftshift(fshift)
img_back =cv2.idft(f_ishift)
img_back=cv2.magnitude(img_back[:,:,0],img_back[:,:,1])#将复数变回来
plt.subplot(121),plt.imshow(img,cmap='gray'),plt.title('Input image')
plt.subplot(122),plt.imshow(img_back,cmap='gray'),plt.title('Result')
plt.show()
![](https://i-blog.csdnimg.cn/blog_migrate/3f74194584336e0adeef39dfb5a33cf7.png)