Bonjour à tous,
Tout d'abord, je suis tout nouveau sur Matlab et plus spécifiquement sur le forum, désolé d'avance pour d’éventuelles maladresses
Dans un devoir, on nous donne des signaux d'un ECG (dans un premier temps sans bruit) et je suis censé trouver les piques des ondes R.
En cours, nous avons vu une méthode (matched filter), qui permet la détection d'un complexe QRS et j'ai donc essayé de "traduire" cette méthode dans mon code.
Dans l'exemple vu en cours, on nous donc un vecteur x[n] représentant un morceau du signal ECG, et un template y[n] de longueur N=4 représentant le premier complexe QRS du signal x[n].
La méthode consistait à:
1. une normalisation du signal x[n] et du model y[n] entre -1 et 1.
2. calculer la corrélation entre le modèle y[n] et une séquence du signal x[n] de longueur y[n] avec la formule suivante :
3. On définit un limite K,tel que si corr ⩾ K, on décidera qu'il s'agit d'un complexe QRS.
Voici donc mon code en matlab:
Et ma fonction:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 %change signal_path, min_idx_template and max_idx_template for other signal %part 1 - signal 2 clear all close all signal_path = 'ECG_OSCAR_03.mat'; a = load(signal_path); a_table = struct2table(a); y = 1*(table2array(a_table)); Fs = 1000; x = (0:length(y)-1)*(1/Fs); value=1; min_idx_template = 680; max_idx_template = 792; [Heart_Rate,R02] = find_HR_oscar(y, Fs, min_idx_template, max_idx_template); save('OSCAR_ST.mat','R02') figure(1) plot(x,y) xlim([9 14]); xlabel('Sec'); ylabel('mV'); title('ECG - signal 2'); figure(2) plot(x,y) hold on plot(x(R02),y(R02),'ro') hold off xlim([27 34]); xlabel('Sec'); ylabel('mV'); title('R wave detection - signal 2'); t = R02(2:end)*x(end)/length(x); figure(3) plot(t,Heart_Rate) xlabel('Sec'); ylabel('Beat'); title('HR - signal 2');
Le code à l'air de fonctionner correctement, cependant, étant donné qu'il met environ 20 sec à s’exécuter (et apparemment à cause de la fonction cov lors du calcul de la corrélation) j'aurai aimé obtenir conseil sur comment réarranger mon code et/ou peut être réfléchir à une autre méthode tout simplement.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 function [HR,r_idx_vec] = find_HR_oscar(y, Fs, min_idx_template, max_idx_template) max_y = max(y); min_y = min(y); %normalized signal for n = 1:length(y) y_norm(n) = -1+((2*(y(n)-min_y))/((max_y)-(min_y))); end %template template = y(min_idx_template:max_idx_template); %qrs_first_idx if max(template)>abs(min(template)) [~,first_idx] = max(template); positivity=1; else [~,first_idx]=min(template); positivity=2; end r_idx_vec = min_idx_template+first_idx-1; %normalized template for i = 1:length(template) template_norm(i) = -1+((2*(template(i)-min(template)))/((max(template))-(min(template)))); end std_template_norm = std(template_norm); %correlation between template and part of the signal for j=(max_idx_template+1):(length(y)-length(template)+1) part_y_norm = y_norm(j:j+length(template)-1); std_part_y_norm = std(part_y_norm); cov_part_y_template = cov(part_y_norm,template_norm); corr_part_y_template = cov_part_y_template(1,2)/(std_template_norm*std_part_y_norm); if corr_part_y_template >=0.92 more_samples = y_norm(j-length(template):j+length(template)-1); if positivity==1 [val2, idx] = max(more_samples); else [val2, idx] = min(more_samples); end if j-length(template)+idx-1 > r_idx_vec(length(r_idx_vec))+100 r_idx_vec = [r_idx_vec, j-length(template)+idx-1]; end end end %HR detection [BPM] HR = Fs*(1./diff(r_idx_vec)); end
D'avance merci.
Oscar
P.S: Je n'ai pas réussi à Upload le signal qu'on nous a donné à tester.
Partager