Dimitrios@0
|
1 function [results] = eventDetectionMetrics_classWiseEventBased(outputFile,GTFile)
|
Dimitrios@0
|
2
|
Dimitrios@0
|
3
|
Dimitrios@0
|
4 % Initialize
|
Dimitrios@0
|
5 eventID = {'alert','clearthroat','cough','doorslam','drawer','keyboard','keys',...
|
Dimitrios@0
|
6 'knock','laughter','mouse','pageturn','pendrop','phone','printer','speech','switch'};
|
Dimitrios@0
|
7
|
Dimitrios@0
|
8
|
Dimitrios@0
|
9 % Load event list from output and ground-truth
|
Dimitrios@0
|
10 [onset,offset,classNames] = loadEventsList(outputFile);
|
Dimitrios@0
|
11 [onsetGT,offsetGT,classNamesGT] = loadEventsList(GTFile);
|
Dimitrios@0
|
12
|
Dimitrios@0
|
13
|
Dimitrios@0
|
14 % Total number of detected and reference events per class
|
Dimitrios@0
|
15 Ntot = zeros(16,1);
|
Dimitrios@0
|
16 for i=1:length(onset)
|
Dimitrios@0
|
17 pos = strmatch(classNames{i}, eventID);
|
Dimitrios@0
|
18 Ntot(pos) = Ntot(pos)+1;
|
Dimitrios@0
|
19 end;
|
Dimitrios@0
|
20
|
Dimitrios@0
|
21 Nref = zeros(16,1);
|
Dimitrios@0
|
22 for i=1:length(onsetGT)
|
Dimitrios@0
|
23 pos = strmatch(classNamesGT{i}, eventID);
|
Dimitrios@0
|
24 Nref(pos) = Nref(pos)+1;
|
Dimitrios@0
|
25 end;
|
Dimitrios@0
|
26 I = find(Nref>0); % index for classes present in ground-truth
|
Dimitrios@0
|
27
|
Dimitrios@0
|
28
|
Dimitrios@0
|
29 % Number of correctly transcribed events per class, onset within a +/-100 ms range
|
Dimitrios@0
|
30 Ncorr = zeros(16,1);
|
Dimitrios@0
|
31 NcorrOff = zeros(16,1);
|
Dimitrios@0
|
32 for j=1:length(onsetGT)
|
Dimitrios@0
|
33 for i=1:length(onset)
|
Dimitrios@0
|
34
|
Dimitrios@0
|
35 if( strcmp(classNames{i},classNamesGT{j}) && (abs(onsetGT(j)-onset(i))<=0.1) )
|
Dimitrios@0
|
36 pos = strmatch(classNames{i}, eventID);
|
Dimitrios@0
|
37 Ncorr(pos) = Ncorr(pos)+1;
|
Dimitrios@0
|
38
|
Dimitrios@0
|
39 % If offset within a +/-100 ms range or within 50% of ground-truth event's duration
|
Dimitrios@0
|
40 if abs(offsetGT(j) - offset(i)) <= max(0.1, 0.5 * (offsetGT(j) - onsetGT(j)))
|
Dimitrios@0
|
41 pos = strmatch(classNames{i}, eventID);
|
Dimitrios@0
|
42 NcorrOff(pos) = NcorrOff(pos) +1;
|
Dimitrios@0
|
43 end;
|
Dimitrios@0
|
44
|
Dimitrios@0
|
45 break; % In order to not evaluate duplicates
|
Dimitrios@0
|
46
|
Dimitrios@0
|
47 end;
|
Dimitrios@0
|
48 end;
|
Dimitrios@0
|
49 end;
|
Dimitrios@0
|
50
|
Dimitrios@0
|
51
|
Dimitrios@0
|
52 % Compute onset-only class-wise event-based metrics
|
Dimitrios@0
|
53 Nfp = Ntot-Ncorr;
|
Dimitrios@0
|
54 Nfn = Nref-Ncorr;
|
Dimitrios@0
|
55 Nsubs = min(Nfp,Nfn);
|
Dimitrios@0
|
56 tempRec = Ncorr(I)./(Nref(I)+eps);
|
Dimitrios@0
|
57 tempPre = Ncorr(I)./(Ntot(I)+eps);
|
Dimitrios@0
|
58 results.Rec = mean(tempRec);
|
Dimitrios@0
|
59 results.Pre = mean(tempPre);
|
Dimitrios@0
|
60 tempF = 2*((tempPre.*tempRec)./(tempPre+tempRec+eps));
|
Dimitrios@0
|
61 results.F = mean(tempF);
|
Dimitrios@0
|
62 tempAEER = (Nfn(I)+Nfp(I)+Nsubs(I))./(Nref(I)+eps);
|
Dimitrios@0
|
63 results.AEER = mean(tempAEER);
|
Dimitrios@0
|
64
|
Dimitrios@0
|
65
|
Dimitrios@0
|
66 % Compute onset-offset class-wise event-based metrics
|
Dimitrios@0
|
67 NfpOff = Ntot-NcorrOff;
|
Dimitrios@0
|
68 NfnOff = Nref-NcorrOff;
|
Dimitrios@0
|
69 NsubsOff = min(NfpOff,NfnOff);
|
Dimitrios@0
|
70 tempRecOff = NcorrOff(I)./(Nref(I)+eps);
|
Dimitrios@0
|
71 tempPreOff = NcorrOff(I)./(Ntot(I)+eps);
|
Dimitrios@0
|
72 results.RecOff = mean(tempRecOff);
|
Dimitrios@0
|
73 results.PreOff = mean(tempPreOff);
|
Dimitrios@0
|
74 tempFOff = 2*((tempPreOff.*tempRecOff)./(tempPreOff+tempRecOff+eps));
|
Dimitrios@0
|
75 results.FOff = mean(tempFOff);
|
Dimitrios@0
|
76 tempAEEROff = (NfnOff(I)+NfpOff(I)+NsubsOff(I))./(Nref(I)+eps);
|
Dimitrios@0
|
77 results.AEEROff = mean(tempAEEROff); |