Abhipsa
Abhipsa

Reputation: 41

ECG signal filtering

I am trying to filter ECG signal acquired from Bioplux sensor. I am including lowpass filter to remove noise of frequencies over 200 Hz, highpass filter for removing baseline wander, and notch filter for removing powerline frequency of 60 Hz. I am not able to understand why I am getting a wavy shaped output after the high-pass filtering. Could someone suggest some ideas to get properly filtered ECG signal? The rawsignal data text file and the obtained output after filtering can be seen in the following link:

https://drive.google.com/open?id=1hvvQpMMa_hn9VNlUh4HAqb_H1lCu70or

The code I have written is as below:

from scipy import signal
from scipy.signal import butter, iirnotch, lfilter
import numpy as np
import matplotlib.pyplot as plt

def 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

def 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, a

def notch_filter(cutoff, q):
    nyq = 0.5*fs
    freq = cutoff/nyq
    b, a = iirnotch(freq, q)
    return b, a

def highpass(data, fs, order=5):
    b,a = butter_highpass(cutoff_high, fs, order=order)
    x = lfilter(b,a,data)
    return x

def lowpass(data, fs, order =5):
    b,a = butter_lowpass(cutoff_low, fs, order=order)
    y = lfilter(b,a,data)
    return y

def notch(data, powerline, q):
    b,a = notch_filter(powerline,q)
    z = lfilter(b,a,data)
    return z

def 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 x
    return y
    return z

rawdata = np.loadtxt('D:\CANADA TRIP\BiosignalsSample.txt', skiprows=0)
signal = rawdata
fs = 1000

cutoff_high = 0.5
cutoff_low = 200
powerline = 60
order = 6

#print(signal)
plt.figure(1)
ax1 = plt.subplot(321)
plt.plot(signal)
ax1.set_title("Raw signal")

conditioned_signal = final_filter(signal, fs, order)
ax2 = plt.subplot(322)
plt.plot(conditioned_signal)
ax2.set_title("Conditioned signal")

hsignal = highpass(signal, fs, order)
ax3 = plt.subplot(323)
plt.plot(hsignal)
ax3.set_title("Only highpass filter")

lsignal = lowpass(signal, fs, order)
ax4 = plt.subplot(324)
plt.plot(lsignal)
ax4.set_title("Only lowpass filter")

nonotch_1 = highpass(signal, fs, order)
nonotch = lowpass(nonotch_1, fs, order)
ax5 = plt.subplot(325)
plt.plot(nonotch)
ax5.set_title("High and low pass")

onlynotch = notch(signal, powerline, 30)
ax6 = plt.subplot(326)
plt.plot(onlynotch)
ax6.set_title("Notch filter only")

plt.show()

Upvotes: 4

Views: 6823

Answers (1)

Isra Ragheb
Isra Ragheb

Reputation: 51

try using a bandpass filter from 0.1 to 45 Hz, rather than cascading a lowpass and highpass filter.

def bandpass(lowcut, highcut, order=5):
    nyq = 0.5 * fs
    low = lowcut / nyq
    high = highcut / nyq
    b, a = butter(order, [low, high], btype='band')
    return b, a

Upvotes: 2

Related Questions