Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
448 views
in Technique[技术] by (71.8m points)

python - Get frequency with highest amplitude from FFT

I have raw accelerometer data in form of x,y,z axes which is smoothened and I applied a band pass filter. Now I want to convert it to frequency domain signal and using the scipy.fftpack.fft to apply 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()

This figure has no points plotted and is empty. The return value of fft is a complex array. I'm using fftfreq to get the frequency of highest amplitude.

Can someone point where its wrong or give an example of how to get the value of frequency with the highest amplitude by applying FFT?

Full code of this is available here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I suggest you step away from your code and first master ability to perform a fft call and make sense of the result returned from that call ... either read in a sin curve of known freq or just write a function to populate an array with a floating point sin curve ( this is your time domain signal ) ... then feed that array into a fft call which will typically return back to you a new array of complex numbers ... each element of this new array which is now in the frequency domain represents one frequency value ... a frequency bin ... the magnitude of that frequency can be calculated using

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
}

where number_of_samples is just the length of your time domain array you fed into the fft call

Above code shows you how to iterate across the frequency domain array of complex numbers returned back to you from an earlier fft call ... above is pseudo code not python but your process could will be very similar

To identify the frequency ( curr_freq ) with the largest amplitude just keep track of which curr_freq had maximum magnitude in above loop ... In our toy setup you may well know the frequency of your source input sin curve so that same frequency should pop out as the curr_freq with the largest magnitude in above ... after you get this working and its concepts sink in then apply what you have learned to your task at hand - good luck

Fourier Analysis and its various incantations are extremely powerful and can open many doors. Its a topic which demands thinking, yet if we allow ourselves to simply plug some api calls together to get something working we have missed something very magical indeed


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...