65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 中的 Butterworth 滤波器

starIconstarIconstarIconstarIconstarIcon

5.00/5 (12投票s)

2016年4月22日

CPOL

1分钟阅读

viewsIcon

71853

本文介绍了 C# 中的低通 Butterworth 滤波器代码

引言

本文档展示了用 C# 编写的四阶零相位偏移低通巴特沃斯滤波器函数的代码。该代码由 Sam Van Wassenbergh(安特卫普大学,2007 年)最初用 Visual Basic for Applications (VBA) 编写,后被转换为 C#。 我在使用 VBA 代码的一个应用程序时,当我决定将该应用程序转换为 C# 时,发现很少有关于用 C# 编写的巴特沃斯滤波器的资源,因此我将 VBA 代码转换为 C#,并认为一篇文章对其他人可能会有所帮助。

Using the Code

函数如下所示。未经过滤的数据作为 double[] 数组传递给函数,以及秒为单位的时间步长和所需的截止频率(单位为 Hz)。 除非输入数据 indatanull,则返回 null,或者如果截止频率为 0,则返回原始数据(未经过滤),否则返回经过滤波的数据。 时间步长变量 deltaTimeinsec(即连续两个数据点之间的时间,单位为秒)用于计算采样率(时间步长的倒数)。 输入数据被准备在一个稍大的数组中(多出 4 个点 - 两端各多出 2 个点),以便真实的端点在计算中拥有邻居。 在分配变量之后,两个循环执行滤波计算的反向和正向遍历。 然后,输出数据被放回一个与原始数据大小相同的数组中以供返回。

    //--------------------------------------------------------------------------
    // This function returns the data filtered. Converted to C# 2 July 2014.
    // Original source written in VBA for Microsoft Excel, 2000 by Sam Van
    // Wassenbergh (University of Antwerp), 6 june 2007.
    //--------------------------------------------------------------------------
    public static double[] Butterworth(double[] indata, double deltaTimeinsec, double CutOff) {
        if (indata == null) return null;
        if (CutOff == 0) return indata;

        double Samplingrate = 1 / deltaTimeinsec;
        long dF2 = indata.Length - 1;        // The data range is set with dF2
        double[] Dat2 = new double[dF2 + 4]; // Array with 4 extra points front and back
        double[] data = indata; // Ptr., changes passed data

        // Copy indata to Dat2
        for (long r = 0; r < dF2; r++) {
            Dat2[2 + r] = indata[r];
        }
        Dat2[1] = Dat2[0] = indata[0];
        Dat2[dF2 + 3] = Dat2[dF2 + 2] = indata[dF2];

        const double pi = 3.14159265358979;
        double wc = Math.Tan(CutOff * pi / Samplingrate);
        double k1 = 1.414213562 * wc; // Sqrt(2) * wc
        double k2 = wc * wc;
        double a = k2 / (1 + k1 + k2);
        double b = 2 * a;
        double c = a;
        double k3 = b / k2;
        double d = -2 * a + k3;
        double e = 1 - (2 * a) - k3;

        // RECURSIVE TRIGGERS - ENABLE filter is performed (first, last points constant)
        double[] DatYt = new double[dF2 + 4];
        DatYt[1] = DatYt[0] = indata[0];
        for (long s = 2; s < dF2 + 2; s++) {
            DatYt[s] = a * Dat2[s] + b * Dat2[s - 1] + c * Dat2[s - 2]
                       + d * DatYt[s - 1] + e * DatYt[s - 2];
        }
        DatYt[dF2 + 3] = DatYt[dF2 + 2] = DatYt[dF2 + 1];

        // FORWARD filter
        double[] DatZt = new double[dF2 + 2];
        DatZt[dF2] = DatYt[dF2 + 2];
        DatZt[dF2 + 1] = DatYt[dF2 + 3];
        for (long t = -dF2 + 1; t <= 0; t++) {
            DatZt[-t] = a * DatYt[-t + 2] + b * DatYt[-t + 3] + c * DatYt[-t + 4]
                        + d * DatZt[-t + 1] + e * DatZt[-t + 2];
        }

        // Calculated points copied for return
        for (long p = 0; p < dF2; p++) {
            data[p] = DatZt[p];
        }

        return data;
    }

结论

一个四阶零相位偏移低通巴特沃斯滤波器函数被展示在 C# 语言中,它是从 Sam Van Wassenbergh 最初的 VBA 代码转换而来的。

© . All rights reserved.