-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathevalRes.m
108 lines (103 loc) · 3.75 KB
/
evalRes.m
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
function [gt,dt] = evalRes( gt0, dt0, thr, mul )
% Evaluates detections against ground truth data.
%
% Uses modified Pascal criteria that allows for "ignore" regions. The
% Pascal criteria states that a ground truth bounding box (gtBb) and a
% detected bounding box (dtBb) match if their overlap area (oa):
% oa(gtBb,dtBb) = area(intersect(gtBb,dtBb)) / area(union(gtBb,dtBb))
% is over a sufficient threshold (typically .5). In the modified criteria,
% the dtBb can match any subregion of a gtBb set to "ignore". Choosing
% gtBb' in gtBb that most closely matches dtBb can be done by using
% gtBb'=intersect(dtBb,gtBb). Computing oa(gtBb',dtBb) is equivalent to
% oa'(gtBb,dtBb) = area(intersect(gtBb,dtBb)) / area(dtBb)
% For gtBb set to ignore the above formula for oa is used.
%
% Highest scoring detections are matched first. Matches to standard,
% (non-ignore) gtBb are preferred. Each dtBb and gtBb may be matched at
% most once, except for ignore-gtBb which can be matched multiple times.
% Unmatched dtBb are false-positives, unmatched gtBb are false-negatives.
% Each match between a dtBb and gtBb is a true-positive, except matches
% between dtBb and ignore-gtBb which do not affect the evaluation criteria.
%
% In addition to taking gt/dt results on a single image, evalRes() can take
% cell arrays of gt/dt bbs, in which case evaluation proceeds on each
% element. Use bbGt>loadAll() to load gt/dt for multiple images.
%
% Each gt/dt output row has a flag match that is either -1/0/1:
% for gt: -1=ignore, 0=fn [unmatched], 1=tp [matched]
% for dt: -1=ignore, 0=fp [unmatched], 1=tp [matched]
%
% USAGE
% [gt, dt] = bbGt( 'evalRes', gt0, dt0, [thr], [mul] )
%
% INPUTS
% gt0 - [mx5] ground truth array with rows [x y w h ignore]
% dt0 - [nx5] detection results array with rows [x y w h score]
% thr - [.5] the threshold on oa for comparing two bbs
% mul - [0] if true allow multiple matches to each gt
%
% OUTPUTS
% gt - [mx5] ground truth results [x y w h match]
% dt - [nx6] detection results [x y w h score match]
%
% EXAMPLE
%
% See also bbGt, bbGt>compOas, bbGt>loadAll
% get parameters
if(nargin<3 || isempty(thr)), thr=.7; end
if(nargin<4 || isempty(mul)), mul=0; end
% if gt0 and dt0 are cell arrays run on each element in turn
if( iscell(gt0) && iscell(dt0) ), n=length(gt0);
assert(length(dt0)==n); gt=cell(1,n); dt=gt;
for i=1:n, [gt{i},dt{i}] = evalRes(gt0{i},dt0{i},thr,mul); end; return;
end
% check inputs
if(isempty(gt0)), gt0=zeros(0,5); end
if(isempty(dt0)), dt0=zeros(0,5); end
assert( size(dt0,2)==5 ); nd=size(dt0,1);
assert( size(gt0,2)==5 ); ng=size(gt0,1);
% sort dt highest score first, sort gt ignore last
[~,ord]=sort(dt0(:,5),'descend'); dt0=dt0(ord,:);
[~,ord]=sort(gt0(:,5),'ascend'); gt0=gt0(ord,:);
gt=gt0; dt=dt0; dt=[dt zeros(nd,1)];
gt(:,5)=-gt(:,5);
% Attempt to match each (sorted) dt to each (sorted) gt
oa = compOas( dt(:,1:4), gt(:,1:4), gt(:,5)==-1 );
for d = 1:nd
bstOa = thr;
bstg = 0;
bstm = 0; % info about best match so far
for g = 1:ng
% if this gt already matched, continue to next gt
m = gt(g,5);
if(m==1 && ~mul)
continue;
end
% if dt already matched, and on ignore gt, nothing more to do
if(bstm~=0 && m==-1)
break;
end
% compute overlap area, continue to next gt unless better match made
if(oa(d,g)<bstOa)
continue;
end
% match successful and best so far, store appropriately
bstOa = oa(d,g);
bstg = g;
if(m==0)
bstm = 1;
else
bstm = -1;
end
end;
g = bstg;
m = bstm;
% store type of match for both dt and gt
if(m==-1)
dt(d,6) = m;
elseif(m==1)
gt(g,5) = m;
dt(d,6) = m;
end
end
end