【问题标题】:How do I get the frequencies from a signal?如何从信号中获取频率?
【发布时间】:2019-03-21 15:10:53
【问题描述】:

我正在寻找一种从信号中获取频率的方法。这是一个例子:

signal = [numpy.sin(numpy.pi * x / 2) for x in range(1000)]

此数组将表示录制声音的样本(x = 毫秒)

sin(pi*x/2) => 250 赫兹

我们如何从信号(点列表)中获取频率?

注意: 我已经阅读了许多 Stackoverflow 线程并观看了许多 youtube 视频。我还没有找到答案。请使用简单的词。 (感谢每一个回答)

【问题讨论】:

    标签: python signals fft frequency


    【解决方案1】:

    您正在寻找的是Fourier Transform


    一点背景

    让我们从formal definition开始:

    傅里叶变换 (FT) 将函数(通常是时间或信号的函数)分解为其组成频率

    这本质上是一种数学运算,当应用于信号时,可以让您了解每个频率在时间序列中的呈现方式。为了了解这背后的一些直觉,查看DFT 的数学定义可能会有所帮助:

    这里的k 一直向上扫到N-1 以计算所有DFT 系数。

    首先要注意的是,这个定义有点类似于两个函数的相关性,在这种情况下是x(n) 和负指数函数。虽然这看起来有点抽象,但通过使用Euler's formula 并稍微调整一下定义,DFT 可以表示为与正弦波和余弦波的相关性,这将解释虚数和DFT 的真实部分。

    因此请记住,这实质上是计算相关性,每当复指数分解中的相应正弦或余弦与 x(n) 匹配时,X(K) 中就会出现一个峰值,这意味着,这种频率存在于信号中。


    我们如何用 numpy 做同样的事情?

    所以在给出了非常简短的理论背景之后,让我们考虑一个例子来看看如何在 python 中实现它。让我们考虑following signal

    Fs = 150.0;  # sampling rate
    Ts = 1.0/Fs; # sampling interval
    t = np.arange(0,1,Ts) # time vector
    
    ff = 50;   # frequency of the signal
    y = np.sin(2*np.pi*ff*t)
    
    plt.plot(t, y)
    plt.xlabel('Time')
    plt.ylabel('Amplitude')
    

    现在,可以使用np.fft.fft 计算 DFT,如前所述,它将告诉您现在在变换域中信号中每个频率的贡献:

    n = len(y) # length of the signal
    k = np.arange(n)
    T = n/Fs
    frq = k/T # two sides frequency range
    frq = frq[:len(frq)//2] # one side frequency range
    
    Y = np.fft.fft(y)/n # dft and normalization
    Y = Y[:n//2]
    

    现在,如果我们绘制实际频谱图,您会看到我们在 50Hz 的频率处得到一个峰值,从数学角度来说,它是一个以 50Hz 基频为中心的 delta 函数。这可以在以下Table of Fourier Transform Pairs 表中检查。

    所以对于上面的信号,我们会得到:

    plt.plot(frq,abs(Y)) # plotting the spectrum
    plt.xlabel('Freq (Hz)')
    plt.ylabel('|Y(freq)|')
    

    【讨论】:

      猜你喜欢
      • 2017-02-09
      • 2013-04-01
      • 1970-01-01
      • 2017-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-25
      • 2012-05-18
      相关资源
      最近更新 更多