为什么我的 FFT 频谱的第二个分量的幅度总是最大的?

信息处理 fft 频谱 频率 采样 零填充
2022-02-08 06:47:42

在使用 FFT 时,我对当前的实验设置有一个奇怪的情况。我正在处理拍频(中频输出)并使用标准 FFT 算法(复杂到复杂)。我的采样数据是实值的,所以我创建了一个双倍大小的数组,其中包含交替的实值和复值(复值设置为零),如下图所示。我使用的 FFT 的特定实现 ( LomontFFT ) 需要解决缺乏复值类型处理的问题。

在此处输入图像描述

这里 ADC 对 400 个数据点进行采样,然后在 Hanning 之后对 112 位进行零填充以生成 512 个数据点。

这是我编写的代码(C#):

public void fftElavualtion (double[] adcValues)
{
        int N = 512;
        double Fs = 195312.5;
        double[] data_sample = Enumerable.Repeat(0.0, N).ToArray();
        double[] data_sampleHanned = new double[adcValues.Length];
        double[] fftData = new double[N * 2];
        double[] magnitude = new double[N];
        double max_magnitude = double.NegativeInfinity;
        int max_index = -1;
        double fundamentalFrequency;

        data_sampleHanned = HanningWindow(adcValues);

        Array.Copy(data_sampleHanned, data_sample, data_sampleHanned.Length);

        for (int i = 0; i <= (N - 1); i++)
        {
            fftData[2 * i] = data_sample[i];
            fftData[(2 * i) + 1] = 0;
        }

        var fftMethod = new Lomont.LomontFFT();
        fftMethod.FFT(fftData, true);

        for (int y = 0; y <= (N - 1); y++)
        {
            double re = fftData[2 * y];
            double im = fftData[2 * y + 1];
            magnitude[y] = Math.Sqrt(re * re + im * im);
        }

        for (int k = 1; k <= (N - 1); k++)
        {
            if (magnitude[k] > max_magnitude)
            {
                max_magnitude = magnitude[k];
                max_index = k;
            }
        }

        fundamentalFrequency = max_index * Fs / N;

        textBoxFundaFreq.Text = "Freq = " + fundamentalFrequency.ToString();
        for (int x = 1; x < N; x++)
        {
            this.chart2.Series[0].Points.AddXY(x, magnitude[x]);
        }
    }

问题是:

  1. 每个频率仓代表(采样率)/(采样总数)的带宽,因此为 200,000/512。即,大约 390 赫兹。这对垃圾箱来说太高了吗?如果是这样,我该如何管理,因为我只能有 400 个样本并且也不能更改采样率(系统约束)。零填充有改善吗?

  2. 为了找到基频,我正在定位最高幅度的索引(max_index)并将其与每个 bin 的 badwidth 相乘。这为所有试验产生了相同的频率,因为无论将什么信号馈送到处理系统,第二个数量级总是很高。

总是第二个 bin 具有最高能量或最高幅度的可能原因是什么?

注意:我忽略了 FFT 中出现问题的情况,因为 LomontFFT 是可信的。信息:(使用 ADC 采样的双值示例 - CSV 中的 400 个数据点)

 2047.5,2063.88,2082.99,2099.37,2115.75,2140.32,2149.875,2156.7,2167.62,2178.54,2194.92,2205.84,2214.03,2222.22,2231.775,2238.6,2184,2115.75,2061.15,2013.375,1951.95,1897.35,1835.925,1774.5,1842.75,1911,2033.85,2115.75,2184,2293.2,2375.1,2457,2375.1,2252.25,2129.4,1992.9,1842.75,1706.25,1610.7,1501.5,1638,1777.23,1919.19,2059.785,2199.015,2336.88,2476.11,2613.975,2457,2297.295,2170.35,1904.175,1636.635,1449.63,1365,1236.69,1569.75,1835.925,1979.25,2080.26,2306.85,2457,2605.785,2852.85,2730,2661.75,2530.71,2429.7,2306.85,2182.635,2115.75,2047.5,1911,1774.5,1638,1501.5,1365,1228.5,1092,955.5,1092,1228.5,1365,1501.5,1638,1774.5,1911,2047.5,2197.65,2347.8,2497.95,2648.1,2798.25,2948.4,3091.725,3228.225,3084.9,2934.75,2784.6,2634.45,2484.3,2334.15,2190.825,2047.5,1774.5,1528.8,1228.5,1092,962.325,832.65,709.8,655.2,791.7,941.85,1090.635,1283.1,1528.8,1760.85,1911,2047.5,2293.2,2455.635,2593.5,2852.85,3016.65,3289.65,3412.5,3549,3412.5,3262.35,3001.635,2728.635,2455.635,2319.135,2115.75,2047.5,1794.975,1542.45,1365,1078.35,941.85,764.4,477.75,273,526.4805,682.5,832.65,1090.635,1337.7,1501.5,1909.635,2047.5,2184,2443.35,2661.75,2989.35,3274.635,3562.65,3701.88,3842.475,3685.5,3535.35,3207.75,2934.75,2730,2525.25,2306.85,2047.5,1842.75,1490.58,1119.3,982.8,709.8,436.8,163.8,40.95,204.75,436.8,764.4,1078.35,1300.845,1610.7,1883.7,2047.5,2320.5,2613.975,2907.45,3194.1,3480.75,3753.75,3890.25,4093.635,3549,2866.5,2184,1842.75,1706.25,1228.5,682.5,1.092,271.635,464.1,750.75,955.5,1228.5,1569.75,1842.75,2047.5,2320.5,2593.5,2866.5,3139.5,3412.5,3685.5,3822,3999.45,3822,3685.5,3412.5,3139.5,2866.5,2593.5,2320.5,2047.5,1774.5,1501.5,1228.5,955.5,682.5,518.7,313.95,135.135,313.95,518.7,682.5,955.5,1228.5,1501.5,1774.5,2047.5,2252.25,2525.25,2757.3,3057.6,3344.25,3494.4,3671.85,3842.475,3671.85,3494.4,3344.25,3057.6,2757.3,2525.25,2252.25,2047.5,1774.5,1501.5,1228.5,955.5,819,696.15,477.75,375.375,477.75,696.15,819,955.5,1228.5,1501.5,1774.5,2047.5,2320.5,2593.5,2866.5,3016.65,3139.5,3276,3426.15,3617.25,3426.15,3276,3139.5,3016.65,2866.5,2593.5,2320.5,2047.5,1829.1,1556.1,1255.8,1146.6,955.5,873.6,764.4,679.77,846.3,955.5,1201.2,1351.35,1501.5,1706.25,1842.75,2047.5,2184,2347.8,2525.25,2702.7,2866.5,3003,3139.5,3288.285,3139.5,3003,2866.5,2702.7,2525.25,2347.8,2184,2047.5,1911,1774.5,1638,1501.5,1365,1228.5,1092,1044.225,1092,1228.5,1365,1501.5,1638,1774.5,1911,2046.135,2184,2317.77,2454.27,2525.25,2593.5,2689.05,2852.85,2921.1,2852.85,2689.05,2593.5,2525.25,2454.27,2317.77,2184,2047.5,1965.6,1815.45,1733.55,1636.635,1474.2,1228.5,1351.35,1481.025,1562.925,1644.825,1726.725,1808.625,1890.525,1945.125,2027.025,2047.5,2095.275,2145.78,2197.65,2245.425,2293.2,2327.325,2361.45,2388.75,2361.45,2327.325,2293.2,2245.425,2197.65,2145.78,2095.275,2047.5,2020.2,1992.9,1965.6,1938.3,1911,1883.7,1829.1,1774.5,1842.75,1911,1979.25,2047.5,2115.75,2184,2115.75,2047.5
1个回答

好的,所以我尝试执行相同的计算(但请原谅我,我是用 Python 做的,但它应该是可读的)。

import numpy as np                    # Linear algebra module
from matplotlib import pyplot as plt  # Plot module
from scipy import signal              # One common DSP module

# Spectral density calculation
data = np.array([2047.5,2063.88,2082.99,2099.37,2115.75,2140.32,2149.875,2156.7,2167.62,2178.54,2194.92,2205.84,2214.03,2222.22,2231.775,2238.6,2184,2115.75,2061.15,2013.375,1951.95,1897.35,1835.925,1774.5,1842.75,1911,2033.85,2115.75,2184,2293.2,2375.1,2457,2375.1,2252.25,2129.4,1992.9,1842.75,1706.25,1610.7,1501.5,1638,1777.23,1919.19,2059.785,2199.015,2336.88,2476.11,2613.975,2457,2297.295,2170.35,1904.175,1636.635,1449.63,1365,1236.69,1569.75,1835.925,1979.25,2080.26,2306.85,2457,2605.785,2852.85,2730,2661.75,2530.71,2429.7,2306.85,2182.635,2115.75,2047.5,1911,1774.5,1638,1501.5,1365,1228.5,1092,955.5,1092,1228.5,1365,1501.5,1638,1774.5,1911,2047.5,2197.65,2347.8,2497.95,2648.1,2798.25,2948.4,3091.725,3228.225,3084.9,2934.75,2784.6,2634.45,2484.3,2334.15,2190.825,2047.5,1774.5,1528.8,1228.5,1092,962.325,832.65,709.8,655.2,791.7,941.85,1090.635,1283.1,1528.8,1760.85,1911,2047.5,2293.2,2455.635,2593.5,2852.85,3016.65,3289.65,3412.5,3549,3412.5,3262.35,3001.635,2728.635,2455.635,2319.135,2115.75,2047.5,1794.975,1542.45,1365,1078.35,941.85,764.4,477.75,273,526.4805,682.5,832.65,1090.635,1337.7,1501.5,1909.635,2047.5,2184,2443.35,2661.75,2989.35,3274.635,3562.65,3701.88,3842.475,3685.5,3535.35,3207.75,2934.75,2730,2525.25,2306.85,2047.5,1842.75,1490.58,1119.3,982.8,709.8,436.8,163.8,40.95,204.75,436.8,764.4,1078.35,1300.845,1610.7,1883.7,2047.5,2320.5,2613.975,2907.45,3194.1,3480.75,3753.75,3890.25,4093.635,3549,2866.5,2184,1842.75,1706.25,1228.5,682.5,1.092,271.635,464.1,750.75,955.5,1228.5,1569.75,1842.75,2047.5,2320.5,2593.5,2866.5,3139.5,3412.5,3685.5,3822,3999.45,3822,3685.5,3412.5,3139.5,2866.5,2593.5,2320.5,2047.5,1774.5,1501.5,1228.5,955.5,682.5,518.7,313.95,135.135,313.95,518.7,682.5,955.5,1228.5,1501.5,1774.5,2047.5,2252.25,2525.25,2757.3,3057.6,3344.25,3494.4,3671.85,3842.475,3671.85,3494.4,3344.25,3057.6,2757.3,2525.25,2252.25,2047.5,1774.5,1501.5,1228.5,955.5,819,696.15,477.75,375.375,477.75,696.15,819,955.5,1228.5,1501.5,1774.5,2047.5,2320.5,2593.5,2866.5,3016.65,3139.5,3276,3426.15,3617.25,3426.15,3276,3139.5,3016.65,2866.5,2593.5,2320.5,2047.5,1829.1,1556.1,1255.8,1146.6,955.5,873.6,764.4,679.77,846.3,955.5,1201.2,1351.35,1501.5,1706.25,1842.75,2047.5,2184,2347.8,2525.25,2702.7,2866.5,3003,3139.5,3288.285,3139.5,3003,2866.5,2702.7,2525.25,2347.8,2184,2047.5,1911,1774.5,1638,1501.5,1365,1228.5,1092,1044.225,1092,1228.5,1365,1501.5,1638,1774.5,1911,2046.135,2184,2317.77,2454.27,2525.25,2593.5,2689.05,2852.85,2921.1,2852.85,2689.05,2593.5,2525.25,2454.27,2317.77,2184,2047.5,1965.6,1815.45,1733.55,1636.635,1474.2,1228.5,1351.35,1481.025,1562.925,1644.825,1726.725,1808.625,1890.525,1945.125,2027.025,2047.5,2095.275,2145.78,2197.65,2245.425,2293.2,2327.325,2361.45,2388.75,2361.45,2327.325,2293.2,2245.425,2197.65,2145.78,2095.275,2047.5,2020.2,1992.9,1965.6,1938.3,1911,1883.7,1829.1,1774.5,1842.75,1911,1979.25,2047.5,2115.75,2184,2115.75,2047.5])
freq, spectrum = signal.periodogram(data, window="hann", fs=195312.5, nfft=1024) # using Hann window and padding with 1024 - 400 zeros

# Plotting
plt.figure()
plt.xlabel("Frequency")
plt.ylabel("Magnitude")
plt.title("Spectral density")
plt.plot(freq, spectrum)

## zoom and plot points
plt.figure()
plt.xlim([0, 10000])
plt.xlabel("Frequency")
plt.ylabel("Magnitude")
plt.title("Spectral density")
plt.plot(freq, spectrum)
plt.plot(freq, spectrum, "ko")

plt.show()

我懂了:

在此处输入图像描述

在此处输入图像描述

那么第一件事:你应该使用,RealFFT因为你的输入是实值的。N样品中,你得到N//2+1样品。这更快,更不容易出错。您还需要消除所有地方的冗余:这是一团糟。


就您的问题而言,您忘记了删除显然在那里泄漏的 DC 组件(又名detrend -ing)。删除数据的平均值应该足以摆脱它。