我想知道数据的频率。我有点想到它可以使用FFT完成,但我不知道该怎么做。一旦我将整个数据传递给FFT,它就会给我2个峰值,但我怎样才能获得频率?
提前多多感谢。
答案 0 :(得分:10)
假设x[n] = cos(2*pi*f0*n/fs)
其中f0
是赫兹的正弦波频率,n=0:N-1
,fs
是每秒样本中x
的采样率
让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。
答案 1 :(得分:8)
以下是您可能正在寻找的内容:
当你谈到计算信号的频率时,你可能对组件正弦波不太感兴趣。这就是FFT给你的。例如,如果你总和sin(2 * pi * 10x)+ sin(2 * pi * 15x)+ sin(2 * pi * 20x)+ sin(2 * pi * 25x),你可能想要检测“频率” “为5(看看这个功能的图表)。但是,该信号的FFT将检测频率为5的 0 的幅度。
您可能更感兴趣的是信号的周期性。也就是说,信号变得最像自己的间隔。所以你最想要的是 autocorrelation 。仔细看看。这基本上可以衡量信号在被移位一定量后自身与自身相似的程度。因此,如果您在自相关中找到一个峰值,那么这表明信号在移动超过该量时与自身匹配良好。它背后有很多很酷的数学,如果你有兴趣可以查阅,但如果你只想让它工作,那就这样做:
使用平滑窗口(余弦将会这样做)窗口信号。窗口应该至少是您想要检测的最大周期的两倍。大3倍会产生更好的结果)。 (如果您感到困惑,请参阅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)
用其平方值(real ^ 2 + imag ^ 2)替换FFT的所有系数。这实际上是在进行自相关。
参加iFFT
找到iFFT中最大的峰值。这是波形的最强周期。实际上你可以更聪明地选择哪个峰值,但对于大多数用途来说,这应该足够了。要查找频率,只需f = 1 / T.
答案 2 :(得分:6)
如果您有一个频率的信号(例如:
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()
现在频率位于最大峰值。
答案 3 :(得分:4)
如果您正在查看最常用类型的FFT的幅度结果,那么实际数据的强正弦频率分量将显示在两个位置,一个位于下半部分,加上其复共轭镜像上半部分。这两个峰值都代表相同的光谱峰值和相同的频率(对于严格的实际数据)。如果FFT结果bin编号从0(零)开始,则FFT结果的下半部分中由bin表示的正弦分量的频率最有可能。
Frequency_of_Peak = Data_Sample_Rate * Bin_number_of_Peak / Length_of_FFT ;
确保在上述等式中找出合适的单位(获得每秒周期单位,每两周,每千克等)。
请注意,除非数据的波长是FFT长度的精确整数的约数,否则实际峰值将在二进制位之间,从而在多个附近的FFT结果二进制位之间分配能量。因此,您可能需要进行插值以更好地估计频率峰值。寻找更精确的频率估计的常见插值方法是3点抛物线和Sinc卷积(这与使用零填充更长的FFT几乎相同)。
答案 4 :(得分:1)
假设您使用离散傅里叶变换来查看频率,那么您必须注意如何将归一化频率解释为物理频率(即Hz)。
根据FFTW tutorial关于如何计算信号的功率谱:
#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);
}
请注意,它处理的数据长度不均匀。请注意,如果给出数据长度,FFTW将为您提供与奈奎斯特频率相对应的“bin”(采样率除以2)。否则,你没有得到它(即最后一个箱子就在Nyquist之下)。
MATLAB example类似,但他们选择的长度为1000(偶数):
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;
通常,它可以是(DFT)的实现依赖。您应该以已知频率创建测试纯正弦波,然后确保计算得到相同的数字。
答案 5 :(得分:-7)
频率=速度/波长。
波长是两个峰值之间的距离。