【问题标题】:Is np.fft.fft working properly? I am getting very large frequency valuesnp.fft.fft 工作正常吗?我得到非常大的频率值
【发布时间】:2020-02-04 00:31:50
【问题描述】:

我正在尝试做一些音频清理,这是我在使用 python 或其他方式之前从未做过的,我想到了可以使用 FFT 来查找构成我的音频的频率并消除不构成音频的频率'属于。我在普通音频上做了,但我无法理解结果,所以我在一个简单的正弦波上试了一下。

我做到了

frequency = 1000

num_samples = 48000

# The sampling rate of the analog to digital convert

sampling_rate = 48000.0
sine_wave = [np.sin(2 * np.pi * frequency * x1 / sampling_rate) for x1 in range(num_samples)]
sine_wave = np.array(sine_wave)

然后我播放并绘制它,它看起来和听起来都像正常大小的波浪。

fig, ax = plt.subplots(figsize=(20,3))
ax.plot(sine_wave[:500])
IPython.display.Audio(data=sine_wave, rate=44100)

但是当我做 fft 并查看图表上的频率时,它没有意义

def do_fft(data_samples):  
    data_fft = np.fft.fft(data_samples)
    freq = (np.abs(data_fft[:len(data_fft)]))
    plt.subplots(figsize=(20,10))
    plt.plot(freq)
    print("The frequency is {} Hz".format(np.argmax(freq)))
    return freq

sine_freq = do_fft(sine_wave)
sine_freq[47000]

首先,我真的不明白我的频率阵列应该是什么意思。我知道某个索引处的高数字 K 意味着 K Hz 在声音中出现了很多。这是有道理的,因为我在 1000 Hz 时得到了 23,999.99999 的值,这就是我的波频率。没有意义的是,我在 47,000 Hz 下得到了 24,000。这对我来说没有任何意义。我做错什么了吗? fft 是不是不能正常工作?

【问题讨论】:

  • 我想将这个问题作为重复问题结束,但重复的问题太多了,我什至不知道该选择哪一个...请阅读these Q&As 中的一些内容以获得答案。跨度>

标签: python numpy signal-processing fft


【解决方案1】:

严格实数(所有虚部 == 零)数据的 FFT 始终是共轭镜像对称的。这就是 FFT 的数学运算方式。因此,您的 47kHz 峰值(与 -1kHz 相同)只是 1kHz 在 48k 采样率下的镜像。奈奎斯特折叠频率或镜像铰链是采样率的一半(和/或如果您认为较高的 bin 频率为负值,则为零)。

【讨论】:

    【解决方案2】:

    我更喜欢明确定义时间并计算频率。应该根据这些频率绘制 FT。 argmax 单独计算向量中的位置,而不是频率。 采样率 (sa/sec) 不是频率。奈奎斯特定理(除其他外)指出,您的最大频率(以 Hz 为单位)是采样率(以 Sa/sec 为单位)的 1/2。 由于我们使用的是复数 FT(显示正负频率),-999.979 Hz 实际上是 +1000 Hz。

    import numpy as np
    import matplotlib.pyplot as p
    
    sampling_rate = 48000 
    
    t= np.linspace(0,1,sampling_rate+1)       # time vector
    dt=t[1]-t[0]
    print(f'first/last time {t[0]}, {t[-1]}')
    print(f'time interval : {dt}')
    
    
    f = 1000
    sig = np.sin(2 * np.pi * f*t)
    
    fig = p.figure(figsize=(15,10))
    p.subplot(211)
    p.plot(sig[:500])
    
    p.subplot(212)
    ft = np.fft.fftshift(np.fft.fft(sig))
    freq=np.fft.fftshift(np.fft.fftfreq(len(t),dt))
    p.plot(freq,ft )
    print(f'argmax of FT is not a frequency, but a position in a vector : {np.argmax(ft)}')
    f0=freq[np.argmax(ft)]
    print(f'the frequency is {f0:.3f} Hz')
    

    【讨论】:

    • 我在这里有点困惑。你的 ft 变量是什么?那代表什么? np.fft.fftshift 在做什么?你能否解释一下你做了什么来得到你的 freq 变量。另外,您将频率绘制为英尺。为什么会有负数?为什么有 2 个酒吧?
    • 有四个变量:时间t、时间幅度sig、频率freq和频率空间幅度ft。由于 DFT 的定义有两个条形图,它允许负频率。这些负频率的幅度与正频率的幅度相同,因此您可以只绘制右半部分而不会丢失信息。通过打印一些 'freq' 和 'ft' 值来检查它。另请参阅@hotpaw2 注释。
    • fftshift 是频率向量的旋转(Mathematica)或滚动(Numpy)。不带 fftshift 的 FT 从 0 频率开始,在中间达到最大(奈奎斯特),然后在中间以负奈奎斯特频率重新开始,最后达到 0 频率。这是就地 FFT 操作的结果。你可以只拿上半场就可以了(没有。负频率)。但是负频率在许多物理情况(例如衍射)中都很有用。我试图保持一般,所以我使用所有 FFT 提供,但正如@hotpaw 所说,对于你的情况,你不需要 neg。频率。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多