0
$\begingroup$

I was trying to apply FIR filter on the ECG signal: a bandstop for 45-55 Hz for noise removal and a highpass filter for moving baseline wander. But after that, the ECG signal show strange waveform at the beginning.

Here is the processed signal in time domain:

enter image description here

The related code is as follows.

class FIRfilterDesign:
def __init__(self):
    return

def highpassDesign(self, sample_rate, cutoff_freq):
    # set up suitable number of taps
    M = 2 * sample_rate
    # calculate teh desired k
    k = int(cutoff_freq / sample_rate * M)
    # generate desired X(k)
    X = np.zeros(M)
    X[k:M - k + 1] = 1
    # do the inverse Fast Fourier Transform to get x(n)
    x = np.fft.ifft(X)
    # keep the real part
    x = np.real(x)
    # swap the positive half and negative half for impulse response
    h = np.zeros(M)
    h[0:int(M / 2)] = x[int(M / 2):M]
    h[int(M / 2):M] = x[0:int(M / 2)]
    # apply window function for little ripples
    h = h * np.hamming(M)
    return h

def bandstopDesign(self, sample_rate, cutoff_freq1, cutoff_freq2):
    # set up suitable number of taps
    M = 2 * sample_rate
    # calculate the value of desired k1 and k2
    k1 = int(cutoff_freq1 / sample_rate * M)
    k2 = int(cutoff_freq2 / sample_rate * M)
    # generate desired X(k)
    X = np.ones(M)
    X[k1:k2 + 1] = 0
    X[M - k2:M - k1 + 1] = 0
    # do the inverse Fast Fourier Transform to get x(n)
    x = np.fft.ifft(X)
    # keep the real part
    x = np.real(x)
    # pl.plot(x)
    # pl.plot(X)

    # swap the positive half and negative half for impulse response
    h = np.zeros(M)
    h[0:int(M / 2)] = x[int(M / 2):M]
    h[int(M / 2):M] = x[0:int(M / 2)]

    # apply window function for little ripples
    h = h * np.hamming(M)
    return h


class FIRfilter:
def __init__(self, _coefficients):
    # buffer for store delay line
    self.coefficients = _coefficients
    self.ntaps = len(_coefficients)
    self.buffer = np.zeros(self.ntaps)

    return

def dofilter(self, v):
    # insert the new value at the front of the delay line
    self.buffer = np.insert(self.buffer, 0, v)
    result = 0
    # sum up input signal * coefficients
    for i in range(0, self.ntaps - 1):
        result = result + self.buffer[i] * self.coefficients[i]
    return result

rawECG = np.loadtxt('ECG.dat')
t = np.arange(0, 20, 0.004)
# Call the function created in Q1 to generate coefficients
a = firfilter.FIRfilterDesign()
h1 = a.highpassDesign(250, 2)
h2 = a.bandstopDesign(250, 45, 55)
h = np.convolve(h1, h2, 'same')
h = h * np.hamming(len(h))

b = firfilter.FIRfilter(h)
filteredECG = np.zeros(len(rawECG))
# process sample by sample
for i in range(0, len(rawECG) - 1):
    filteredECG[i] = b.dofilter(rawECG[i])

I am pretty new to DSP.

$\endgroup$
0

1 Answer 1

3
$\begingroup$

It appears that your input has a sizable DC offset and what you are seeing is the initial transient of either the high pass (or maybe the band stop as well).

One way to fix this would be to initialize the filter state variables with an estimate of the DC offset.

$\endgroup$
1
  • $\begingroup$ Thanks a lot! I think it appears after high pass filtering. The waveform looks better after I remove the DC offset $\endgroup$
    – nanarua
    Nov 14, 2021 at 15:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.