// konstruktor MOVING_AVG, SAV_GOL, LMS LOW, HIGH public ECG_Baseline_Params(Filtr_Method method, Filtr_Type type, int windowSize, string analysisName) { this.Method = method; this.AnalysisName = analysisName; this.Type = type; if (type == Filtr_Type.LOWPASS) this.WindowSizeLow = windowSize; else if (type == Filtr_Type.HIGHPASS) this.WindowSizeHigh = windowSize; }
//konstruktor BUTTERWORTH BAND public ECG_Baseline_Params(Filtr_Method method, Filtr_Type type, int orderLow, int orderHigh, double fcLow, double fcHigh, string analysisName) { this.Method = method; this.AnalysisName = analysisName; this.Type = type; this.FcLow = fcLow; this.FcHigh = fcHigh; this.OrderLow = orderLow; this.OrderHigh = orderHigh; }
//konstruktor BUTTERWORTH LOW, HIGH public ECG_Baseline_Params(Filtr_Method method, Filtr_Type type, int order, double fc, string analysisName) { this.Method = method; this.AnalysisName = analysisName; this.Type = type; if (type == Filtr_Type.LOWPASS) this.FcLow = fc; else if (type == Filtr_Type.HIGHPASS) this.FcHigh = fc; if (type == Filtr_Type.LOWPASS) this.OrderLow = order; else if (type == Filtr_Type.HIGHPASS) this.OrderHigh = order; }
public Vector<double> butterworth(Vector<double> signal, double fs, double fc, int order, Filtr_Type type) { //TODO: Comments int L = signal.Count; int DCGain = 1; double[] DoubleArray = new double[L]; DoubleArray = signal.ToArray(); Complex[] ComplexArray = new Complex[L]; for (int i = 0; i < L; i++) { ComplexArray[i] = new Complex(DoubleArray[i], 0); } Fourier.Forward(ComplexArray, FourierOptions.Matlab); double binWidth, binFreq, gain; if (fc > 0) { binWidth = fs / L; for(int i = 0; i < (L/2); i++) { binFreq = binWidth * (i+1); gain = DCGain / Math.Sqrt(1 + Math.Pow(binFreq/fc, 2.0 * order)); if (type == Filtr_Type.HIGHPASS) { gain = 1 - gain; } ComplexArray[i] *= gain; ComplexArray[L - 1 - i] *= gain; } } Fourier.Inverse(ComplexArray, FourierOptions.Matlab); for (int i = 0; i < L; i++) { DoubleArray[i] = ComplexArray[i].Real; } Vector<double> output_signal = Vector<double>.Build.DenseOfArray(DoubleArray); return output_signal; }
// konstruktor MOVING_AVG, SAV_GOL, LMS BAND public ECG_Baseline_Params(Filtr_Method method, Filtr_Type type, int windowSizeLow, int windowSizeHigh, string analysisName) { this.Method = method; this.AnalysisName = analysisName; this.Type = type; this.WindowSizeLow = windowSizeLow; this.WindowSizeHigh = windowSizeHigh; }
public Vector<double> savitzky_golay(Vector<double> signal, int window_size, Filtr_Type type) { //TODO: Comments int signal_size = signal.Count; if ((window_size % 2) == 0) { window_size = window_size + 1; } Vector<double> signal_extension_front = Vector<double>.Build.Dense((window_size / 2), signal[0]); Vector<double> signal_extension_back = Vector<double>.Build.Dense((window_size / 2), signal[signal_size - 1]); int signal_extension_size = signal_extension_front.Count; Vector<double> signal_extended = Vector<double>.Build.Dense(2*signal_extension_size + signal_size, 0); //przygotowanie zmiennej, w której znajdzie się sygnał przygotowany do filtracji Vector<double> signal_filtered = Vector<double>.Build.Dense(signal_size, 0); //zmienna na sygnał przefiltrowany for (int i = 0; i < signal_extension_size; i++) { signal_extended[i] = signal_extension_front[i]; //powielenie piewszej próbki sygnału wejściowego } for (int i = 0; i < signal_size; i++) { signal_extended[i + signal_extension_size] = signal[i]; //powielenie piewszej próbki sygnału wejściowego } for (int i = 0; i < signal_extension_size; i++) { signal_extended[i + signal_extension_size + signal_size] = signal_extension_back[i]; //powielenie piewszej próbki sygnału wejściowego } Vector<double> samples = Vector<double>.Build.Dense(signal_extended.Count, 0); for (int i = 0; i < samples.Count; i++) { samples[i] = i + 1; } double[] coeff = new double[3]; Vector<double> samples_destination = Vector<double>.Build.Dense(window_size, 0); Vector<double> signal_extended_destination = Vector<double>.Build.Dense(window_size, 0); double[] output_signal_table = new double[signal_size]; for (int i = 0; i < signal_size; i++) { samples.CopySubVectorTo(samples_destination, i, 0, window_size); signal_extended.CopySubVectorTo(signal_extended_destination, i, 0, window_size); coeff = Fit.Polynomial(samples_destination.ToArray(), signal_extended_destination.ToArray(), 3, DirectRegressionMethod.NormalEquations); output_signal_table[i] = coeff[3] * Math.Pow(samples[i + (window_size / 2)], 3) + coeff[2] * Math.Pow(samples[i + (window_size / 2)], 2) + coeff[1] * samples[i + (window_size / 2)] + coeff[0]; } Vector<double> output_signal = Vector<double>.Build.DenseOfArray(output_signal_table); if (type == Filtr_Type.HIGHPASS) { return signal - output_signal; } return output_signal; }
public Vector<double> moving_average(Vector<double> signal, int window_size, Filtr_Type type) { int signal_size = signal.Count; //rozmiar sygału wejściowego Vector<double> signal_extension = Vector<double>.Build.Dense(window_size - 1, signal[0]); //uwzględnienie warunków początkowych filtracji Vector<double> signal_extended = Vector<double>.Build.Dense(signal_extension.Count + signal_size, 0); //przygotowanie zmiennej, w której znajdzie się sygnał przygotowany do filtracji Vector<double> signal_filtered = Vector<double>.Build.Dense(signal_size, 0); //zmienna na sygnał przefiltrowany for (int i = 0; i < signal_extension.Count; i++) { signal_extended[i] = signal_extension[i]; //powielenie piewszej próbki sygnału wejściowego } for (int i = 0; i < signal_size; i++) { signal_extended[i + window_size - 1] = signal[i]; //przygotowanie sygnału do filtracji } double sum = 0; //zmienna pomocnicza for (int i = 0; i < signal_size; i++) { sum = 0; for (int j = 0; j < window_size; j++) { sum = sum + signal_extended[i + j]; //sumowanie kolejnych próbek sygnału } signal_filtered[i] = sum / window_size; //obliczenie średniej } if(type == Filtr_Type.HIGHPASS) { return signal - signal_filtered; } return signal_filtered; //sygnał przefiltrowany }