You are on page 1of 13

Owen Humphreys

10382535

load ecgpvcs.mat
y=length(ecg1);
d=[1:y]/200;
ecg1=ecg1/1000;

%determining number of samples in data%
%to convert into time domain%
%convert to volts

%%%%%%%%%%%%%plot
figure(1)
plot(d,ecg1)
xlabel 'seconds'
ylabel 'Volts'
title 'Time domain: original signal'
N = 2048;
X = abs(fft(ecg1,N));
X = fftshift(X);
F = [-N/2:N/2-1]/N*200;
figure(2)
plot(F,X)
xlabel 'frequency'
title 'Frequency domain: original signal'

Figure 1 unfiltered ecg signal in time domain

Owen Humphreys 10382535 Figure 2 closer view of unfiltered ecg signal in time domain Figure 3 unfiltered ecg signal in frequency domain .

Figure 4 filtered ecg signal in time domain .bw).Rs). % high pass filter Fs=200. Wp=0. bw = wo/35. bw = wo/35. Rs=40. [num.1.den] = iirnotch(wo.den]=butter(n.Wn] = buttord(Wp.ecg1).Wn. ecg1=filter(num.ecg1). Ws=2/Fn.'high'). Rp=0. [n.den. ecg1=filter(num. ecg1=filter(num. Fn=Fs/2.Ws.Rp.Owen Humphreys 10382535 %%%%%%%%%%%%%%%% filter % 50 Hz notch filter wo = 50/(500/2).den] = iirnotch(wo. [num.den. % 60 Hz notch filter wo = 60/(500/2).ecg1).den.bw).1/Fn. [num.

Owen Humphreys 10382535 Figure 5 closer view of filtered ecg signal in time domain Figure 6 filtered ecg signal in frequency domain Figure 3 unfiltered ecg signal in frequency domain shows a very large peak at around 0 Hz. whereas it was at 2 V before filtering. . the low frequency noise due to body movement has been removed and the ECG signal has become straighter. After the low pass filter the large peak at around 0 Hz is attenuated. There is no peak at 50 or 60 Hz so the notch filters have no effect. The removal of the DC or very low frequency signal results in the baseline at 0 V as expected. Figure 5 closer view of filtered ecg signal in time domainshows a closer view of the signal in the time domain.

'MinPeakHeight'. [Rmag. ecg1(S)).R]=findpeaks(ecg1.ecg1(S).65). . %invert ecg to find S peak [~. plot(S.0. Smag] = deal(ecg1(R).'rv'.'MarkerFaceColor'. %smooth signal %find R peaks [~.Owen Humphreys 10382535 %%%%%%%%%%%%%%%% Peak Detection ecg1 = sgolayfilt(ecg1.ecg1(R_normal).'rv'.'MinPeakHeight'.65).4 & ecg1(R)<0.'y'). %find S Peaks ecg1_inverted=-ecg1. %separate into R peaks into R Normal and R PVC R_normal = R(ecg1(R)>0.3). plot(R_pvc.S]=findpeaks(ecg1_inverted.ecg1(R_pvc).'rv'.4).'MarkerFaceColor'.0.'r'). R_pvc= R(ecg1(R)>0.21).'MarkerFaceColor'. %%%%%%%%%plot figure hold on plot(ecg1) xlabel 'seconds' ylabel 'Volts' title 'Time domain: peak detection' plot(R_normal.'g').7.

PVC R peak (orange). they have not been separated). and S peaks isolated This method can detect the normal R peak (red). PVC R.Owen Humphreys 10382535 Figure 7 ECG with Normal R. . The distance between these peaks could then be calculated. Therefore the Pan Tompkin code is used instead. Although the signal needs to be much smoother because there are many false detections. PVC R. normal S peak (green). and S peaks isolated Figure 8 Closer view of ECG with Normal R. this would give more features to classify the PVC beats than the Pan Tompkin. and PVC S peak (also green.

200.qrs_i_raw. Figure 9 Output of Pan Tompkin Figure 10 Closer view of Output of Pan Tompkin .delay]=pan_tompkin(ecg1.Owen Humphreys 10382535 %%%%%%%%%%Pan Tompkin [qrs_amp_raw.1).

It then applies a high pass filter to remove low frequencies caused by body movement. This creates just two peaks per beat which makes it easier for peak detection.Owen Humphreys 10382535 The Pan Tompkin first applies a low pass filter to remove high frequency noise. The signal is then averaged over 30 samples to create a single peak for peak detection. Figure 11 Output of Pan Tompkin Figure 12 Closer view of output of Pan Tompkin . It squares the magnitude to reduce low amplitude signals and amplify the large amplitude signals.

The Pan Tompkin also calculated the distance between the R peaks. A PVC R peak is identified if it is above this red line.Owen Humphreys 10382535 The red line is the moving average of the amplitude of the peaks. and the sample number it occurred at. they just need to be correct relative to each other. It is only the relative heights and distances between the points that is needed to identify PVC beats. Comparing the Pan Tompkin output to the original ECG signal it is clear that the Pan Tompkin output is shifted. The output points do not need to fit absolutely on the ECG. Figure 13 Comparing original ECG signal to output of Pan Tompkin (green circles) . The Pan Tompkin outputs the amplitude of the R wave. this is used as the second feature for classification.

-1 = Normal. %split into train and test data train_data=data(1:120.:).55 class(k)=1.1)]. feature2=[zeros(401. end The class is notated by 1 = PVC.1)]. while k<402 feature2(k)=qrs_i_raw(k)-qrs_i_raw(k-1). %%%%%% set class class=[zeros(401.1)==1). The class is set by choosing every R peak that is above the value of 0. end %store classes and features data=[class feature1 feature2].:). k=k+1.Owen Humphreys 10382535 %%%%%%%%%%%%%%%%%%% feature selection %change from 1 row 401 columns to 401 rows 1 column feature1=rot90(qrs_amp_raw).55. %set first value. end k=k+1. else class(k)=-1. while k<402 if feature1(k)>0. %%split classes c1=find(train_data(:. k=1. .1)==-1). test_data=data(120:401. then manually checking and changing if any of the values are incorrect. this won't work in loop %find relative distance between peaks by subtracting absolute values k=2. %initialise vector feature2(1)=26. c2=find(train_data(:.

There is a very clear separation between the two groups of data on the magnitude y axis.0000 0.3). Good hyperplane Figure 15 scatter plot showing correlation .1644 0.0731 0. A hyperplane could be drawn between the two sets of data at about 110 samples on the x axis (the distance between the R peaks).0000 Figure 14 Table of correlation values The correlation function shows a very high correlation between the class and the height of the R peak. 'r') xlabel 'Samples between R peaks' ylabel 'Magintude of R peaks' title 'Magnitude Vs Distance between R peaks' Class Feature 1 Feature 2 1.0000 0.0731 1.2).9530 1.1644 0.3). 'b') hold on scatter(train_data(c2.train_data(c2.train_data(c1.2).Owen Humphreys 10382535 %%find best features correlation=abs(corrcoef(train_data)) scatter(train_data(c1. This can also be seen with a scatter plot of the data.9530 0. but the data is much closer together and the correlation is not as good.

2) .:)==0.train_data(:.1)-Predicted_Train_lebels. accuracy_test=test_data(:.2:3) . count=count+1.2) .:)==0. end accuracy_Predicted_Test_lebels=count/282 .2:3) . count=0. end k=k+1.1) ).Owen Humphreys 10382535 %%%%%%%%%%% Train_data Accuracy Predicted_Train_lebels = classify (train_data(:. while k<283 if accuracy_test(k. k=1.1)-Predicted_Test_lebels k=1. end k=k+1.train_data(:. accuracy_train=train_data(:. end accuracy_Predicted_Train_lebels=count/120 %%%%%%%%%%% Test_data Accuracy Feature1 clc Predicted_Test_lebels = classify (test_data(:. count=0. train_data(:.1)). train_data(:. count=count+1. while k<121 if accuracy_train(k.

1) ). while k<283 if accuracy_test(k. .45 % Conclusion: The most accurate feature to classify the test data is the R peak magnitude alone.[2 3]) .:)==0.1) ). count=0. accuracy_test=test_data(:. while k<283 if accuracy_test(k.1)-Predicted_Test_lebels k=1.3) .16 % 68. count=count+1.79 % 96. end accuracy_Predicted_Test_lebels=count/282 %%%%%%%%%%% Test_data Accuracy Feature1 & Feature2 clc Predicted_Test_lebels = classify (test_data(:.:)==0. count=0. end k=k+1.1)-Predicted_Test_lebels k=1.Owen Humphreys 10382535 %%%%%%%%%%% Test_data Accuracy Feature2 clc Predicted_Test_lebels = classify (test_data(:. accuracy_test=test_data(:. train_data(:.3) . count=count+1.train_data(:. end accuracy_Predicted_Test_lebels=count/282 Feature Train Data Test Data: Feature1 – R Magnitude Test Data: Feature2 – Distance between R peaks Test Data: Feature1 & Feature2 Accuracy 100 % 97.train_data(:.[2 3]) . train_data(:. end k=k+1.