Python - opencv (六) 傅里叶变换
一. 傅里叶变换
概念
https://zhuanlan.zhihu.com/p/19763358
作用
高频:变化剧烈的灰度分量,如边界
低频:变化缓慢的灰度分量,如大海
高通滤波器:只保留高频,边界增强
低通滤波器:只保留低频,图片模糊
二. opencv的实现
傅里叶变换:
cv2.dft(), cv2.idft(), 需要先将图片转换为np.float32格式
得到的结果频率为0的部分会在左上角,通常要转换到中心位置,通过shift实现
cv2.dft()的结果是双通道的,需要转换为图像格式
1 import numpy as np 2 3 import cv2 4 import matplotlib.pyplot as plt 5 6 7 def add_to_plot(position, image, name): 8 plt.subplot(position) 9 plt.imshow(image, cmap='gray') 10 plt.title(name) 11 plt.xticks([]) 12 plt.yticks([]) 13 14 15 if __name__ == '__main__': 16 img = cv2.imread('../pics/6.jpg', 0) 17 img_float32 = np.float32(img) 18 dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT) 19 dft_shift = np.fft.fftshift(dft) 20 21 magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:,:,0], dft_shift[:,:,1])) 22 add_to_plot(121, img, 'Input') 23 add_to_plot(122, magnitude_spectrum, 'Magnitude') 24 plt.show()
低通滤波:
1 import numpy as np 2 3 import cv2 4 import matplotlib.pyplot as plt 5 6 7 def add_to_plot(position, image, name): 8 plt.subplot(position) 9 plt.imshow(image, cmap='gray') 10 plt.title(name) 11 plt.xticks([]) 12 plt.yticks([]) 13 14 15 if __name__ == '__main__': 16 img = cv2.imread('../pics/6.jpg', 0) 17 img_float32 = np.float32(img) 18 dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT) 19 dft_shift = np.fft.fftshift(dft) 20 21 rows, cols = img.shape 22 crow, ccol = int(rows/2), int(cols/2) 23 24 # 低通 25 mask = np.zeros((rows, cols, 2), np.uint8) 26 mask[crow-30: crow+30, ccol-30: ccol+30] = 1 27 28 # IDFT 29 f_shift = dft_shift * mask 30 f_ishift = np.fft.fftshift(f_shift) 31 img_back = cv2.idft(f_ishift) 32 img_back = cv2.magnitude(img_back[:,:,0], img_back[:,:,1]) 33 34 add_to_plot(121, img, 'Input') 35 add_to_plot(122, img_back, 'Magnitude') 36 plt.show()
效果:
高通滤波:
1 import numpy as np 2 3 import cv2 4 import matplotlib.pyplot as plt 5 6 7 def add_to_plot(position, image, name): 8 plt.subplot(position) 9 plt.imshow(image, cmap='gray') 10 plt.title(name) 11 plt.xticks([]) 12 plt.yticks([]) 13 14 15 if __name__ == '__main__': 16 img = cv2.imread('../pics/6.jpg', 0) 17 img_float32 = np.float32(img) 18 dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT) 19 dft_shift = np.fft.fftshift(dft) 20 21 rows, cols = img.shape 22 crow, ccol = int(rows/2), int(cols/2) 23 24 # 高通 25 mask = np.ones((rows, cols, 2), np.uint8) 26 mask[crow-30: crow+30, ccol-30: ccol+30] = 0 27 28 # IDFT 29 f_shift = dft_shift * mask 30 f_ishift = np.fft.fftshift(f_shift) 31 img_back = cv2.idft(f_ishift) 32 img_back = cv2.magnitude(img_back[:,:,0], img_back[:,:,1]) 33 34 add_to_plot(121, img, 'Input') 35 add_to_plot(122, img_back, 'Magnitude') 36 plt.show()
效果:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析