Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么使用FFT在信号中舍入频率值?_Python_Numpy_Fft - Fatal编程技术网

Python 为什么使用FFT在信号中舍入频率值?

Python 为什么使用FFT在信号中舍入频率值?,python,numpy,fft,Python,Numpy,Fft,所以,我试图弄清楚如何在实践中使用DFT来检测信号中的主要频率。我一直在想傅里叶变换是什么,DFT算法是如何工作的,但显然我还有很多路要走。我已经编写了一些代码来生成信号,因为它的目的是与音乐一起工作,我生成了一个主要的C和弦,因此产生了奇怪的频率值,然后尝试返回到频率数字。这是我的密码 sr = 44100 # sample rate x = np.linspace(0, 1, sr) # one second of signal tpi = 2 * np.pi data = np.sin(2

所以,我试图弄清楚如何在实践中使用DFT来检测信号中的主要频率。我一直在想傅里叶变换是什么,DFT算法是如何工作的,但显然我还有很多路要走。我已经编写了一些代码来生成信号,因为它的目的是与音乐一起工作,我生成了一个主要的C和弦,因此产生了奇怪的频率值,然后尝试返回到频率数字。这是我的密码

sr = 44100 # sample rate
x = np.linspace(0, 1, sr) # one second of signal
tpi = 2 * np.pi
data = np.sin(261.63 * tpi * x) + np.sin(329.63 * tpi * x) + np.sin(392.00 * tpi * x)
freqs = np.fft.fftfreq(sr)
fft = np.fft.fft(data)
idx = np.argsort(np.abs(fft))
fft = fft[idx]
freqs = freqs[idx]
print(freqs[-6:] * sr)
这给了我[-262.262.-330.330.-392.392.]
这与我编码的261.63、329.63和392.0的频率不同。我做错了什么?如何修复它?

由于您希望获得0.01 Hz的分辨率,您需要至少采样100秒的数据。您将能够解析高达22.05 kHz的频率

由于您希望获得0.01 Hz的分辨率,因此需要对至少100秒的数据进行采样。您将能够解析高达22.05 kHz的频率

DFT结果箱在频率上由Fs/N分隔,其中N是FFT的长度。因此,DFT窗口的持续时间限制了DFT结果单元频率中心间距方面的分辨率


但是,对于低噪声高S/N中分离良好的频率峰值,您可以通过在DFT结果单元之间插值DFT结果,而不是增加数据的持续时间,将频率峰值位置估计到更高的分辨率。您可以尝试使用抛物线插值进行粗略的频率峰值位置估计,但是加窗Sinc插值(本质上是Shannon-Whittaker重建)将提供更好的频率估计精度和分辨率,因为感兴趣的频率峰值周围有足够低的噪声底,例如,在人工波形的情况下,附近没有正弦信号。

DFT结果单元在频率上由Fs/N分隔,其中N是FFT的长度。因此,DFT窗口的持续时间限制了DFT结果单元频率中心间距方面的分辨率


但是,对于低噪声高S/N中分离良好的频率峰值,您可以通过在DFT结果单元之间插值DFT结果,而不是增加数据的持续时间,将频率峰值位置估计到更高的分辨率。您可以尝试使用抛物线插值进行粗略的频率峰值位置估计,但是加窗Sinc插值(本质上是Shannon-Whittaker重建)将提供更好的频率估计精度和分辨率,因为感兴趣的频率峰值周围有足够低的噪声底,例如,在人工波形的情况下,附近没有正弦信号。

事实上,如果帧持续T秒,DFT的频率为k/T Hz,其中k是一个整数。因此,过采样不会提高估计频率的精度,只要这些频率被识别为DFT幅度的最大值。相反,考虑到持续100s的较长帧将导致DFT频率之间的间隔为0.01Hz,这可能足以产生预期的频率。通过将峰值频率估计为其相对于功率密度的平均频率,可以得到更好的结果

图1:即使在应用Tuckey窗之后,加窗信号的DFT也不是Dirac的总和:在峰值底部仍然存在一些光谱泄漏。在估计频率时,必须考虑该功率

另一个问题是帧的长度不是信号周期的倍数,信号周期可能不是周期性的。然而,DFT的计算就好像信号是周期性的,但在帧的边缘是不连续的。它会产生被称为频谱泄漏的杂散频率。开窗是处理此类问题和缓解与人工不连续相关问题的参考方法。实际上,在帧边缘附近,窗口的值会不断减小到零。在中提供了许多窗口功能。窗口应用为:

tuckey_window=signal.tukey(len(data),0.5,True)
data=data*tuckey_window
在这一点上,存在最大震级的频率仍然是262330和392。应用窗口只会使峰值更明显:加窗信号的DFT具有三个不同的峰值,每个峰值具有一个中心瓣和一个副瓣,具体取决于窗口的DFT。这些窗口的波瓣是对称的:因此,相对于功率密度,中心频率可以计算为峰值的平均频率


由此产生的估计频率为261.6359 Hz、329.637Hz和392.0088 Hz:比262、330和392Hz好得多,并且对于这种纯无噪声输入信号,它满足所需的0.01Hz精度。

确实,如果帧持续T秒,DFT的频率为k/T Hz,其中k是整数。因此,过采样不会提高估计频率的精度,只要这些频率 偏差被认为是DFT的最大值。相反,考虑到持续100s的较长帧将导致DFT频率之间的间隔为0.01Hz,这可能足以产生预期的频率。通过将峰值频率估计为其相对于功率密度的平均频率,可以得到更好的结果

图1:即使在应用Tuckey窗之后,加窗信号的DFT也不是Dirac的总和:在峰值底部仍然存在一些光谱泄漏。在估计频率时,必须考虑该功率

另一个问题是帧的长度不是信号周期的倍数,信号周期可能不是周期性的。然而,DFT的计算就好像信号是周期性的,但在帧的边缘是不连续的。它会产生被称为频谱泄漏的杂散频率。开窗是处理此类问题和缓解与人工不连续相关问题的参考方法。实际上,在帧边缘附近,窗口的值会不断减小到零。在中提供了许多窗口功能。窗口应用为:

tuckey_window=signal.tukey(len(data),0.5,True)
data=data*tuckey_window
在这一点上,存在最大震级的频率仍然是262330和392。应用窗口只会使峰值更明显:加窗信号的DFT具有三个不同的峰值,每个峰值具有一个中心瓣和一个副瓣,具体取决于窗口的DFT。这些窗口的波瓣是对称的:因此,相对于功率密度,中心频率可以计算为峰值的平均频率


由此产生的估计频率为261.6359 Hz、329.637Hz和392.0088 Hz:比262、330和392Hz好得多,并且对于这样一个纯无噪声的输入信号,它满足了所需的0.01Hz精度。

好吧,你没有说你期望看到的,所以说不出来。我认为从我的描述来看,它相当清楚。我希望看到我输入信号的频率,261.63、329.63和392@MadWombat因为你的采样频率与你的采样频率一样多(以Hz为单位),所以最大的理论分辨率是1Hz–因此,如果没有更多的样本,这是不可能的。@MadWombat,你更新了你的代码,但不是你所说的输出。@MadWombat如果你没有足够的样本,更高的采样率没有什么区别。可用频率桶的最大数量是样本数量/2也有消极成分Swell,你没有说你期望看到的,所以说不出来。我认为从我的描述可以相当清楚。我希望看到我输入信号的频率,261.63、329.63和392@MadWombat因为你的采样频率与你的采样频率一样多(以Hz为单位),所以最大的理论分辨率是1Hz–因此,如果没有更多的样本,这是不可能的。@MadWombat,你更新了你的代码,但不是你所说的输出。@MadWombat如果你没有足够的样本,更高的采样率没有什么区别。可用频率桶的最大数量为采样数/2,也有负分量。是否有可能以限制频率范围为代价修改DFT算法以提高精度?您可以通过降低采样率来减小范围。只要采样100秒,仍然可以获得0.01 Hz的分辨率。仅当序列号较低时,才需要增加长度。否则,可以插值以获得更高的分辨率。我想知道。是否有可能以限制频率范围为代价修改DFT算法以提高精度?您可以通过降低采样率来减小范围。只要采样100秒,仍然可以获得0.01 Hz的分辨率。仅当序列号较低时,才需要增加长度。否则,可以插值以获得更高的分辨率。