C#中的低通和高通滤波器

我需要用c#编写的低通和高通滤波器。 我有这个过滤过程的双数组。 我想如果我尝试将matlab Butterworth和Chebyshev算法转换为c#,那就更容易了。 但我在互联网上找不到butter.m和Chebyshev算法的代码,我不想在我的计算机上设置matlab和信号处理工具箱。 你能提供这些代码吗? 谢谢..

http://www.musicdsp.org/archive.php?classid=3#38

我在sEMG分析器软件中按照以下半模式实现了filter,效果很好。

public class FilterButterworth { ///  /// rez amount, from sqrt(2) to ~ 0.1 ///  private readonly float resonance; private readonly float frequency; private readonly int sampleRate; private readonly PassType passType; private readonly float c, a1, a2, a3, b1, b2; ///  /// Array of input values, latest are in front ///  private float[] inputHistory = new float[2]; ///  /// Array of output values, latest are in front ///  private float[] outputHistory = new float[3]; public FilterButterworth(float frequency, int sampleRate, PassType passType, float resonance) { this.resonance = resonance; this.frequency = frequency; this.sampleRate = sampleRate; this.passType = passType; switch (passType) { case PassType.Lowpass: c = 1.0f / (float)Math.Tan(Math.PI * frequency / sampleRate); a1 = 1.0f / (1.0f + resonance * c + c * c); a2 = 2f * a1; a3 = a1; b1 = 2.0f * (1.0f - c * c) * a1; b2 = (1.0f - resonance * c + c * c) * a1; break; case PassType.Highpass: c = (float)Math.Tan(Math.PI * frequency / sampleRate); a1 = 1.0f / (1.0f + resonance * c + c * c); a2 = -2f * a1; a3 = a1; b1 = 2.0f * (c * c - 1.0f) * a1; b2 = (1.0f - resonance * c + c * c) * a1; break; } } public enum PassType { Highpass, Lowpass, } public void Update(float newInput) { float newOutput = a1 * newInput + a2 * this.inputHistory[0] + a3 * this.inputHistory[1] - b1 * this.outputHistory[0] - b2 * this.outputHistory[1]; this.inputHistory[1] = this.inputHistory[0]; this.inputHistory[0] = newInput; this.outputHistory[2] = this.outputHistory[1]; this.outputHistory[1] = this.outputHistory[0]; this.outputHistory[0] = newOutput; } public float Value { get { return this.outputHistory[0]; } } } 

请注意,此滤波器是为音频DSP目的而创建的。 要创建干净的输出,您需要将共振设置为sqrt(2)

我发现这个看起来很有前途的在线工具: 交互式数字滤波器设计:Butterworth / Bessel / Chebyshev滤波器

您只需输入您的要求:

  • filter设计:Butterworth / Bessel / Chebyshev
  • 滤波器类型:低通/高通/带通/带阻
  • 过滤订单
  • 转角频率/频率

单击“提交”,它将计算以下信息:

  • 增益,极点,零点
  • 递归关系
  • 实现递归关系的C代码
  • 幅度,相位,脉冲和阶跃响应的图

您可以直接从递归关系中实现C#中的filter。

如果您只需要一些常量filter,那么您就完成了。 但是,如果您需要能够在运行时调整filter参数,则需要执行更多操作。 幸运的是,教授提供了他的工具的源代码 ,应该可以转换为C#。

看看OpenCV / EmguCV 。

它们都是开源的,因此如果您正在寻找的话,您可以拥有“代码”。

您可以在另一个stackoverflow问题上查看Butterworth Low Passfilter的源代码。 正如其他人所指出的那样,EmguCV附带了大量有效编码的filter,开箱即用

以下是使用NMath的fft的butterworth和chebyshevfilter的一些c#代码示例。

这里有一个它有很多模式,HP LP BP峰值,等等,它是一个BiQuad或许是2极静态滤波器的东西,它是一个特殊的滤波器并具有某种数字结果: https:// github的.com / filoe / cscore /斑点/主/ CSCore / DSP / BiQuad.cs

  /* * These implementations are based on http://www.earlevel.com/main/2011/01/02/biquad-formulas/ */ using System; namespace CSCore.DSP { ///  /// Represents a biquad-filter. ///  public abstract class BiQuad { ///  /// The a0 value. ///  protected double A0; ///  /// The a1 value. ///  protected double A1; ///  /// The a2 value. ///  protected double A2; ///  /// The b1 value. ///  protected double B1; ///  /// The b2 value. ///  protected double B2; ///  /// The q value. ///  private double _q; ///  /// The gain value in dB. ///  private double _gainDB; ///  /// The z1 value. ///  protected double Z1; ///  /// The z2 value. ///  protected double Z2; private double _frequency; ///  /// Gets or sets the frequency. ///  /// value;The samplerate has to be bigger than 2 * frequency. public double Frequency { get { return _frequency; } set { if (SampleRate < value * 2) { throw new ArgumentOutOfRangeException("value", "The samplerate has to be bigger than 2 * frequency."); } _frequency = value; CalculateBiQuadCoefficients(); } } ///  /// Gets the sample rate. ///  public int SampleRate { get; private set; } ///  /// The q value. ///  public double Q { get { return _q; } set { if (value <= 0) { throw new ArgumentOutOfRangeException("value"); } _q = value; CalculateBiQuadCoefficients(); } } ///  /// Gets or sets the gain value in dB. ///  public double GainDB { get { return _gainDB; } set { _gainDB = value; CalculateBiQuadCoefficients(); } } ///  /// Initializes a new instance of the  class. ///  /// The sample rate. /// The frequency. ///  /// sampleRate /// or /// frequency /// or /// q ///  protected BiQuad(int sampleRate, double frequency) : this(sampleRate, frequency, 1.0 / Math.Sqrt(2)) { } ///  /// Initializes a new instance of the  class. ///  /// The sample rate. /// The frequency. /// The q. ///  /// sampleRate /// or /// frequency /// or /// q ///  protected BiQuad(int sampleRate, double frequency, double q) { if (sampleRate <= 0) throw new ArgumentOutOfRangeException("sampleRate"); if (frequency <= 0) throw new ArgumentOutOfRangeException("frequency"); if (q <= 0) throw new ArgumentOutOfRangeException("q"); SampleRate = sampleRate; Frequency = frequency; Q = q; GainDB = 6; } ///  /// Processes a single  sample and returns the result. ///  /// The input sample to process. /// The result of the processed  sample. public float Process(float input) { double o = input * A0 + Z1; Z1 = input * A1 + Z2 - B1 * o; Z2 = input * A2 - B2 * o; return (float)o; } ///  /// Processes multiple  samples. ///  /// The input samples to process. /// The result of the calculation gets stored within the  array. public void Process(float[] input) { for (int i = 0; i < input.Length; i++) { input[i] = Process(input[i]); } } ///  /// Calculates all coefficients. ///  protected abstract void CalculateBiQuadCoefficients(); } ///  /// Used to apply a lowpass-filter to a signal. ///  public class LowpassFilter : BiQuad { ///  /// Initializes a new instance of the  class. ///  /// The sample rate. /// The filter's corner frequency. public LowpassFilter(int sampleRate, double frequency) : base(sampleRate, frequency) { } ///  /// Calculates all coefficients. ///  protected override void CalculateBiQuadCoefficients() { double k = Math.Tan(Math.PI * Frequency / SampleRate); var norm = 1 / (1 + k / Q + k * k); A0 = k * k * norm; A1 = 2 * A0; A2 = A0; B1 = 2 * (k * k - 1) * norm; B2 = (1 - k / Q + k * k) * norm; } } ///  /// Used to apply a highpass-filter to a signal. ///  public class HighpassFilter : BiQuad { private int p1; private double p2; ///  /// Initializes a new instance of the  class. ///  /// The sample rate. /// The filter's corner frequency. public HighpassFilter(int sampleRate, double frequency) : base(sampleRate, frequency) { } ///  /// Calculates all coefficients. ///  protected override void CalculateBiQuadCoefficients() { double k = Math.Tan(Math.PI * Frequency / SampleRate); var norm = 1 / (1 + k / Q + k * k); A0 = 1 * norm; A1 = -2 * A0; A2 = A0; B1 = 2 * (k * k - 1) * norm; B2 = (1 - k / Q + k * k) * norm; } } ///  /// Used to apply a bandpass-filter to a signal. ///  public class BandpassFilter : BiQuad { ///  /// Initializes a new instance of the  class. ///  /// The sample rate. /// The filter's corner frequency. public BandpassFilter(int sampleRate, double frequency) : base(sampleRate, frequency) { } ///  /// Calculates all coefficients. ///  protected override void CalculateBiQuadCoefficients() { double k = Math.Tan(Math.PI * Frequency / SampleRate); double norm = 1 / (1 + k / Q + k * k); A0 = k / Q * norm; A1 = 0; A2 = -A0; B1 = 2 * (k * k - 1) * norm; B2 = (1 - k / Q + k * k) * norm; } } ///  /// Used to apply a notch-filter to a signal. ///  public class NotchFilter : BiQuad { ///  /// Initializes a new instance of the  class. ///  /// The sample rate. /// The filter's corner frequency. public NotchFilter(int sampleRate, double frequency) : base(sampleRate, frequency) { } ///  /// Calculates all coefficients. ///  protected override void CalculateBiQuadCoefficients() { double k = Math.Tan(Math.PI * Frequency / SampleRate); double norm = 1 / (1 + k / Q + k * k); A0 = (1 + k * k) * norm; A1 = 2 * (k * k - 1) * norm; A2 = A0; B1 = A1; B2 = (1 - k / Q + k * k) * norm; } } ///  /// Used to apply a lowshelf-filter to a signal. ///  public class LowShelfFilter : BiQuad { ///  /// Initializes a new instance of the  class. ///  /// The sample rate. /// The filter's corner frequency. /// Gain value in dB. public LowShelfFilter(int sampleRate, double frequency, double gainDB) : base(sampleRate, frequency) { GainDB = gainDB; } ///  /// Calculates all coefficients. ///  protected override void CalculateBiQuadCoefficients() { const double sqrt2 = 1.4142135623730951; double k = Math.Tan(Math.PI * Frequency / SampleRate); double v = Math.Pow(10, Math.Abs(GainDB) / 20.0); double norm; if (GainDB >= 0) { // boost norm = 1 / (1 + sqrt2 * k + k * k); A0 = (1 + Math.Sqrt(2 * v) * k + v * k * k) * norm; A1 = 2 * (v * k * k - 1) * norm; A2 = (1 - Math.Sqrt(2 * v) * k + v * k * k) * norm; B1 = 2 * (k * k - 1) * norm; B2 = (1 - sqrt2 * k + k * k) * norm; } else { // cut norm = 1 / (1 + Math.Sqrt(2 * v) * k + v * k * k); A0 = (1 + sqrt2 * k + k * k) * norm; A1 = 2 * (k * k - 1) * norm; A2 = (1 - sqrt2 * k + k * k) * norm; B1 = 2 * (v * k * k - 1) * norm; B2 = (1 - Math.Sqrt(2 * v) * k + v * k * k) * norm; } } } ///  /// Used to apply a highshelf-filter to a signal. ///  public class HighShelfFilter : BiQuad { ///  /// Initializes a new instance of the  class. ///  /// The sample rate. /// The filter's corner frequency. /// Gain value in dB. public HighShelfFilter(int sampleRate, double frequency, double gainDB) : base(sampleRate, frequency) { GainDB = gainDB; } ///  /// Calculates all coefficients. ///  protected override void CalculateBiQuadCoefficients() { const double sqrt2 = 1.4142135623730951; double k = Math.Tan(Math.PI * Frequency / SampleRate); double v = Math.Pow(10, Math.Abs(GainDB) / 20.0); double norm; if (GainDB >= 0) { // boost norm = 1 / (1 + sqrt2 * k + k * k); A0 = (v + Math.Sqrt(2 * v) * k + k * k) * norm; A1 = 2 * (k * k - v) * norm; A2 = (v - Math.Sqrt(2 * v) * k + k * k) * norm; B1 = 2 * (k * k - 1) * norm; B2 = (1 - sqrt2 * k + k * k) * norm; } else { // cut norm = 1 / (v + Math.Sqrt(2 * v) * k + k * k); A0 = (1 + sqrt2 * k + k * k) * norm; A1 = 2 * (k * k - 1) * norm; A2 = (1 - sqrt2 * k + k * k) * norm; B1 = 2 * (k * k - v) * norm; B2 = (v - Math.Sqrt(2 * v) * k + k * k) * norm; } } } ///  /// Used to apply an peak-filter to a signal. ///  public class PeakFilter : BiQuad { ///  /// Gets or sets the bandwidth. ///  public double BandWidth { get { return Q; } set { if (value <= 0) throw new ArgumentOutOfRangeException("value"); Q = value; } } ///  /// Initializes a new instance of the  class. ///  /// The sampleRate of the audio data to process. /// The center frequency to adjust. /// The bandWidth. /// The gain value in dB. public PeakFilter(int sampleRate, double frequency, double bandWidth, double peakGainDB) : base(sampleRate, frequency, bandWidth) { GainDB = peakGainDB; } ///  /// Calculates all coefficients. ///  protected override void CalculateBiQuadCoefficients() { double norm; double v = Math.Pow(10, Math.Abs(GainDB) / 20.0); double k = Math.Tan(Math.PI * Frequency / SampleRate); double q = Q; if (GainDB >= 0) //boost { norm = 1 / (1 + 1 / q * k + k * k); A0 = (1 + v / q * k + k * k) * norm; A1 = 2 * (k * k - 1) * norm; A2 = (1 - v / q * k + k * k) * norm; B1 = A1; B2 = (1 - 1 / q * k + k * k) * norm; } else //cut { norm = 1 / (1 + v / q * k + k * k); A0 = (1 + 1 / q * k + k * k) * norm; A1 = 2 * (k * k - 1) * norm; A2 = (1 - 1 / q * k + k * k) * norm; B1 = A1; B2 = (1 - v / q * k + k * k) * norm; } } } }