-
Notifications
You must be signed in to change notification settings - Fork 19
/
VOCevaldet.m
executable file
·123 lines (108 loc) · 3.25 KB
/
VOCevaldet.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
function [rec,prec,ap] = VOCevaldet(VOCopts,id,cls,draw)
% load test set
cp=sprintf(VOCopts.annocachepath,VOCopts.testset);
if exist(cp,'file')
fprintf('%s: pr: loading ground truth\n',cls);
load(cp,'gtids','recs');
else
[gtids,t]=textread(sprintf(VOCopts.imgsetpath,VOCopts.testset),'%s %d');
for i=1:length(gtids)
% display progress
if toc>1
fprintf('%s: pr: load: %d/%d\n',cls,i,length(gtids));
drawnow;
tic;
end
% read annotation
recs(i)=PASreadrecord(sprintf(VOCopts.annopath,gtids{i}));
end
save(cp,'gtids','recs');
end
fprintf('%s: pr: evaluating detections\n',cls);
% hash image ids
hash=VOChash_init(gtids);
% extract ground truth objects
npos=0;
gt(length(gtids))=struct('BB',[],'diff',[],'det',[]);
for i=1:length(gtids)
% extract objects of class
clsinds=strmatch(cls,{recs(i).objects(:).class},'exact');
gt(i).BB=cat(1,recs(i).objects(clsinds).bbox)';
gt(i).diff=[recs(i).objects(clsinds).difficult];
gt(i).det=false(length(clsinds),1);
npos=npos+sum(~gt(i).diff);
end
% load results
[ids,confidence,b1,b2,b3,b4]=textread(sprintf(VOCopts.detrespath,id,cls),'%s %f %f %f %f %f');
BB=[b1 b2 b3 b4]';
% sort detections by decreasing confidence
[sc,si]=sort(-confidence);
ids=ids(si);
BB=BB(:,si);
% assign detections to ground truth objects
nd=length(confidence);
tp=zeros(nd,1);
fp=zeros(nd,1);
tic;
for d=1:nd
% display progress
if toc>1
fprintf('%s: pr: compute: %d/%d\n',cls,d,nd);
drawnow;
tic;
end
% find ground truth image
i=VOChash_lookup(hash,ids{d});
if isempty(i)
error('unrecognized image "%s"',ids{d});
elseif length(i)>1
error('multiple image "%s"',ids{d});
end
% assign detection to ground truth object if any
bb=BB(:,d);
ovmax=-inf;
for j=1:size(gt(i).BB,2)
bbgt=gt(i).BB(:,j);
bi=[max(bb(1),bbgt(1)) ; max(bb(2),bbgt(2)) ; min(bb(3),bbgt(3)) ; min(bb(4),bbgt(4))];
iw=bi(3)-bi(1)+1;
ih=bi(4)-bi(2)+1;
if iw>0 & ih>0
% compute overlap as area of intersection / area of union
ua=(bb(3)-bb(1)+1)*(bb(4)-bb(2)+1)+...
(bbgt(3)-bbgt(1)+1)*(bbgt(4)-bbgt(2)+1)-...
iw*ih;
ov=iw*ih/ua;
if ov>ovmax
ovmax=ov;
jmax=j;
end
end
end
% assign detection as true positive/don't care/false positive
if ovmax>=VOCopts.minoverlap
if ~gt(i).diff(jmax)
if ~gt(i).det(jmax)
tp(d)=1; % true positive
gt(i).det(jmax)=true;
else
fp(d)=1; % false positive (multiple detection)
end
end
else
fp(d)=1; % false positive
end
end
% compute precision/recall
fp=cumsum(fp);
tp=cumsum(tp);
rec=tp/npos;
prec=tp./(fp+tp);
ap=VOCap(rec,prec);
if draw
% plot precision/recall
plot(rec,prec,'-');
grid;
xlabel 'recall'
ylabel 'precision'
title(sprintf('class: %s, subset: %s, AP = %.3f',cls,VOCopts.testset,ap));
end