Python实现FFT及IFFT

运行环境及编译工具

  • Windows
  • VS Code

编程语言及库版本

版本
Python3.7.0
copy
numpy1.19.2
opencv3.4.2
PIL8.1.0
matplotlib3.4.3

可执行文件

  • HW_2.py
  • HW_2.ipynb
  • 在HW_2.ipynb中执行,详细程序信息在HW_2.py中

问题 1 通过计算一维傅里叶变换实现图像二维快速傅里叶变换(10 分)

实现一个函数 F=dft2D(f), 其中 f 是一个灰度源图像,F 是其对应的二维快速傅里叶变换 (FFT)图像. 具体实现要求按照课上的介绍通过两轮一维傅里叶变换实现。也就是首先计算 源图像每一行的一维傅里叶变换,然后对于得到的结果计算其每一列的一维傅里叶变换。 如果实现采用 MATLAB, 可以直接调用函数 fft 计算一维傅里叶变换。如果采用其他语言, 请选择并直接调用相应的一维傅里叶变换函数。

基本思路

FFT与IFFT算法主要是利用了函数“值表示”的思想和傅里叶正交的性质,依靠递归的方法可以大大缩减程序量。一维变换的编程基本思路如下图所示,对二维图像来说,先进行每行的变换,再在行变换的基础上进行列变换。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9P2jH7X7-1642676557251)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211026225526745.png)]

如何运行

问题一包含两个函数,均在HW_2.py文件中,在HW_2.ipynb中调试执行

from HW_2 import *
# 递归实现一维fft算法
oned_fft(arr):
# 对图像的fft
dft2D(f):

问题2 图像二维快速傅里叶逆变换 (10 分)

实现一个函数 f=idft2D(F), 其中 F 是一个灰度图像的傅里叶变换,f 是其对应的二维快速傅 里叶逆变换 (IFFT)图像,也就是灰度源图像. 具体实现要求按照课上的介绍通过类似正向变 换的方式实现。

基本思路

基本思路与上相同,需要注意的是最后得到的结果需除去图像尺寸 M × N M\times N M×N

如何运行
from HW_2 import *
# 递归实现一维fft算法
oned_ifft(arr):
# 对图像的fft
idft2D(f):

问题3 测试图像二维快速傅里叶变换与逆变换 (8 分)

对于给定的输入图像 rose512.tif, 首先将其灰度范围通过归一化调整到[0,1]. 将此归一化的 图像记为 f. 首先调用问题 1 下实现的函数 dft2D 计算其傅里叶变换,记为 F。然后调用问题 2 下的函数 idft2D 计算 F 的傅里叶逆变换,记为 g. 计算并显示误差图像 d = f-g.

基本思路

基本思路为:读图f - 归一化f - FFT变换F - IFFT变换g - 误差图像d

如何运行
from HW_2 import *
Q_3()
运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qhtUx82f-1642676510871)(F:\研究生课程\图像处理\作业\第二次作业\作业02_梁奥\Q_4.png)]

问题4 计算图像的中心化二维快速傅里叶变换与谱图像 (12 分)

我们的目标是复现下图中的结果。首先合成矩形物体图像,建议图像尺寸为 512×512,矩形位于图像中心,建议尺寸为 60 像素长,10 像素宽,灰度假设已归一化设为 1. 对于输入图像 f 计算其中心化二维傅里叶变换 F。然后计算对应的谱图像 S=log(1+abs(F)). 显示该谱图像。

基本思路
  • 创建空白图像f,像素值均为0
  • 将空白图像中心 10 × 60 10\times 60 10×60区域的像素值置为1
  • 中心化f,得到f_shift: f _ s h i f t ( x , y ) = ( − 1 ) x + y f ( x , y ) f\_shift(x,y)=(-1)^{x+y}f(x,y) f_shift(x,y)=(1)x+yf(x,y)
  • 分别对f,和f_shift进行fft变换得到F,和F_shift
  • 对F_shift计算谱图像
如何运行
from HW_2 import *
Q_4()
运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qhtUx82f-1642676510871)(F:\研究生课程\图像处理\作业\第二次作业\作业02_梁奥\Q_4.png)]

选做题 测试更多图像的二维快速傅里叶变换 (10 分)

计算其他 5 幅图像的二维快速傅里叶变换: house.tif, house02.tif, lena_gray_512.tif, lunar_surface.tif, characters_test_pattern.tif。注意,有些图像的尺寸不是 2 的整数次幂,需要 进行相应的像素填补处理。如果图像有多个通道可以选择其中的一个通道进行计算。

基本思路
  • 判断图像尺寸是否为二次幂,并返回最近的二次幂值
  • 以上述返回的二次幂值为尺寸创建zero图像,并原图大小的范围内用原图像素填充
  • 对每张图像进行Q3的操作
如何运行
from HW_2 import *
Q_5("./house.tif")
Q_5("./house02.tif")
Q_5("./lena_gray_512.tif")
Q_5("./lunar_surface.tif")
Q_5("./characters_test_pattern.tif")
运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-raLAVlsb-1642676510878)(F:\研究生课程\图像处理\作业\第二次作业\作业02_梁奥\Q_5_house.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T6U5OuBT-1642676510879)(F:\研究生课程\图像处理\作业\第二次作业\作业02_梁奥\Q_5_house02.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pl4mGZCM-1642676510881)(F:\研究生课程\图像处理\作业\第二次作业\作业02_梁奥\Q_5_lena_gray_512.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6T7tGhFu-1642676510882)(F:\研究生课程\图像处理\作业\第二次作业\作业02_梁奥\Q_5_lunar_surface.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9PaTMuLB-1642676510885)(F:\研究生课程\图像处理\作业\第二次作业\作业02_梁奥\Q_5_characters_test_pattern.png)]6510879)]

  • 16
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
要使用FFT(快速傅立叶变换)来实现IFFT(快速傅立叶逆变换),可以使用以下步骤: 1. 将输入序列进行零填充,以确保序列长度为2的幂。可以使用零填充函数将输入序列扩展到适当的长度。 2. 使用FFT算法对填充后的序列进行傅立叶变换。可以使用现有的FFT库或实现FFT算法来执行此步骤。 3. 对变换后的频域序列进行IFFT操作。IFFT操作与FFT操作非常相似,只是需要将正负号反转以进行逆变换。可以使用相同的FFT库或实现IFFT算法来执行此步骤。 4. 截取IFFT结果的前原始序列长度部分,以去除填充的零值。 下面是一个使用Python和NumPy库进行FFT和IFFT的示例代码: ```python import numpy as np def ifft(x): N = len(x) if N <= 1: return x even = ifft(x[0::2]) odd = ifft(x[1::2]) T = [np.exp(-2j * np.pi * k / N) * odd[k] for k in range(N//2)] return [even[k] + T[k] for k in range(N//2)] + [even[k] - T[k] for k in range(N//2)] def fft(x): N = len(x) if N <= 1: return x even = fft(x[0::2]) odd = fft(x[1::2]) T = [np.exp(-2j * np.pi * k / N) * odd[k] for k in range(N//2)] return [even[k] + T[k] for k in range(N//2)] + [even[k] - T[k] for k in range(N//2)] # 示例输入序列 x = [0, 1, 2, 3] # 填充序列到长度为2的幂 padded_x = np.pad(x, (0, 2**int(np.ceil(np.log2(len(x)))) - len(x)), 'constant') # 执行FFT fft_result = fft(padded_x) # 执行IFFT ifft_result = ifft(fft_result) # 截取结果的前原始序列长度部分 result = ifft_result[:len(x)] print("输入序列:", x) print("填充后的序列:", padded_x) print("FFT结果:", fft_result) print("IFFT结果:", ifft_result) print("还原后的序列:", result) ``` 这是一个基本的FFT和IFFT实现示例,使用递归方式进行FFT和IFFT操作。在实际应用中,你可能会使用更高效的算法或现有的库来执行这些操作。但是,这个示例可以帮助你理解FFT和IFFT的基本原理和实现方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值