假设如下采样信号
int sampleCount = 10000;
var time = new double[sampleCount];
var xs = new double[sampleCount];
var ys_real = new double[sampleCount];
var ys_img = new double[sampleCount];
//10KHz采样,生成实部数据 和 X轴数据
for(int i=0;i< sampleCount; i++)
{
time[i] = i;
var x= ((double)i) / ((double)sampleCount);
xs[i] = x;
ys_real[i] =
0.5 * Math.Sin(2 * Math.PI * 10 * x ) //叠加10Hz信号
+ 0.2 * Math.Sin(2 * Math.PI * 80 * x + Math.PI / 4) //叠加80Hz信号
+ 0.05 * Math.Sin(2 * Math.PI * 200 * x + Math.PI / 6)//叠加200Hz信号
+ 0.07 * Math.Sin(2 * Math.PI * 400 * x + Math.PI / 8)//叠加400Hz信号
+ 10;////叠加直流分量
}
//绘制10K个点
_timePlot.Plot.Clear();
_timePlot.Plot.Add.ScatterLine(xs.ToArray(), ys_real.ToArray());
_timePlot.Plot.Axes.AutoScale();
_timePlot.Refresh();
//傅里叶向前变换FFT default选型需要导入2的N次方数据 这里选Matlab不需要2的幂数
Fourier.Forward(ys_real, ys_img, MathNet.Numerics.IntegralTransforms.FourierOptions.Matlab);
var result = new double[ys_real.Length];
for (int i = 0; i < result.Count(); i++)
{
var temp = new Complex32((float)ys_real[i], (float)ys_img[i]);
result[i] = temp.Magnitude;//复数的模
//归一化
//0HZ的直流分量 =振幅/采样点数N
if (i == 0) { result[i] = result[i] / sampleCount; }
else
{
//其他==振幅/采样点数N/2
result[i] = result[i] / (sampleCount / 2);
}
}
//Scottplot绘制FFT波形
_fftPlot.Plot.Clear();
_fftPlot.Plot.Add.ScatterLine(time.Take(sampleCount/2).ToArray(), result.Take(sampleCount/2).ToArray());
_fftPlot.Plot.Axes.AutoScale();
_fftPlot.Refresh();
频率和整幅都可以匹配
//去除高频部分大于70的频率信号
for (int i = 0; i < ys_real.Length; i++)
{
if (i > 70)
{
ys_real[i] = 0;
ys_img[i] = 0;
}
}
//反傅里叶变化
Fourier.Inverse(ys_real, ys_img, FourierOptions.Matlab);
//绘制过滤过的波形 图上黄色波形
_timePlot.Plot.Add.ScatterLine(xs.ToArray(), ys_real.ToArray());
_timePlot.Plot.Axes.AutoScale();
_timePlot.Refresh();
只剩下0.5 * Math.Sin(2 * Math.PI * 10 * x )+ 10;的时域信号
//TIME->FFT-- > FILTER(noise) - IFFT - TIME
用途:
- 计算信号的频域信号分析特征
- 对信号进行预处理,剔除高频毛刺部分