我想知道数据的频率。我有一点想法,可以使用FFT来完成,但我不确定如何做。一旦我将整个数据传递给FFT,它就会给我2个峰值,但我该如何得到频率?
非常感谢提前。
我想知道数据的频率。我有一点想法,可以使用FFT来完成,但我不确定如何做。一旦我将整个数据传递给FFT,它就会给我2个峰值,但我该如何得到频率?
非常感谢提前。
以下是您可能要查找的内容:
当您谈论计算信号频率时,可能不太关心组成正弦波。这就是FFT给您的东西。例如,如果您求和sin(2*pi*10x)+sin(2*pi*15x)+sin(2*pi*20x)+sin(2*pi*25x),您可能想将“频率”检测为5(查看此函数的图表)。但是,此信号的FFT将检测到频率5的0幅度。
您可能更感兴趣的是信号的周期性。也就是说,信号变得最像自己的间隔。因此,您最有可能想要的是自相关。查一下。这基本上会给您一个度量,即经过一定量的移动后,信号与自身相似程度的度量。因此,如果在自相关中找到峰值,则表示信号在移位一定量后与自身匹配良好。它背后有很多很酷的数学,如果您有兴趣,请查阅,但如果您只想让它工作,请执行以下操作:
使用平滑窗口(余弦函数即可),对信号进行加权。窗口的大小至少应是你希望检测到的最大周期的两倍,如果为三倍,则结果更佳(如有疑问,请参考http://zone.ni.com/devzone/cda/tut/p/id/4844)。
进行FFT变换(确保FFT大小是窗口大小的两倍,第二个半部分用零填充。如果FFT大小只是窗口大小,则实际上会进行圆形自相关,这不是你想要的。请参考https://en.wikipedia.org/wiki/Discrete_Fourier_transform#Circular_convolution_theorem_and_cross-correlation_theorem)。
将FFT的所有系数替换为它们的平方值(real^2+imag^2)。这实际上是进行自相关。
进行iFFT变换。
找到iFFT中的最大峰值。这是波形的最强周期性。你可以在选择峰值时更聪明一些,但对于大多数目的来说,这应该足够了。要找到频率,只需取f=1/T。
x [n] = cos(2*pi*f0*n/fs)
,其中f0
是您正弦波的频率(以赫兹为单位),n = 0:N-1
,fs
是每秒样本数时的采样率。X = fft(x)
。 x
和X
都具有长度N
。 假设X
在n0
和N-n0
处具有两个峰值。f0 = fs * n0 / N
赫兹。
示例:fs
为每秒8000个样本,N
为16000个样本。 因此,x
持续两秒钟。X = fft(x)
在2000和14000(= 16000-2000)处有峰值。 因此,f0
= 8000 * 2000/16000 = 1000 Hz。y = sin(2 pi f t)
使用:
然后你会得到两个峰值,一个在与f对应的频率处,另一个在与-f对应的频率处。
因此,为了得到一个频率,可以丢弃负频率部分。它位于正频率部分之后。此外,数组中的第一个元素是直流偏移量,因此频率为0。(请注意,此偏移通常大于0,因此其他频率成分可能会被压制。)
代码示例(我用Python编写了它,但在C#中同样简单):
import numpy as np
from pylab import *
x = np.random.rand(100) # create 100 random numbers of which we want the fourier transform
x = x - mean(x) # make sure the average is zero, so we don't get a huge DC offset.
dt = 0.1 #[s] 1/the sampling rate
fftx = np.fft.fft(x) # the frequency transformed part
# now discard anything that we do not need..
fftx = fftx[range(int(len(fftx)/2))]
# now create the frequency axis: it runs from 0 to the sampling rate /2
freq_fftx = np.linspace(0,2/dt,len(fftx))
# and plot a power spectrum
plot(freq_fftx,abs(fftx)**2)
show()
Frequency_of_Peak = Data_Sample_Rate * Bin_number_of_Peak / Length_of_FFT ;
#include <rfftw.h>
...
{
fftw_real in[N], out[N], power_spectrum[N/2+1];
rfftw_plan p;
int k;
...
p = rfftw_create_plan(N, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);
...
rfftw_one(p, in, out);
power_spectrum[0] = out[0]*out[0]; /* DC component */
for (k = 1; k < (N+1)/2; ++k) /* (k < N/2 rounded up) */
power_spectrum[k] = out[k]*out[k] + out[N-k]*out[N-k];
if (N % 2 == 0) /* N is even */
power_spectrum[N/2] = out[N/2]*out[N/2]; /* Nyquist freq. */
...
rfftw_destroy_plan(p);
}
N = length(x);
xdft = fft(x);
xdft = xdft(1:N/2+1);
psdx = (1/(Fs*N)).*abs(xdft).^2;
psdx(2:end-1) = 2*psdx(2:end-1);
freq = 0:Fs/length(x):Fs/2;
频率=速度/波长。
波长是两个峰之间的距离。