我目前正在实施信号频谱图。
我的输入数据:1.051,1.365,1.837,2.334,2.486,2.688,2.878,2.579,2.11,1.605,0.936,0.73,1.036,1.336,1.796,2.043,2.462,2.935,2.892,2.609,2.151,1.641,0.961, 0.738,0.767,1.303,1.503,2.004,2.435,2.931,2.908,2.641,1.935,1.423,0.988,0.747,0.755,1.018,1.465,1.966,2.662,2.919,2.918,2.669,1.976,1.462,1.017,0.757, 0.746,0.989,1.426,1.927,2.637,2.908,2.927,2.441,2.015,1.501,1.302,1.025,0.739,0.962,1.644,2.144,2.605,2.895,2.935,2.467,2.304,1.797,1.331,1.039,0.732, 0.936,1.608,2.103,2.575,2.88,2.688,2.493,2.343,1.835,1.365,1.054,0.725,0.913,1.568,2.067,2.288,2.867,2.69,2.516,2.379,1.877,1.397,1.072,0.721,1.144, 1.277、1.77
您可以在我的屏幕截图上看到此数据。是底图。它仅包含100点。并且不可能增加它的数量。
输入信号频率为1000 Hz。而且可以更改。
我使用FFTW来获取频谱。
输入信号频率为1000 Hz。在顶部的图表中,它仅显示约200 Hz。那是主要问题。我想也许我的代码是错误的或积分不足。
我的数据分析代码:
QVectorDouble points(100);
points = this->reader->ReadCOM(100);
double timePassed = this->reader->timePassed;
unsigned int n = points.count();
double timeShift = timePassed / n;
QVectorDouble signalX(n), signalY(n);
for (unsigned int i = 0; i < n; i++)
{
signalX[i] = i*timeShift; // x goes from 0 to timePassed to take points amount
signalY[i] = points[i];
}
fftw::maxthreads = get_max_threads();
unsigned int np = n / 2 + 1;
size_t align = sizeof(Complex);
array1<Complex> F(np, align);
array1<double> f(n, align);
rcfft1d Forward(n, f, F);
for(unsigned int i = 0; i < n; i++) {
f[i] = points[i];
}
Forward.fft(f, F);
QVectorDouble spectrX(np), spectrY(np);
for (int i = 0; i < np; i++)
{
spectrX[i] = i * 20; //multiply by 20 because np is (100/2 + 1) and chart maximum xOrigin is 1000
spectrY[i] = abs(F[i]) / np;
}
最佳答案
以下是一些不太正确的事情:
在时域图中,以1000Hz的采样率100个点应为您提供0.1秒的总持续时间。假设signalX
为0.1秒,则用于timePassed
的公式是正确的。您应该研究为什么该变量实际上是大约0.4秒。
由于您在0.1秒内有8个完整的周期,因此应该获得8 * 1 / 0.1 = 80Hz的峰值频率。因此,显然,声谱图的x轴缩放存在问题。更具体地说,应将频率增量设置为1000/np
或使用np == 10
设置为10Hz。这将生成一个高达500Hz的图,该图是采样率的一半(与Nyquist定理一致),其中峰值将以正确的80Hz频率出现。