从FFT获得最大幅度的频率

时间:2019-04-15 22:44:17

标签: python scipy fft accelerometer heartrate

我有x,y,z轴形式的原始加速度计数据,这些数据经过了平滑处理,并应用了带通滤波器。现在,我想将其转换为频域信号,并使用scipy.fftpack.fft进行FFT。

sampling_frequency = 32
def fft(acc_data):
  N = len(acc_data)

  fft_data = sp.fftpack.fft(acc_data)
  freqs = sp.fftpack.fftfreq(N)

  plt.bar(freqs, np.abs(fft_data)) 
  plt.xlabel('Frequency in Hertz [Hz]')
  plt.ylabel('Magnitude')
  plt.title('FFT')
  plt.show()

该图没有绘制点,为空。 fft的返回值是一个复杂的数组。我正在使用fftfreq来获取最高振幅的频率。

有人可以指出错误的地方还是举一个例子,说明如何通过应用FFT获得最大幅度的频率值?

完整的代码可用here

1 个答案:

答案 0 :(得分:1)

我建议您远离代码,并先掌握执行fft调用的能力,并理解该调用返回的结果...要么读入已知频率的sin曲线,要么编写一个函数来填充具有浮点正弦曲线的数组(这是您的时域信号)...然后将该数组馈入fft调用,该调用通常会返回给您一个新的复数数组...这个新数组的每个元素是现在在频域中代表一个频率值...一个频率仓...该频率的幅度可以使用

来计算
nyquist_limit_index := int(number_of_samples / 2)

curr_freq := 0.0
incr_freq := flow_data_spec.sample_rate / number_of_samples

for index, curr_complex := range complex_fft { 

    if index <= nyquist_limit_index  {

        curr_real = real(curr_complex) // pluck out real portion of imaginary number
        curr_imag = imag(curr_complex) // ditto for im

        curr_mag = 2.0 * math.Sqrt(curr_real*curr_real+curr_imag*curr_imag) / number_of_samples

        curr_theta = math.Atan2(curr_imag, curr_real) // phase shift of this freq

        curr_dftt := discrete_fft { // populate a struct of current array element

            real:      2.0 * curr_real,
            imaginary: 2.0 * curr_imag,
            magnitude: curr_mag,
            theta:     curr_theta,
        }

        //  optionally stow curr_dftt for later
    }

    curr_freq += incr_freq
}

其中number_of_samples只是馈入fft调用的时域数组的长度

上面的代码向您展示了如何遍历从先前的fft调用返回给您的复数的频域数组中...上面是伪代码而非python,但是您的过程可能非常相似

要确定最大振幅的频率(curr_freq),只需跟踪上述循环中哪个curr_freq的幅度最大即可...在我们的玩具设置中,您可能会知道源输入正弦曲线的频率,因此应该使用相同的频率弹出时,显示出上面最大的curr_freq ...在您完成此工作并且其概念沉入其中之后,将您学到的知识应用到手头的任务中-祝您好运

傅立叶分析及其各种方法非常强大,可以打开许多门。这是一个需要思考的主题,但是如果我们允许我们自己简单地将一些api调用连接在一起以使某些事情正常工作,那么我们确实会错过一些非常神奇的事情