理解 FFT 输出

我需要一些帮助来理解 DFT/FFT 计算的输出。

我是一个经验丰富的软件工程师,需要解释一些智能手机加速度计读数,如找到主要频率。不幸的是,十五年前,我大部分的大学电子工程学课程都是在睡觉,但是在过去的几天里,我一直在阅读 DFT 和 FFT (显然,几乎没什么用)。

拜托,不要回答“去上电子工程课”。如果我的雇主愿意付钱给我,我就打算这么做。:)

所以我的问题是:

我捕捉到一个32赫兹的信号。下面是我在 Excel 中绘制的32个点的1秒钟示例。

enter image description here

然后我从哥伦比亚大学得到了一些用 Java 写的 FFT 密码(在遵循了“ Java 中可靠快速的 FFT 算法”的帖子中的建议之后)。

这个程序的输出如下。我相信它正在运行一个就地 FFT,因此它对输入和输出重用相同的缓冲区。

Before:


Re: [0.887  1.645  2.005  1.069  1.069  0.69  1.046  1.847  0.808  0.617  0.792  1.384  1.782  0.925  0.751  0.858  0.915  1.006  0.985  0.97  1.075  1.183  1.408  1.575  1.556  1.282  1.06  1.061  1.283  1.701  1.101  0.702  ]


Im: [0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  ]


After:


Re: [37.054  1.774  -1.075  1.451  -0.653  -0.253  -1.686  -3.602  0.226  0.374  -0.194  -0.312  -1.432  0.429  0.709  -0.085  0.0090  -0.085  0.709  0.429  -1.432  -0.312  -0.194  0.374  0.226  -3.602  -1.686  -0.253  -0.653  1.451  -1.075  1.774  ]


Im: [0.0  1.474  -0.238  -2.026  -0.22  -0.24  -5.009  -1.398  0.416  -1.251  -0.708  -0.713  0.851  1.882  0.379  0.021  0.0  -0.021  -0.379  -1.882  -0.851  0.713  0.708  1.251  -0.416  1.398  5.009  0.24  0.22  2.026  0.238  -1.474  ]

因此,在这一点上,我不能理解输出的正反面。我理解 DFT 的概念,例如实部分是分量余弦波的振幅,虚部分是分量正弦波的振幅。我还可以按照伟大著作《 数字信号处理的科学家和工程师指南》中的图表来做: enter image description here

所以我的具体问题是:

  1. 从 FFT 的输出,我如何找到“最出现的频率”?这是我对加速度计数据分析的一部分。我应该读取实数(余弦)还是虚数(正弦)数组?

  2. 我有一个32点输入在时间域。FFT 的输出不应该是实数的16元数组和虚数的16元数组吗?为什么这个程序给我实数和虚数的数组输出都是32的?

  3. 与前面的问题相关的是,如何解析输出数组中的索引?鉴于我的输入32个采样在32赫兹,我的理解是,一个16个元素的阵列输出应该有其索引均匀分布到1/2的采样率(32赫兹) ,所以我是否正确地理解,每个元素的阵列代表(32赫兹 * 1/2)/16 = 1赫兹?

  4. 为什么 FFT 输出为负值?我以为这些数值代表正弦曲线的振幅。例如,对于频率为3的余弦波,Real [3] = -1.075的输出应该意味着振幅为 -1.075。是吗?振幅怎么会是负的?

50137 次浏览

1) Look for the indices in the real array with the highest values, besides the first one (that's the DC component). You'll probably need a sample rate considerably higher than 32 Hz, and a larger window size, to get much in the way of meaningful results.

2) The second half of both arrays is the mirror of the first half. For instance, note that the last element of the real array (1.774) is the same as the second element (1.774), and the last element of the imaginary array (1.474) is the negative of the second element.

3) The maximum frequency you can pick up at a sample rate of 32 Hz is 16 Hz (Nyquist limit), so each step is 2 Hz. As noted earlier, remember that the first element is 0 Hz (i.e, the DC offset).

4) Sure, a negative amplitude makes perfect sense. It just means that the signal is "flipped" -- a standard FFT is based on a cosine, which normally has value = 1 at t = 0, so a signal which had value = -1 at time = 0 would have a negative amplitude.

  1. You should neither look for the real or imaginative part of a complex number (that what's your real and imaginary array is). Instead you want to look for the magnitude of the frequency which is defined as sqrt (real * real + imag * imag). This number will always be positive. Now all you have to search is for the maximum value (ignore the first entry in your array. That is your DC offset and carries no frequency dependent information).

  2. You get 32 real and 32 imaginary outputs because you are using a complex to complex FFT. Remember that you've converted your 32 samples into 64 values (or 32 complex values) by extending it with zero imaginary parts. This results in a symetric FFT output where the frequency result occurs twice. Once ready to use in the outputs 0 to N/2, and once mirrored in the outputs N/2 to N. In your case it's easiest to simply ignore the outputs N/2 to N. You don't need them, they are just an artifact on how you calculate your FFT.

  3. The frequency to fft-bin equation is (bin_id * freq/2) / (N/2) where freq is your sample-frequency (aka 32 Hz, and N is the size of your FFT). In your case this simplifies to 1 Hz per bin. The bins N/2 to N represent negative frequencies (strange concept, I know). For your case they don't contain any significant information because they are just a mirror of the first N/2 frequencies.

  4. Your real and imaginary parts of each bin form a complex number. It is okay if real and imaginary parts are negative while the magnitude of the frequency itself is positive (see my answer to question 1). I suggest that you read up on complex numbers. Explaining how they work (and why they are useful) exceeds what is possible to explain in a single stackoverflow-question.

Note: You may also want to read up what autocorrelation is, and how it is used to find the fundamental frequency of a signal. I have a feeling that this is what you really want.

You already have some good answers, but I'll just add that you really need to apply a window function to your time domain data prior to the FFT, otherwise you will get nasty artefacts in your spectrum, due to spectral leakage.

Note that the "most occurring frequency" can get splattered into multiple FFT bins, even with a window function. So you may have to use a longer window, multiple windows, or interpolation to better estimate the frequency of any spectral peaks.