-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathevaluate_detections_on_test.m
executable file
·118 lines (102 loc) · 3.57 KB
/
evaluate_detections_on_test.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
function [gt_ids, gt_bboxes, gt_isclaimed, tp, fp, duplicate_detections] = ...
evaluate_detections_on_test(bboxes, confidences, image_ids, label_path)
% 'bboxes' is Nx4, N is the number of non-overlapping detections, and each
% row is [x_min, y_min, x_max, y_max]
% 'confidences' is the Nx1 (final cascade node) confidence of each
% detection.
% 'image_ids' is the Nx1 image names for each detection.
% This code is based on the 2010 Pascal VOC toolkit:
% http://pascallin.ecs.soton.ac.uk/challenges/VOC/voc2010/index.html#devkit
% and James Hays' CS 4495/6476 assignment files:
% http://www.cc.gatech.edu/~hays/compvision/proj5/
%this lists the ground truth bounding boxes for the test set.
fid = fopen(label_path);
gt_info = textscan(fid, '%s %d %d %d %d');
fclose(fid);
gt_ids = gt_info{1,1};
gt_bboxes = [gt_info{1,2}, gt_info{1,3}, gt_info{1,4}, gt_info{1,5}];
gt_bboxes = double(gt_bboxes);
gt_isclaimed = zeros(length(gt_ids),1);
npos = size(gt_ids,1); %total number of true positives.
% sort detections by decreasing confidence
[sc,si]=sort(-confidences);
image_ids=image_ids(si);
bboxes =bboxes(si,:);
% assign detections to ground truth objects
nd=length(confidences);
tp=zeros(nd,1);
fp=zeros(nd,1);
duplicate_detections = zeros(nd,1);
tic;
for d=1:nd
% display progress
if toc>1
fprintf('pr: compute: %d/%d\n',d,nd);
drawnow;
tic;
end
cur_gt_ids = strcmp(image_ids{d}, gt_ids); %will this be slow?
bb = bboxes(d,:);
ovmax=-inf;
for j = find(cur_gt_ids')
bbgt=gt_bboxes(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 %higher overlap than the previous best?
ovmax=ov;
jmax=j;
end
end
end
% assign detection as true positive/don't care/false positive
if ovmax >= 0.3
if ~gt_isclaimed(jmax)
tp(d)=1; % true positive
gt_isclaimed(jmax)=true;
else
fp(d)=1; % false positive (multiple detection)
duplicate_detections(d) = 1;
end
else
fp(d)=1; % false positive
end
end
% compute cumulative precision/recall
cum_fp=cumsum(fp);
cum_tp=cumsum(tp);
rec=cum_tp/npos;
prec=cum_tp./(cum_fp+cum_tp);
ap=VOCap(rec,prec);
% plot precision/recall
figure(12)
plot(rec,prec,'-');
axis([0 1 0 1])
grid;
xlabel 'recall'
ylabel 'precision'
title(sprintf('Average Precision = %.3f',ap));
set(12, 'Color', [.988, .988, .988])
pause(0.1) %let's ui rendering catch up
average_precision_image = frame2im(getframe(12));
% getframe() is unreliable. Depending on the rendering settings, it will
% grab foreground windows instead of the figure in question. It could also
% return a partial image.
imwrite(average_precision_image, 'average_precision.png')
figure(13)
plot(cum_fp,rec,'-')
axis([0 300 0 1])
grid;
xlabel 'False positives'
ylabel 'Number of correct detections (recall)'
%% Re-sort return variables so that they are in the order of the input bboxes
reverse_map(si) = 1:nd;
tp = tp(reverse_map);
fp = fp(reverse_map);
duplicate_detections = duplicate_detections(reverse_map);