MathNet.Filtering带通参数

时间:2017-10-13 12:20:09

标签: c# mathnet mathdotnet mathnet-filtering

我正在尝试使用MathNet滤波器对信号应用带通滤波器;我准确地使用MathNet.Filtering.OnlineFiter.CreateBandpass(..)方法。

问题是,我没有得到预期的结果,我对方法的参数感到困惑。我有一个以1Khz采样的信号,我想要移除4到6 Hz范围之外的所有信号。调用方法CreateBandpass(..)的正确方法是什么?

修改

这是代码,如评论所示:

OnlineFilter bandPass = CreateBandpass(ImpulseResponse.Finite, samplingRate, 3, 7);
postProcessedData = bandPass.ProcessSamples(preProcessedData);

光源是5 Hz的正弦波,有一些相对较高的频率噪声(如30-70 hz);信号的幅度约为20个峰 - 峰值,以0为中心(所以-10到+10)。经滤波的信号是5Hz的正弦波,没有噪声,振幅峰峰值为2.1

P.S。

顺便说一下,测试波也会发生这种情况。如果a产生纯正弦波(无论频率如何)并围绕其频率对其进行滤波,我将获得相同频率和完全无关幅度的正弦波。另一方面,如果我使用FFT(仍然使用MathNet)波并移除我不感兴趣的组件,我可以以预期的振幅重建波并完全清除噪声。

1 个答案:

答案 0 :(得分:1)

如果您的信号频率为5Hz,噪音为30-70Hz,那么您根本不需要带通滤波器,低频通道也可以。此外,预计会有一些衰减,虽然在你的情况下有点过分,原因是...... 你的过滤器太窄。使用具有截止频率的低通,例如10Hz,或者具有0-10Hz的低/高截止的带通。下面的示例显示了这些选项之间的比较。请注意,毫无疑问,具有相同10Hz带宽的低通和带通滤波器与预期完全匹配。

enter image description here

    //signal + noise
    double fs = 1000; //sampling rate
    double fw = 5; //signal frequency
    double fn = 50; //noise frequency
    double n = 5; //number of periods to show
    double A = 10; //signal amplitude
    double N = 1; //noise amplitude
    int size = (int)(n * fs / fw); //sample size

    var t = Enumerable.Range(1, size).Select(p => p * 1 / fs).ToArray();
    var y = t.Select(p => (A * Math.Sin(2 * pi * fw * p)) + (N * Math.Sin(2 * pi * fn * p))).ToArray(); //Original

    //lowpass filter
    double fc = 10; //cutoff frequency
    var lowpass = OnlineFirFilter.CreateLowpass(ImpulseResponse.Finite, fs, fc);

    //bandpass filter
    double fc1 = 0; //low cutoff frequency
    double fc2 = 10; //high cutoff frequency
    var bandpass = OnlineFirFilter.CreateBandpass(ImpulseResponse.Finite, fs, fc1, fc2);

    //narrow bandpass filter
    fc1 = 3; //low cutoff frequency
    fc2 = 7; //high cutoff frequency
    var bandpassnarrow = OnlineFirFilter.CreateBandpass(ImpulseResponse.Finite, fs, fc1, fc2);

    double[] yf1 = lowpass.ProcessSamples(y); //Lowpass
    double[] yf2 = bandpass.ProcessSamples(y); //Bandpass
    double[] yf3 = bandpassnarrow.ProcessSamples(y); //Bandpass Narrow