I am trying to design a high pass filter to remove baseline drift from an ECG signal. the baseline drift is of very low frequency like 0.3Hz or so with an amplitude of 25% of the ECG signal. But the bandwidth of ECG signal itself is 0.5Hz to 150Hz. I have been trying fdatoolbox in matlab to design the HPF but I was not able to remove the baseline drift accurately.Please help on how can i achieve a low order filter to eliminate baseline drift. I have got it using higher order filters of order above 1000. But I'm looking for a way if I can get lower order filter,like order of less than 30, to do the same.Thanks for your help..
-
$\begingroup$ What's your sampling frequency? $\endgroup$ – Matt L. May 21 '14 at 7:58
-
$\begingroup$ @MattL. you mean the sampling frequency that i've given during filter design? I've given it as some 350Hz like that.. $\endgroup$ – user2940249 May 21 '14 at 8:53
You usually use a DC notch filter. This is a recursive filter that should kill a very narrow band of frequencies around DC. One possible implementation is a first order DC notch with transfer function
$$\frac{1 - z^{-1}}{1 - \lambda z^{-1}},$$
where $\lambda$ is some number very close to 1, say 0.99. A to demonstrate this in MATLAB,
b = [1 -1];
a = [1 -0.99];
freqz(b,a);
Notice that the phase response around DC gets pretty non-linear. Such is the nature of these recursive filters.
The closer you make $\lambda$ to 1, the narrower the notch gets and the more distorted your phase response becomes around DC.
For ECG signals, this will usually do. Experiment with $\lambda$ values that will suit your needs. Sometimes, if you make the notch too narrow, you won't get all off the drift, so 0.99 is usually a good starting point.
Recently, we have released a baseline filtering and noise removal method that takes into account the sparsity (and the potential asymmetry) of one-dimensional signals. It was initially applied to analytical chemistry data (chromatograms), but could possibly be used of ECG. It relies on a recursive low-pass filter, an asymmetry parameter, and a penalization related to the noise level and the strength of the signal and its derivatives.
One illustration for BEADS background removal is:
The code for BEADS (Baseline Estimation And Denoising with Sparsity) is available in Matlab, R, C++. It has been used for instance in the following papers:
- Epileptic seizure onset detection based on EEG and ECG data fusion
- Shannon’s Energy Based Algorithm in ECG Signal Processing
- Detection of Atrial Fibrillation in ECG Hand-held Devices Using a Random Forest Classifier
- Combined matching pursuit and Wigner-Ville Distribution analysis for the discrimination of ictal heart rate variability
- Signal processing using sparse derivatives with applications to chromatograms and ECG
- Training System Methodology Using ECG Signal
-
$\begingroup$ Is this approach limited to cases when chromatograms begin and end with 0 intensity? I have issues when it's not the case: github.com/tvijverb/BEADS_Baseline_correction/issues/1 But maybe I just didn't set it up properly.. $\endgroup$ – Stanislav Bashkyrtsev Oct 29 '18 at 15:27
-
$\begingroup$ In this implementation, you are correct, due to initializations for the IIR filter. A little preprocessing of the data helps in this cases. What do your data look like at the edges? $\endgroup$ – Laurent Duval Oct 29 '18 at 15:31
-
$\begingroup$ There is a screenshot attached if you follow the link - it starts with non-zero baseline (presumably - a residual from previous runs) and ends with non-zero baseline. By re-processing - do you mean adding artificial 0's at the beginning and at the end? $\endgroup$ – Stanislav Bashkyrtsev Oct 30 '18 at 7:48
-
$\begingroup$ I do not have a full answer to all cases, honestly. Here, the jump at $0.25$ represents an issue with the algorithm hypotheses. Does it work better on the $[0.25 \, 2.00]$ interval? I am working on different preprocessing techniques (mirroring, linear slope removal), I can include your data in tests $\endgroup$ – Laurent Duval Oct 30 '18 at 8:48
-
1$\begingroup$ It works great from 0.5 to 1.25 though the baseline doesn't touch 0. $\endgroup$ – Stanislav Bashkyrtsev Oct 30 '18 at 9:46