我正在尝试使用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)波并移除我不感兴趣的组件,我可以以预期的振幅重建波并完全清除噪声。
答案 0 :(得分:1)
如果您的信号频率为5Hz,噪音为30-70Hz,那么您根本不需要带通滤波器,低频通道也可以。此外,预计会有一些衰减,虽然在你的情况下有点过分,原因是...... 你的过滤器太窄。使用具有截止频率的低通,例如10Hz,或者具有0-10Hz的低/高截止的带通。下面的示例显示了这些选项之间的比较。请注意,毫无疑问,具有相同10Hz带宽的低通和带通滤波器与预期完全匹配。
//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