使用 python 进行二维 FFT 会导致频率略有偏移

2023-12-31

我知道关于在 python 中使用快速傅立叶变换(FFT)方法存在几个问题,但不幸的是它们都不能帮助我解决我的问题:

我想使用python计算给定二维信号f的快速傅里叶变换,即f(x,y)。 Python 文档帮助很大,解决了 FFT 带来的一些问题,但与我期望它显示的频率相比,我最终得到的频率仍然略有偏移。这是我的Python代码:

from scipy.fftpack import fft, fftfreq, fftshift
import matplotlib.pyplot as plt
import numpy as np
import math

fq = 3.0 # frequency of signal to be sampled
N = 100.0 # Number of sample points within interval, on which signal is considered
x = np.linspace(0, 2.0 * np.pi, N) # creating equally spaced vector from 0 to 2pi, with spacing 2pi/N
y = x
xx, yy = np.meshgrid(x, y) # create 2D meshgrid
fnc = np.sin(2 * np.pi * fq * xx) # create a signal, which is simply a sine function with frequency fq = 3.0, modulating the x(!) direction
ft = np.fft.fft2(fnc) # calculating the fft coefficients

dx = x[1] - x[0] # spacing in x (and also y) direction (real space)
sampleFrequency = 2.0 * np.pi / dx
nyquisitFrequency = sampleFrequency / 2.0

freq_x = np.fft.fftfreq(ft.shape[0], d = dx) # return the DFT sample frequencies 
freq_y = np.fft.fftfreq(ft.shape[1], d = dx)

freq_x = np.fft.fftshift(freq_x) # order sample frequencies, such that 0-th frequency is at center of spectrum 
freq_y = np.fft.fftshift(freq_y)

half = len(ft) / 2 + 1 # calculate half of spectrum length, in order to only show positive frequencies

plt.imshow(
    2 * abs(ft[:half,:half]) / half,
    aspect = 'auto',
    extent = (0, freq_x.max(), 0, freq_y.max()),
    origin = 'lower',
    interpolation = 'nearest',
)
plt.grid()
plt.colorbar()
plt.show()

运行它时我得到的是:

现在您会发现 x 方向上的频率并不完全位于fq = 3,但稍微向左移动。为什么是这样? 我认为这与以下事实有关:FFT 是一种使用对称参数的算法,并且

half = len(ft) / 2 + 1

用于在适当的位置显示频率。但我不太明白确切的问题是什么以及如何解决它。

编辑:我还尝试使用更高的采样频率(N = 10000.0),这并没有解决问题,而是将频率稍微向右移动了太多。所以我很确定问题不在于采样频率。

注意:我知道泄漏效应会导致这里的非物理振幅,但在这篇文章中我主要对正确的频率感兴趣。


我发现了很多问题

you use 2 * np.pi两次,如果你想要一个很好的整数周期数,你应该选择 linspace 或 arg 到正弦弧度之一

此外np.linspace默认为endpoint=True,给您额外的分数 101 而不是 100

fq = 3.0 # frequency of signal to be sampled
N = 100 # Number of sample points within interval, on which signal is considered
x = np.linspace(0, 1, N, endpoint=False) # creating equally spaced vector from 0 to 2pi, with spacing 2pi/N
y = x
xx, yy = np.meshgrid(x, y) # create 2D meshgrid
fnc = np.sin(2 * np.pi * fq * xx) # create a signal, which is simply a sine function with frequency fq = 3.0, modulating the x(!) direction

你可以检查这些问题:

len(x)
Out[228]: 100

plt.plot(fnc[0])

现在修复 linspace 端点意味着您有偶数个 fft bin,因此您可以删除+ 1 in the half calc

matshow()似乎有更好的默认值,你的extent = (0, freq_x.max(), 0, freq_y.max()), in imshow似乎 fubar 的 fft bin 编号

from scipy.fftpack import fft, fftfreq, fftshift
import matplotlib.pyplot as plt
import numpy as np
import math

fq = 3.0  # frequency of signal to be sampled
N = 100  # Number of sample points within interval, on which signal is considered
x = np.linspace(0, 1, N, endpoint=False)  # creating equally spaced vector from 0 to 2pi, with spacing 2pi/N
y = x
xx, yy = np.meshgrid(x, y)  # create 2D meshgrid
fnc = np.sin(2 * np.pi * fq * xx)  # create a signal, which is simply a sine function with frequency fq = 3.0, modulating the x(!) direction

plt.plot(fnc[0])

ft = np.fft.fft2(fnc)  # calculating the fft coefficients

#dx = x[1] - x[0]  # spacing in x (and also y) direction (real space)
#sampleFrequency = 2.0 * np.pi / dx
#nyquisitFrequency = sampleFrequency / 2.0
#
#freq_x = np.fft.fftfreq(ft.shape[0], d=dx)  # return the DFT sample frequencies 
#freq_y = np.fft.fftfreq(ft.shape[1], d=dx)
#
#freq_x = np.fft.fftshift(freq_x)  # order sample frequencies, such that 0-th frequency is at center of spectrum 
#freq_y = np.fft.fftshift(freq_y)

half = len(ft) // 2  # calculate half of spectrum length, in order to only show positive frequencies

plt.matshow(
            2 * abs(ft[:half, :half]) / half,
            aspect='auto',
            origin='lower'
            )
plt.grid()
plt.colorbar()
plt.show()

zoomed the plot: enter image description here

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 python 进行二维 FFT 会导致频率略有偏移 的相关文章

随机推荐

  • 在 Win7 中,某些字体无法像在 Win2K/XP 中那样工作

    我的问题是如何更改字体处理才能在 Windows 7 下正常工作 我确信我已经对以前有效但不再有效的内容做出了假设 但我什至不知道从哪里开始寻找 我祈祷有人可以帮忙 以下是我理解的详细信息 我还在 Microsoft Windows 开发人
  • 应用内购买:用户绑定购买上的“恢复购买”按钮

    我目前正在我的 Swift 应用程序中实现应用内购买 该产品是一种非消耗性产品 可为用户激活一种高级版本 通常 对于非消耗品购买 您必须在应用程序中放置 恢复购买 按钮 强制 然而 我的问题是 该应用程序以及因此的购买是受用户约束的 因此
  • UIPageViewController 子视图控制器之间的水平填充

    我正在使用 UIPageViewController 来显示嵌入在子视图控制器中的图像 NSDictionary options NSDictionary dictionaryWithObject NSNumber numberWithIn
  • Coq - 在 if ... then ... else 中使用 Prop (True | False)

    我对 Coq 有点陌生 我正在尝试实现插入排序的通用版本 我正在实现一个以比较器作为参数的模块 该 Comparator 实现了比较运算符 如 is eq is le is neq 等 在插入排序中 为了插入 我必须比较输入列表中的两个元素
  • 可以从多个模块访问包

    我的项目在 Java 1 8u151 上运行良好 我正在尝试将其升级到 Java 12 但出现以下错误 Package is accessible from more than one module
  • 如何在 emacs 中永久启用 hs-minor-mode

    我在 emacs 文件中使用 thhs 代码来永久启用 hs minor mode 并更改快捷方式 setq default hs minor mode t global set key kbd C c C h kbd C c C h hi
  • 在 Windows Phone 10 中安装 appx 或 appxbundle?

    我正在开发一个 UWP 应用程序 当使用 VS2015 调试它时运行没有任何问题 但当使用 appx 或 appxbundle 安装它时 我已经阅读了很多打包和安装指南 似乎我并没有遗漏任何步骤 我只需要在设备中部署应用程序以仅用于测试目的
  • MySQL 查询值列表

    我想从值列表创建一个查询并返回每个匹配的数据cat 这可行 但不需要options价值 查询值列表的更简单方法是什么 SELECT FROM table1 WHERE option R cat 12 cat 18 cat 30 您可以使用I
  • 设备可锁定第 n 次尝试时的自定义消息

    我正在寻找一种方法来显示设计可锁定模块中各种失败尝试次数的自定义消息 我发现默认情况下只能通知最后一次尝试 https github com plataformatec devise blob master lib devise model
  • 如何使用 C# 获取 .NET 中的当前用户名?

    如何使用 C 获取 NET 中的当前用户名 string userName System Security Principal WindowsIdentity GetCurrent Name
  • 如何在自己的线程上创建表单并在整个应用程序生命周期中保持其打开状态

    我正在创建一个小测试组件 但遇到了问题 基本上 该组件是控制对数据库的所有访问的类上的装饰器 它创建一个带有两个按钮的表单 模拟丢失连接 和 重新连接 按下按钮 不再让函数调用通过包装器 而是开始抛出 NoConnectionExcepti
  • 如何使背景图像即使滚动也保持在左下角

    我想知道是否有一种方法可以使我的背景图像始终保持在左下角 即使用户滚动浏览器也是如此 我当前的CSS可以在网站加载时使图像位于浏览器底部 但是如果我滚动浏览器 它仍然会停留在同一位置 我很感激任何帮助 html body backgroun
  • 如何在 Windows 10 中启用 USB 重定向 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我的操作系统是 Windows 7 我有一个远程主机 Windows 8 1 我可以使用 RDP 将本地 USB 设备重定向到 Windo
  • Heroku SpringBoot ClassPathResource 获取 FileNotFoundException

    我在 Heroku 上部署了一个 SpringBoot 项目 尽管它在本地运行得很好 但我得到了 FileNotFoundException 这是代码 GetMapping path api items image get file nam
  • 无法在真实设备上获取 FCM 令牌,但在模拟器上获取

    我已将 Firebase 云消息传递集成到我的 iOS 应用程序中 而无需使用 cocoa pod Firebase 分析工作正常 但 FCM 令牌是在模拟器上收到的 而不是在真实设备上收到的 在真实设备上我不断收到错误 无法获取默认令牌错
  • 通过 :ruby 过滤器输出 haml 内容

    当我使用 ruby过滤器在 haml 中做一些简单的事情 例如 ruby to comments gt max comments max comments comments 0 to each do i comment data i put
  • Firebase UID 是否始终为 28 个字符?

    我正在为我的 Firebase 项目创建安全规则并想添加UIDstring length 28按照我的数据库规则 我所有的用户 UID 都是 28 个字符 但我想检查它们是否可以更长或更短 Thanks 一位 Firebase 开发人员有这
  • 绘制我自己的标题栏

    我正在我的 WinForm 应用程序中绘制标题栏的一部分 工作正常 将公司名称置于居中并以橙色显示 这是在表单代码中执行此操作的代码 using System Runtime InteropServices DllImport user32
  • C# - 向 IP 地址和端口发送和接收 TCP/IP 消息

    我有以下代码将 TCP IP 消息发送到特定的 IP 地址和端口 public bool sendTCPMessage string ip address string port string transaction id string c
  • 使用 python 进行二维 FFT 会导致频率略有偏移

    我知道关于在 python 中使用快速傅立叶变换 FFT 方法存在几个问题 但不幸的是它们都不能帮助我解决我的问题 我想使用python计算给定二维信号f的快速傅里叶变换 即f x y Python 文档帮助很大 解决了 FFT 带来的一些