Getting the beat right!!. Processing the ECG signal with... | by Pareeknikhil | Towards Data Science

With a plethora of Biofeedback apps emerging in the health and fitness space, wearable biosensing devices are becoming pivotal in determining the “Active” state of the users. The active state of the user could be defined as the mood; between happy-sad-neutral or stress state; between relaxed-stressed-neutral, or even health state; healthy-risky, depending upon the scope of the application being developed. But a common physiological indicator that pins all the aforementioned use-cases is cardiovascular data. And this article aims to give you a brief summary on filtering raw cardiovascular data from BCI/Fitness tracking devices such as Polar H10 and OpenBCI-Cyton into noise-free data.
Most of the Biofeedback systems rely on two key physiological measurements as indicators of the active state of the user: Cardiovascular activity and Breathing capacity. These signals could further be split into specific metrics such as Heart Rate Variability (HRV), RR interval, Tidal Volume, etc. but we would stick with processing raw cardiovascular activity here (For a detailed read on indicators — here). And Electrocardiograph (ECG) is the savior here in providing the most accurate electrical activity of the heart in real-time as compared to techniques such as Photoplethysmography (PPG). Essentially ECG signals convey information about the structure and function of the heart and further, we are specifically interested in capturing a biomedical signal — the QRS complex of the heart which is useful in diagnosing cardiac arrhythmias, conduction abnormalities, ventricular hypertrophy, myocardial infarction, electrolyte derangements, and other disease states.
What is a QRS complex?
As one would guess from the name, the QRS complex includes the Q wave, R wave, and S wave and all these three waves occur in rapid succession. The QRS complex represents the electrical impulse of the heart as it beats in real-time. And as the blood spreads through the ventricles of the heart, occurs the ventricular depolarization and a corresponding QRS complex is registered in the ECG.
Although not every QRS complex will contain Q, R, and S waves and the convention is such that the Q wave is always negative and that the R wave is the first positive wave of the complex. usually, if the QRS complex only includes an upward (positive) deflection, then it is an R wave. The S wave is the first negative deflection after an R wave.
In a healthy adult and under normal circumstances, the duration of the QRS complex will be between 0.06 and 0.10 seconds.
Share URLCtrl + C to copy
EmbedCtrl + C to copy



What’s noise in ECG data?
The frequency range of a clean ECG signal is between 0.05 Hertz to 100 Hertz but during the transmission and acquisition of the signal via the ECG monitoring device, different noises such as power line interference, baseline drift, channel noise, Eletcromyogram/Muscular movement noise, electrode contact noise could be introduced.
Mainly two types of noises are present in a raw ECG signal (Figure 2 shows the combination of both):
High-Frequency Noise: Power line Noise, White Gaussian Noise, Eletcromyogram/Motion Noise
Low-Frequency Noise: Baseline drift, Electrode contact loss
Understanding each of these noises a bit in detail could help us to effectively identify the type of noise and then we can further use the correct denoising technique to remove the artifact.
Power Line Interference: These are the harmonics of the Electromagnetic interference through the power line and the electromagnetic field of the nearby electrical appliances. Especially the heavy power line machines such as Air-conditioners, microwaves, elevators, and washing machines, etc. The frequency range is between 50 Hz to 60 Hz (USA) depending upon the country of study.
White Gaussian Noise: This a noise that is embedded in the ECG signal usually and the determination of the source is difficult since it is introduced at various levels and is random in nature. It is very similar to channel noise in nature.
Electromyogram/Motion Noise: This type of noise is generated by the electrical activity of the muscle and also due to the change in the electrode-skin impedance change which could further be resulted due to the change in skin temperature, humidity, etc.
Baseline Drift: This is the most common noise and causes greater difficulty in peak detection during the analysis of the ECG signal. It is low-frequency noise and is usually close to 1 Hertz as it is attributed due to respiration and swift body movements.
Electrode Contact Loss: This usually leads to a flat signal and is resulted due to the loss of contact between the electrode and the skin and therefore disconnecting the ECG monitoring device from the body.
Which Denoising techniques can I use?
To eliminate both of these types of artifacts: low frequency and high-frequency noises, one could use two types of filters while cleaning the data:
IIR Notch Filters: Usually know as Notch filters, these are the simplest ones and are usually used to remove power line interference and or a motion artifact at a specific or narrow frequency spectrum. Work really well with the fixed-frequency noise source.
FIR Filters: Also known as the Windowing or Band-pass filters, where high cut-off and low cut-off frequencies are specified and then everything else beyond the specified “band” is attenuated. These filters are very stable and work in the range of 1 Hertz to 100 Hertz thus making them fit for the application on ECG data. The most common type amongst FIR filters is the Butterworth filter.
From our understanding of physiological responses registered in adults, a healthy resting heart rate is 60 to 80 bpm; heart rate in athletes could be as low as 30 bpm and as high as 120 bpm in hypertension. Therefore our band of frequency is between 0.5 Hertz to 2 Hertz.
One could also specify parameters such as the sampling frequency of the device as a parameter into the Butterworth filter. For example, Polar H10 has a sampling frequency rate of 130 Hertz as suggested in the official documentation; though the value ranges around 120 Hz when using the device in real-time, and OpenBCI — Cyton has a sampling frequency of around 250 Hertz as indicated in the official documentation and is mostly consistent throughout its use. Since in our case, sampling frequencies are many folds higher than the heart response frequencies we can easily capture the heartbeats in users with a band of 0.5 Hertz to 2 Hertz.
Where do I find the code?
All of this could be very easily achieved with a few lines of code in Python and with the help of libraries such as Scipy, Numpy, and Pandas, it’s mostly a walk in the park. A sample code snippet is available below for reference (Check out my Github repo for ECG Data Stream and detailed filtering — here):
from scipy import signalfrom scipy.signal import butter, iirnotch, lfilterimport numpy as npimport matplotlib.pyplot as plt## A high pass filter allows frequencies higher than a cut-off valuedef butter_highpass(cutoff, fs, order=5):    nyq = 0.5*fs    normal_cutoff = cutoff/nyq    b, a = butter(order, normal_cutoff, btype='high', analog=False, output='ba')    return b, a## A low pass filter allows frequencies lower than a cut-off valuedef butter_lowpass(cutoff, fs, order=5):    nyq = 0.5*fs    normal_cutoff = cutoff/nyq    b, a = butter(order, normal_cutoff, btype='low', analog=False, output='ba')    return b, adef notch_filter(cutoff, q):    nyq = 0.5*fs    freq = cutoff/nyq    b, a = iirnotch(freq, q)    return b, adef highpass(data, fs, order=5):    b,a = butter_highpass(cutoff_high, fs, order=order)    x = lfilter(b,a,data)    return xdef lowpass(data, fs, order =5):    b,a = butter_lowpass(cutoff_low, fs, order=order)    y = lfilter(b,a,data)    return ydef notch(data, powerline, q):    b,a = notch_filter(powerline,q)    z = lfilter(b,a,data)    return zdef final_filter(data, fs, order=5):    b, a = butter_highpass(cutoff_high, fs, order=order)    x = lfilter(b, a, data)    d, c = butter_lowpass(cutoff_low, fs, order = order)    y = lfilter(d, c, x)    f, e = notch_filter(powerline, 30)    z = lfilter(f, e, y)         return zecg_singal = np.loadtxt('df_ecg_Polar.csv', skiprows=0)fs = 1000## Order of five works well with ECG signalscutoff_high = 0.5cutoff_low = 2powerline = 60order = 5plt.figure(1)ax1 = plt.subplot(211)plt.plot(ecg_signal)ax1.set_title("Raw ECG signal")filter_signal = final_filter(ecg_signal, fs, order)ax2 = plt.subplot(212)plt.plot(filter_signal)ax2.set_title("Clean ECG signal")plt.show()
What are the results I can expect?
Using the above-mentioned filtering technique, one can produce very clean signals with the prominent QRS complex visible. For example, I used the above technique on raw ECG signal recorded from Polar-H10 and OpenBCI-cyton board and the results are illustrated as follows:
OpenBCI — Cytonboard: In OpenBCI raw signal one could observe the drift as well as artifacts. Both baseline correction and artifact removal are successfully achieved with the Butterworth filter with ❤ looking QRS complex.
Polar H10: Polar H10 already filters the data on the device and sends it across, therefore there is only a bit of baseline correction around the mean zero but for the most part of it, the filter output is the same as raw signal input.
Where can I learn more?
Building a live data-stream for Polar and OpenBCI boards is vital in building real-time applications and is a fairly simple task with a little time and sufficient documentation. Luckily we have both !!
How to create a real-time data-stream with Polar devices — ECG and Accelerometer
How to create a real-time data-stream with OpenBCI boards — ECG
References:
1. Wiki, QRS Complex, Wikipedia2. National Centre for Adaptive Neurotechnologies (NCAN), Contributions:OpenBCI Module3. Denisse Castaneda, Aibhlin Esparza, Mohammad Ghamari, Cinna Soltanpur, and Homer Nazera, A review on wearable photoplethysmography sensors and their potential future applications in health care (2019), NCBI4. ACLS Medical training |The Basics of ECG5. Aswathy Velayudhan, Soniya Peter, Noise Analysis and Different Denoising Techniques of ECG Signal - A Survey (2016) ,IOSR-JECE6. Mohamed Elgendi,Carlo Menon, Assessing Anxiety Disorders Using Wearable Devices: Challenges and Future Directions (2019) ,Brain Sciences7. Fred Shaffer1, J. P. Ginsberg, An Overview of Heart Rate Variability Metrics and Norms (2017) ,NCBI8. Inma Mohino-Herranz, Roberto Gil-Pita, Manuel Rosa-Zurera, Fernando Seoane, Activity Recognition Using Wearable Physiological Measurements: Selection of Features from a Comprehensive Literature Study (2019) ,NCBI