我需要用c#編寫的低通和高通濾波器。我有這個過濾器過程的雙數組。我想如果我嘗試將matlab Butterworth和Chebyshev算法轉換爲c#,它會更容易。但是我無法在互聯網上找到butter.m和Chebyshev算法的代碼,我也不想將matlab和信號處理工具箱設置到我的電腦中。你能提供那些代碼嗎?謝謝..C中的低通和高通濾波器#
回答
我發現這個在線工具,看起來很有希望:Interactive Digital Filter Design: Butterworth/Bessel/Chebyshev Filters
你只需輸入你的需求:
- 濾波器設計:北海/貝塞爾/切比雪夫
- 濾波器類型:低通/高通/帶通/ Bandstop
- 濾波器次序
- 角頻率/頻率
點擊提交,並計算了以下信息:
- 收益,極點,零點
- 遞推關係
- C代碼實現的遞推關係的幅度,相位,衝動
- 情節和一步響應
您可以直接從循環關係實現C#中的過濾器。
如果您只需要幾個常量過濾器,就完成了。但是,如果您需要能夠在運行時調整過濾器參數,則需要做更多。幸運的是,教授提供了the source code for his tool,應該可以轉換爲C#。
您可以在另一個stackoverflow問題上看看Butterworth低通濾波器here的源代碼。 正如其他人指出EmguCV自帶了很多過濾器效率和avalaible編碼開箱
你如何在C#中實現這些? – Doug
http://www.musicdsp.org/archive.php?classid=3#38
我實現了過濾器semicode以上如下我們的sEMG分析儀軟件,它的效果很好。
public class FilterButterworth
{
/// <summary>
/// rez amount, from sqrt(2) to ~ 0.1
/// </summary>
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;
/// <summary>
/// Array of input values, latest are in front
/// </summary>
private float[] inputHistory = new float[2];
/// <summary>
/// Array of output values, latest are in front
/// </summary>
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]; }
}
}
下面是使用NMath的FFT一個butterworth和chebyshev濾波器的一些C#代碼示例。
這裏有一個它有很多模式,HP LP BP峯值等等,它是一個BiQuad或許是這種類型的2極靜態濾波器,它是一個特定的濾波器並且具有某種數字結果: https://github.com/filoe/cscore/blob/master/CSCore/DSP/BiQuad.cs
/*
* These implementations are based on http://www.earlevel.com/main/2011/01/02/biquad-formulas/
*/
using System;
namespace CSCore.DSP
{
/// <summary>
/// Represents a biquad-filter.
/// </summary>
public abstract class BiQuad
{
/// <summary>
/// The a0 value.
/// </summary>
protected double A0;
/// <summary>
/// The a1 value.
/// </summary>
protected double A1;
/// <summary>
/// The a2 value.
/// </summary>
protected double A2;
/// <summary>
/// The b1 value.
/// </summary>
protected double B1;
/// <summary>
/// The b2 value.
/// </summary>
protected double B2;
/// <summary>
/// The q value.
/// </summary>
private double _q;
/// <summary>
/// The gain value in dB.
/// </summary>
private double _gainDB;
/// <summary>
/// The z1 value.
/// </summary>
protected double Z1;
/// <summary>
/// The z2 value.
/// </summary>
protected double Z2;
private double _frequency;
/// <summary>
/// Gets or sets the frequency.
/// </summary>
/// <exception cref="System.ArgumentOutOfRangeException">value;The samplerate has to be bigger than 2 * frequency.</exception>
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();
}
}
/// <summary>
/// Gets the sample rate.
/// </summary>
public int SampleRate { get; private set; }
/// <summary>
/// The q value.
/// </summary>
public double Q
{
get { return _q; }
set
{
if (value <= 0)
{
throw new ArgumentOutOfRangeException("value");
}
_q = value;
CalculateBiQuadCoefficients();
}
}
/// <summary>
/// Gets or sets the gain value in dB.
/// </summary>
public double GainDB
{
get { return _gainDB; }
set
{
_gainDB = value;
CalculateBiQuadCoefficients();
}
}
/// <summary>
/// Initializes a new instance of the <see cref="BiQuad"/> class.
/// </summary>
/// <param name="sampleRate">The sample rate.</param>
/// <param name="frequency">The frequency.</param>
/// <exception cref="System.ArgumentOutOfRangeException">
/// sampleRate
/// or
/// frequency
/// or
/// q
/// </exception>
protected BiQuad(int sampleRate, double frequency)
: this(sampleRate, frequency, 1.0/Math.Sqrt(2))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BiQuad"/> class.
/// </summary>
/// <param name="sampleRate">The sample rate.</param>
/// <param name="frequency">The frequency.</param>
/// <param name="q">The q.</param>
/// <exception cref="System.ArgumentOutOfRangeException">
/// sampleRate
/// or
/// frequency
/// or
/// q
/// </exception>
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;
}
/// <summary>
/// Processes a single <paramref name="input"/> sample and returns the result.
/// </summary>
/// <param name="input">The input sample to process.</param>
/// <returns>The result of the processed <paramref name="input"/> sample.</returns>
public float Process(float input)
{
double o = input * A0 + Z1;
Z1 = input * A1 + Z2 - B1 * o;
Z2 = input * A2 - B2 * o;
return (float)o;
}
/// <summary>
/// Processes multiple <paramref name="input"/> samples.
/// </summary>
/// <param name="input">The input samples to process.</param>
/// <remarks>The result of the calculation gets stored within the <paramref name="input"/> array.</remarks>
public void Process(float[] input)
{
for (int i = 0; i < input.Length; i++)
{
input[i] = Process(input[i]);
}
}
/// <summary>
/// Calculates all coefficients.
/// </summary>
protected abstract void CalculateBiQuadCoefficients();
}
/// <summary>
/// Used to apply a lowpass-filter to a signal.
/// </summary>
public class LowpassFilter : BiQuad
{
/// <summary>
/// Initializes a new instance of the <see cref="LowpassFilter"/> class.
/// </summary>
/// <param name="sampleRate">The sample rate.</param>
/// <param name="frequency">The filter's corner frequency.</param>
public LowpassFilter(int sampleRate, double frequency)
: base(sampleRate, frequency)
{
}
/// <summary>
/// Calculates all coefficients.
/// </summary>
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;
}
}
/// <summary>
/// Used to apply a highpass-filter to a signal.
/// </summary>
public class HighpassFilter : BiQuad
{
private int p1;
private double p2;
/// <summary>
/// Initializes a new instance of the <see cref="HighpassFilter"/> class.
/// </summary>
/// <param name="sampleRate">The sample rate.</param>
/// <param name="frequency">The filter's corner frequency.</param>
public HighpassFilter(int sampleRate, double frequency)
: base(sampleRate, frequency)
{
}
/// <summary>
/// Calculates all coefficients.
/// </summary>
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;
}
}
/// <summary>
/// Used to apply a bandpass-filter to a signal.
/// </summary>
public class BandpassFilter : BiQuad
{
/// <summary>
/// Initializes a new instance of the <see cref="BandpassFilter"/> class.
/// </summary>
/// <param name="sampleRate">The sample rate.</param>
/// <param name="frequency">The filter's corner frequency.</param>
public BandpassFilter(int sampleRate, double frequency)
: base(sampleRate, frequency)
{
}
/// <summary>
/// Calculates all coefficients.
/// </summary>
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;
}
}
/// <summary>
/// Used to apply a notch-filter to a signal.
/// </summary>
public class NotchFilter : BiQuad
{
/// <summary>
/// Initializes a new instance of the <see cref="NotchFilter"/> class.
/// </summary>
/// <param name="sampleRate">The sample rate.</param>
/// <param name="frequency">The filter's corner frequency.</param>
public NotchFilter(int sampleRate, double frequency)
: base(sampleRate, frequency)
{
}
/// <summary>
/// Calculates all coefficients.
/// </summary>
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;
}
}
/// <summary>
/// Used to apply a lowshelf-filter to a signal.
/// </summary>
public class LowShelfFilter : BiQuad
{
/// <summary>
/// Initializes a new instance of the <see cref="LowShelfFilter"/> class.
/// </summary>
/// <param name="sampleRate">The sample rate.</param>
/// <param name="frequency">The filter's corner frequency.</param>
/// <param name="gainDB">Gain value in dB.</param>
public LowShelfFilter(int sampleRate, double frequency, double gainDB)
: base(sampleRate, frequency)
{
GainDB = gainDB;
}
/// <summary>
/// Calculates all coefficients.
/// </summary>
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;
}
}
}
/// <summary>
/// Used to apply a highshelf-filter to a signal.
/// </summary>
public class HighShelfFilter : BiQuad
{
/// <summary>
/// Initializes a new instance of the <see cref="HighShelfFilter"/> class.
/// </summary>
/// <param name="sampleRate">The sample rate.</param>
/// <param name="frequency">The filter's corner frequency.</param>
/// <param name="gainDB">Gain value in dB.</param>
public HighShelfFilter(int sampleRate, double frequency, double gainDB)
: base(sampleRate, frequency)
{
GainDB = gainDB;
}
/// <summary>
/// Calculates all coefficients.
/// </summary>
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;
}
}
}
/// <summary>
/// Used to apply an peak-filter to a signal.
/// </summary>
public class PeakFilter : BiQuad
{
/// <summary>
/// Gets or sets the bandwidth.
/// </summary>
public double BandWidth
{
get { return Q; }
set
{
if (value <= 0)
throw new ArgumentOutOfRangeException("value");
Q = value;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="PeakFilter"/> class.
/// </summary>
/// <param name="sampleRate">The sampleRate of the audio data to process.</param>
/// <param name="frequency">The center frequency to adjust.</param>
/// <param name="bandWidth">The bandWidth.</param>
/// <param name="peakGainDB">The gain value in dB.</param>
public PeakFilter(int sampleRate, double frequency, double bandWidth, double peakGainDB)
: base(sampleRate, frequency, bandWidth)
{
GainDB = peakGainDB;
}
/// <summary>
/// Calculates all coefficients.
/// </summary>
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;
}
}
}
}
- 1. 低通和高通濾波器?
- 2. 低/高通濾波器
- 3. 在C中實現簡單的高通和低通濾波器
- 4. 低通濾波器
- 5. C中的低通濾波器
- 6. 低和高通濾波的相位
- 7. 具有特定截止的低通和高通濾波器
- 8. 低通濾波器的Android
- 9. 什麼是高通和低通濾波器?
- 10. NAudio低通濾波器
- 11. JAVA:低通濾波器
- 12. 低通濾波器軟件?
- 13. 測試低通濾波器
- 14. MATLAB:在陣列中應用低通或高通濾波器
- 15. 低通濾波器和採樣頻率
- 16. 通過Octave創建低通濾波器
- 17. MATLAB中圖像的低通濾波器?
- 18. opencv中的低通濾波器
- 19. OpenCL中的低通濾波器
- 20. Python中的低通濾波器
- 21. iPhone中的低通濾波器
- 22. 載波調製和解調中的低通濾波器
- 23. 如何使用dygraphs實現高通和低通濾波?
- 24. 高通濾波器使用FFTW在C
- 25. Butterworth高通濾波器,Matlab
- 26. 高通濾波器matlab
- 27. 在matlab中實現低通濾波器
- 28. MATLAB中的手動高/低通濾波器
- 29. Android OpenCV中的高斯低通濾波器。
- 30. MATLAB上的低通濾波器Butterworth濾波器
感謝您的建議。這些網站非常有用。但是我找不到低通和高通濾波器 – user741319
沒有這個名字。所有的邊緣搜索算法都是高通的,所有的高斯均值和中值濾波器都是低通的。 – Aliostad