-
Notifications
You must be signed in to change notification settings - Fork 32
/
run_tracker.m
250 lines (194 loc) · 7.85 KB
/
run_tracker.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
%
% High-Speed Tracking with Kernelized Correlation Filters
%
% Joao F. Henriques, 2014
% http://www.isr.uc.pt/~henriques/
%
% Main interface for Kernelized/Dual Correlation Filters (KCF/DCF).
% This function takes care of setting up parameters, loading video
% information and computing precisions. For the actual tracking code,
% check out the TRACKER function.
%
% RUN_TRACKER
% Without any parameters, will ask you to choose a video, track using
% the Gaussian KCF on HOG, and show the results in an interactive
% figure. Press 'Esc' to stop the tracker early. You can navigate the
% video using the scrollbar at the bottom.
%
% RUN_TRACKER VIDEO
% Allows you to select a VIDEO by its name. 'all' will run all videos
% and show average statistics. 'choose' will select one interactively.
%
% RUN_TRACKER VIDEO KERNEL
% Choose a KERNEL. 'gaussian'/'polynomial' to run KCF, 'linear' for DCF.
%
% RUN_TRACKER VIDEO KERNEL FEATURE
% Choose a FEATURE type, either 'hog' or 'gray' (raw pixels).
%
% RUN_TRACKER(VIDEO, KERNEL, FEATURE, SHOW_VISUALIZATION, SHOW_PLOTS)
% Decide whether to show the scrollable figure, and the precision plot.
%
% Useful combinations:
% >> run_tracker choose gaussian hog %Kernelized Correlation Filter (KCF)
% >> run_tracker choose linear hog %Dual Correlation Filter (DCF)
% >> run_tracker choose gaussian gray %Single-channel KCF (ECCV'12 paper)
% >> run_tracker choose linear gray %MOSSE filter (single channel)
%
function [precision, fps] = run_tracker(video, kernel_type, feature_type, show_visualization, show_plots)
%path to the videos (you'll be able to choose one with the GUI).
% base_path = './data/Benchmark/';
base_path = '~/Downloads/PF_CNN_SVM/data/';
%default settings
if nargin < 1, video = 'choose'; end
if nargin < 2, kernel_type = 'gaussian'; end
if nargin < 3, feature_type = 'hog'; end
if nargin < 4, show_visualization = ~strcmp(video, 'all'); end
if nargin < 5, show_plots = ~strcmp(video, 'all'); end
%parameters according to the paper. at this point we can override
%parameters based on the chosen kernel or feature type
kernel.type = kernel_type;
features.gray = false;
features.hog = false;
padding = 1.5; %extra area surrounding the target
% padding = 2; %extra area surrounding the target
lambda = 1e-4; %regularization
output_sigma_factor = 0.1; %spatial bandwidth (proportional to target)
switch feature_type
case 'gray',
interp_factor = 0.075; %linear interpolation factor for adaptation
kernel.sigma = 0.2; %gaussian kernel bandwidth
kernel.poly_a = 1; %polynomial kernel additive term
kernel.poly_b = 7; %polynomial kernel exponent
features.gray = true;
cell_size = 1;
case 'hog',
interp_factor = 0.02;
kernel.sigma = 0.5;
kernel.poly_a = 1;
kernel.poly_b = 9;
features.hog = true;
features.hog_orientations = 9;
cell_size = 4;
case 'deep'
interp_factor = 0.02;
kernel.sigma = 0.5;
kernel.poly_a = 1;
kernel.poly_b = 9;
features.deep = true;
cell_size = 8;
init_vgg;
otherwise
error('Unknown feature.')
end
assert(any(strcmp(kernel_type, {'linear', 'polynomial', 'gaussian'})), 'Unknown kernel.')
switch video
case 'choose',
%ask the user for the video, then call self with that video name.
video = choose_video(base_path);
if ~isempty(video),
[precision, fps] = run_tracker(video, kernel_type, ...
feature_type, show_visualization, show_plots);
if nargout == 0, %don't output precision as an argument
clear precision
end
end
case 'all',
%all videos, call self with each video name.
%only keep valid directory names
dirs = dir(base_path);
videos = {dirs.name};
videos(strcmp('.', videos) | strcmp('..', videos) | ...
strcmp('anno', videos) | ~[dirs.isdir]) = [];
%the 'Jogging' sequence has 2 targets, create one entry for each.
%we could make this more general if multiple targets per video
%becomes a common occurence.
videos(strcmpi('Jogging', videos)) = [];
videos(end+1:end+2) = {'Jogging.1', 'Jogging.2'};
all_precisions = zeros(numel(videos),1); %to compute averages
all_fps = zeros(numel(videos),1);
if ~exist('matlabpool', 'file'),
%no parallel toolbox, use a simple 'for' to iterate
for k = 1:numel(videos),
[all_precisions(k), all_fps(k)] = run_tracker(videos{k}, ...
kernel_type, feature_type, show_visualization, show_plots);
end
else
%evaluate trackers for all videos in parallel
if matlabpool('size') == 0,
matlabpool open;
end
parfor k = 1:numel(videos),
[all_precisions(k), all_fps(k)] = run_tracker(videos{k}, ...
kernel_type, feature_type, show_visualization, show_plots);
end
end
%compute average precision at 20px, and FPS
mean_precision = mean(all_precisions);
fps = mean(all_fps);
fprintf('\nAverage precision (20px):% 1.3f, Average FPS:% 4.2f\n\n', mean_precision, fps)
if nargout > 0,
precision = mean_precision;
end
case 'benchmark',
%running in benchmark mode - this is meant to interface easily
%with the benchmark's code.
%get information (image file names, initial position, etc) from
%the benchmark's workspace variables
seq = evalin('base', 'subS');
target_sz = seq.init_rect(1,[4,3]);
pos = seq.init_rect(1,[2,1]) + floor(target_sz/2);
img_files = seq.s_frames;
video_path = [];
%call tracker function with all the relevant parameters
positions = tracker(video_path, img_files, pos, target_sz, ...
padding, kernel, lambda, output_sigma_factor, interp_factor, ...
cell_size, features, false);
%return results to benchmark, in a workspace variable
rects = [positions(:,2) - target_sz(2)/2, positions(:,1) - target_sz(1)/2];
rects(:,3) = target_sz(2);
rects(:,4) = target_sz(1);
res.type = 'rect';
res.res = rects;
assignin('base', 'res', res);
otherwise
%we were given the name of a single video to process.
%get image file names, initial state, and ground truth for evaluation
[img_files, pos, target_sz, ground_truth, video_path] = load_video_info(base_path, video);
%call tracker function with all the relevant parameters
[positions, time] = tracker(video_path, img_files, pos, target_sz, ...
padding, kernel, lambda, output_sigma_factor, interp_factor, ...
cell_size, features, show_visualization);
clear results
results{1}.type = 'rect';
x = positions(:,2);
y = positions(:,1);
w = target_sz(2) * ones(size(x, 1), 1);
h = target_sz(1) * ones(size(x, 1), 1);
results{1}.res = [x-w/2, y-h/2, w, h];
results{1}.startFame = 1;
results{1}.annoBegin = 1;
results{1}.len = size(x, 1);
frames = {'David', 300, 465;%770
'Football1', 1, 74;
'Freeman3', 1, 460;
'Freeman4', 1, 283};
idx = find(strcmpi(video, frames(:,1)));
if ~isempty(idx),
results{1}.startFame = frames{idx, 2};
results{1}.len = frames{idx, 3} - frames{idx, 2}; +1;
end
res_path = ['KCF_results_' feature_type '/'];
if ~isdir(res_path)
mkdir(res_path);
end
save([res_path lower(video) '_kcf_' feature_type '8.mat'], 'results');
%calculate and show precision plot, as well as frames-per-second
precisions = precision_plot(positions, ground_truth, video, show_plots);
fps = numel(img_files) / time;
fprintf('%12s - Precision (20px):% 1.3f, FPS:% 4.2f\n', video, precisions(20), fps)
if nargout > 0,
%return precisions at a 20 pixels threshold
precision = precisions(20);
end
end
end