0

我一直在尝试找到一个导致峰值频率的 DFT(或 FFT)的简单实现。但是,我见过的大多数实现都会输出一个复数数组。如何将这些 radix-2 结果转换为具体频率?

例如,我的输入数据是正弦波函数的 16 个样本,该函数在 500 - 2000Hz 之间振荡,如下所示:

int n = 16;    
double[] input = { 1250, 1537, 1780, 1943, 2000, 1943, 1780, 1537,
            1250, 963, 720, 557, 500, 557, 720, 963 };

现在,我假设由此产生的峰值频率正好是 750 Hz,因为 (2000 - 500) / 2 = 750。

我在考虑我的采样率Fs = 2000 Hz,因为这是我将正弦波限制在的振荡上限。每个 bin k 的中心频率定义为k * Fs / n,因此我的 bin 是 125 Hz、250 Hz、375 Hz、500 Hz、625 Hz 和 750 Hz。但是因为我的振荡下限是 500 赫兹,我假设我需要用 500 赫兹偏移箱,因此它们变成:750 Hz, 825 Hz, 1000 Hz, 1125 Hz, 1250 Hz, 1375 Hz, 1500 Hz

然后使用 jtransforms 的 DoubleFFT_1D 类,我得到一些 FFT 数据:

DoubleFFT_1D fft = new DoubleFFT_1D(n);
fft.realForward(input);

输入变量现在包含:

[20000.0, 0.0, -4.547473508864641E-13, -5999.381020591891, 0.0, 0.0, -1.6292522886374172E-14, 1.1183950775908065, 0.0, -0.0, 1.6292522886374172E-14, -0.7488526914476931, 0.0, 0.0, 4.547473508864641E-13, -1.2482683609296146]

将数组值分组为更易于理解的形式(根据我在 SO其他地方获得的一些信息):

20000.0                                         [sum of input array values]
0.0,                                            [1625 Hz]
-4.547473508864641E-13, -5999.381020591891,     [re1 and im1] [750 Hz]
0.0, 0.0,                                       [re2 and im2] [875 Hz]
-1.6292522886374172E-14, 1.1183950775908065,    [re3 and im3] [1000 Hz]
0.0, -0.0,                                      [re4 and im4] [1125 Hz]
1.6292522886374172E-14, -0.7488526914476931,    [re5 and im5] [1250 Hz]
0.0, 0.0,                                       [re6 and im6] [1375 Hz]
4.547473508864641E-13, -1.2482683609296146      [re7 and im7] [1500 Hz]

两个问题:

  1. 我对频率区间的假设是否正确?
  2. 我现在如何通过总结一些幅度来从这些数据中获得峰值频率?

谢谢。

4

3 回答 3

1

根据定义,FFT 的输出值不是频率;变量(即图表上的轴)是频率。您要做的是找到复杂结果的幅度以获得绝对值,但这些不是频率 - 相反,产生最大峰值的x值是您想要的频率。

如果您不确定,可以在Wikipedia上描述复数的大小。它只是实部和复数部分的平方和的平方根,但是要找到最大值,您显然不需要计算平方根。

于 2013-03-12T09:22:47.193 回答
1

确实,一旦您确定了 bin 的频率,幅度最高的 bin 的频率就接近峰值。但是你可以通过插值做得更好。你的高峰几乎总是在垃圾箱之间。这个网站似乎有几种很好的插值方法:http ://www.dspguru.com/dsp/howtos/how-to-interpolate-fft-peak

于 2013-03-15T03:33:17.570 回答
0

对于每个频率区间,您应该有两个值,实数 (x) 和虚数 (y) 平方和将为您提供该频率的幅度:

magnitude = sqrt(x*x + y*y);

虽然如果只求峰值,不需要平方根,只要找到最高的频率即可

magSquared = x*x + y*y
于 2013-03-12T09:20:39.763 回答