【问题标题】:Mathnet Filtering cutoff frequencyMathnet 滤波截止频率
【发布时间】:2025-12-06 06:10:01
【问题描述】:

所以我一直在尝试使用 Mathnet 过滤库在 C# 中实现低通滤波器。我有一个问题,因为我不知道如何使用该方法为滤波器创建系数。有人能告诉我如何指定截止频率(它必须以每单位的样本为单位)吗? 例如,如果我希望截止频率为 400Hz,那么每单位的样本数是多少? 谢谢。

public Filter(ISampleProvider _source, long Length, int _cutoff)
    {
        source = _source;
        cutoffFrequency = _cutoff;

        float[] s = new float[Length];
        _source.Read(s, 0, (int)Length);
        Normalize(s);

        var coefficients = MathNet.Filtering.FIR.FirCoefficients.LowPass(_source.WaveFormat.SampleRate, (double)400/ ((double)source.WaveFormat.SampleRate/(double)Length), 2);
        MathNet.Filtering.FIR.OnlineFirFilter filter = new MathNet.Filtering.FIR.OnlineFirFilter(coefficients);
        double[] output = Array.ConvertAll(s, x => (double)x);

        double[] output2 = filter.ProcessSamples(output);

        output1 = new float[output2.Length];
        for (int i = 0; i < output2.Length; i++)
        {
            output1[i] = Convert.ToSingle(output2[i]);
        }

    }

我试图将我想要的频率除以信号的频率分辨率,但这样信号似乎根本没有改变。

【问题讨论】:

    标签: c# filter signal-processing mathnet-numerics


    【解决方案1】:

    我最近一直在试验这个库。下面是一个简单的例子,它设置了一个带有窗口函数的 fir 滤波器来改进它(对于 2 MSPS 输入和 125 kHz 截止频率):

                double samplingRate = 2000000;
                double cutoffFreq = 125000;
                int filterWidth = 130;
    
                var mathNetCoeffs = MathNet.Filtering.FIR.FirCoefficients.LowPass(samplingRate, cutoffFreq, filterWidth/2);
                MathNet.Filtering.Windowing.BlackmanWindow blackmanWindow = new MathNet.Filtering.Windowing.BlackmanWindow();
                blackmanWindow.Width = mathNetCoeffs.Length;
                var windowArr = blackmanWindow.CopyToArray();
                for (int i = 0; i < mathNetCoeffs.Length; i++) mathNetCoeffs[i] *= windowArr[i];
                MathNet.Filtering.FIR.OnlineFirFilter mathNetFilter = new MathNet.Filtering.FIR.OnlineFirFilter(mathNetCoeffs);
    

    窗口函数对于制作有效的过滤器非常重要。 Hamming 是另一种流行的选择,但我在这里使用 Blackman。然后通过调用 ProcessSample 或 ProcessSamples 来使用过滤器:

    double mathNetFiltered = mathNetFilter.ProcessSample(value);

    还要注意,实际的过滤器宽度将为 filterWidth + 1。您希望实际的过滤器宽度为奇数(为了获得良好的过滤器对称性),因此将 filterWidth 设置为偶数值。

    【讨论】: