I have a 1-by-10000 matrix of double`s stored in a file named "fecg.mat". The matrix represents the magnitude of a recorded FECG signal.

I've plotted it against time (from 0 to 9999):

enter image description here

For removing the baseline I wonder if I can use a high-pass filter. How do I design a proper filter?

P.S Signal processing isn't my field of study. I have no idea how to filter a discrete time-domain signal.

  • 1
    $\begingroup$ I'd note that for some complex waveforms (such as video signals) it's more effective to "clamp" to some feature of the waveform than to try to "filter" the signal to remove low-frequency noise. However, in this case there's no obvious feature to clamp to. $\endgroup$ Jul 5, 2012 at 12:03
  • 1
    $\begingroup$ So you want to filter a fetal ECG from the mother's ECG and the fetal ECG is at a high frequency. I'd transfer the signal to the frequency domain (FFT) using a window filter to get the frequency in different time frames, then look at the resulting frequencies over the different time windows to tell at what frequency to filter. If you want to know the numeric values of the time and frequencies, you will still need the sample rate. If you just want to see that it is constant, you might not need it. $\endgroup$ Jul 6, 2012 at 13:34

5 Answers 5


Easiest way to remove baseline is to remove the average:

filtered = original - mean(original);

Actually, the average is the first coefficient of the Fourier transform, so it is actually a very sharp filtering: you are eliminating the DC coefficient.

If you want more classic filtering, then check functions like butter and friends, which will synthesize an IIR filter, then use filter to filter out your signal.

Matlab also includes a filter design tool.


MATLAB has a filter design tool called fdatool. Run the fdatool in MATLAB, it gives you a visual GUI, in which you can change the filter parameters. Choose a high-pass filter from there and choose a cut0ff frequency. when you are satisfied with the filter shape, export it to the MATLAB workspace. Let's say your filter name is myFilter and your signal name is mySignal. Then to filter the signal in MATLAB type: filteredSignal = conv(mySignal,myFilter).


If you know the frequency content of the desired signal you can high pass somewhat below that frequency. Let's say that you are only interest in signal above 2 Hz and you sample rate is 100 Hz, then you can do this as follows:

[b,a] = butter(3,2/(100/2),'high');
outputData = filter(b,a,inputData);

This is specific example uses a 3rd order butterworth highpass.

  • $\begingroup$ Thank you.I don't have the frequency and sample rate, but I think I should estimate them, because the frequency of ECG signals mostly are in range of 0.1 to 250 Hz. $\endgroup$
    – hoo_man
    Jul 5, 2012 at 4:26
  • 1
    $\begingroup$ @hoo_man If you don't know the sample rate, the information is meaningless. You'll have to ask whoever gave you the measurement. P.S. The sample rate should be at least 2 * the maximum signal frequency. $\endgroup$ Jul 5, 2012 at 18:13
  • $\begingroup$ @DannyVarod: So under this circumstance the only way is to find the sample rate through trial and error... I start with 500Hz $\endgroup$
    – hoo_man
    Jul 6, 2012 at 7:26
  • $\begingroup$ It doesn't have to be round number. What do you want to do with the data? $\endgroup$ Jul 6, 2012 at 12:16
  • $\begingroup$ @DannyVarod: Mostly the sampling rate for recording ECG is about 400Hz-500Hz. I want to extract the fetal ECG from maternal ECG. First I have to remove the baseline wander. $\endgroup$
    – hoo_man
    Jul 6, 2012 at 12:43

Which filter to use really depends on the specific application. - Too rough a filter could remove the information you are looking for!

The widely used Pan-Tompkins algorithm (for QRS detection) specifies a filter for baseline removal in ECG data. But it is hard to determine whether this filter is suitable for your application from the limited information you supplied. Please elaborate for a more precise answer.

  • 4
    $\begingroup$ Lowpass to recognize the baseline. To remove it you should subtract the result of the lowpass from the original signal, thus creating effectively a highpass filter, isn't it? $\endgroup$
    – Castilho
    Jul 4, 2012 at 18:10
  • $\begingroup$ You're right - I got that part turned upside down. Thanks for correcting that. $\endgroup$
    – mola
    Jul 4, 2012 at 18:35
  • $\begingroup$ I passed the signal through a LPF as Castilho said. but the baseline I obtained was delayed. For matching the baseline and original signal to subtract them should I shift one of them or is there a better way? $\endgroup$
    – hoo_man
    Jul 6, 2012 at 10:01

I would suggest you to use an adaptive filter for removing the 50Hz baseline noise. an lms adaptive filter would do just fine:

xk = sin(2*pi*50*t1);
dk = ecg1; 
bk = [0 0 0];                       %Gewichteter Vektor (FIR Koefizienten mit Anfangswert 0)
                                    %Die Werte ändern sich ständig bis sich
                                    %das System adaptiert hat

mu = .1;                            %Konvergenzgeschwindigkeit des Algorithmes.
                                    %( 0 < mu < 1/(20*(L+1)*Potenz_xk); L Filterorder)                                
%mu=1/(100*(L+1)*Pot_x);            % Konvergenzgeschwindigkeit des Algorithmus.
                                    % Bei den Prädiktiven Adaptiven filter
                                    % gilt die Potenz nicht

yk=zeros(size(xk));                 % Ausgangssignal zum Zeitpunkt t=0 von der FIR.
ek=zeros(size(xk));                 % Fehlersignal zum ZEitpunkt t=0.

%Algorithmus für FIR Adaptiven Filter:
for n = 3:(punkte - 1)                          %Arranca en 3 porque tiene que almacenar las dos muestras anteriores y la actual (FIR de 2 coeficientes)
    xkn = [xk( n ) xk( n - 1 ) xk( n - 2 )];    %Vector niésimo (2 posiciones porque son dos coeficientes).
    yk(n) = xkn * bk';                          %Resultado parcial de la salida por el vector bk traspuesto.
    ek(n) = dk(n) - yk(n);                      %Señal de error parcial.
    bk = bk + 2*mu*ek(n)*xkn;                   %Actualización instante a instante del vector de pesos.  
end                                             %Ende des adaptiven Algorithmes.

Eje1 = figure(1);
set(Eje1,'name','Übung 1: FIR Adaptive Filter','position',[10 10 900 650]);
subplot( 2, 1, 1 );
plot( t1, xk, 'r');
ylabel('EKG mit Rauschen');
title('Eingangssignal: Bewegungsartifakt zu filtern');
subplot( 2, 1, 2 );
plot( t1, ek, '-k');
ylabel('d[k] - y[k]');
title('Ausgangssignal: EKG ohne Rauschen');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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