-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathgetFeaturesFromWindow.m
166 lines (135 loc) · 5.78 KB
/
getFeaturesFromWindow.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
function [members, F, couples, myfeatures, detectedGroups] = getFeaturesFromWindow(myF, index_start, index_end, video_par, model_par)
% select the working window
myF = myF(index_start : index_end, :);
F = myF;
% extract the pedestrians which can be seen inside this window
members = unique(myF(:, 2));
% it is also very useful to verify that each pedestrians will remain in the
% scene for at least a minimum number of frames, let's say 4 - so that we
% will be able to actually work on some data. shorter sequences will thus
% be ignored!
for i = 1 : size(members)
if sum(myF(:, 2) == members(i)) < 4
% delete the trajectory of the user from this scene
myF(myF(:, 2) == members(i), :) = [];
end
end
% update members
members = unique(myF(:, 2));
%% PERSONAL FEATURES
% (i.e. time, position and velocity)
% path is my global variable which contains structured information about
% the trajectory of each pedestrian
path = struct;
path(1).mts = [];
% now i check my video/simulation frame by frame
for f = myF(1, 1) : myF(end, 1)
% since the number of rows in myF associated with each frame is not
% fixed, we have to extract subwindows regarding the current frame
frame_idxs = myF(:, 1) == f;
% I just need the information about this particular frame
pedestrians = myF(frame_idxs, 2);
locations = myF(frame_idxs, [3 5]);
% now, for each pedestrian, I can update its multivariate timeseries
for i = 1 : size(pedestrians)
% initialize the mts if this is the first frame which he appears in
if (size(path, 2) < pedestrians(i))
path(pedestrians(i)).mts = [];
end
if model_par.include_derivatives
% check if we can calculate the velocities
if (size(path(pedestrians(i)).mts, 1) > 0)
velocities = locations(i, :) - path(pedestrians(i)).mts(end, 2:3);
else
velocities = [NaN, NaN];
end
% update the vector
path(pedestrians(i)).mts = [path(pedestrians(i)).mts; f, locations(i, :), velocities];
else
% just update the vector
path(pedestrians(i)).mts = [path(pedestrians(i)).mts; f, locations(i, :)];
end
end
end
% just remove the first line since we don't have first order
% information about it (i.e. derivatives)
for i = 1 : size(members)
path(members(i)).mts = path(members(i)).mts(2:end, :);
end
%% PAIR-WISE FEATURES
% (i.e. md-dwt, proxemics, granger causality, heat map)
% establish every possible couple
c = combnk(1:size(members, 1), 2);
couples = zeros(size(c, 1), 2);
% initialize the feature matrix describing the couples in the scene
myfeature_1 = zeros(size(c, 1), 1);
myfeature_2 = zeros(size(c, 1), 1);
myfeature_3 = zeros(size(c, 1), 1);
myfeature_4 = zeros(size(c, 1), 1);
% initialize the cell array that will eventually contain the groups
% detected by the HM optimization
allHeatMaps = cell(size(c, 1), 1);
detectedGroups = [];
% compute features for each couple!
for i = 1 : size(c, 1)
% select the two pedestrians that will be considered
a = c(i, 1); b = c(i, 2);
couples(i, :) = [members(a), members(b)];
%% 1) compute PROXEMICS
% extract the multi dimensional data (velocities too if included)
t = path(members(a)).mts(:, 2:end)';
r = path(members(b)).mts(:, 2:end)';
if model_par.features(1) == 1
% get temporal information - we need them because the proxemics is
% gonna be computed (as opposed to the dtw) only when both pedestrians
% will be considered available in the scene
time_t = path(members(a)).mts(:, 1)';
time_r = path(members(b)).mts(:, 1)';
% call the most basic proxemics function ever written
myfeature_1(i) = prox(time_t, time_r, t, r);
end
%% 2) compute MD-DWT
if model_par.features(2) == 1
% call the dtwk function by Felty (2005)
[dist, k] = dtwk(t, r);
% since the distance higly depends on the number of points that are
% compared, it has to be normalized!
myfeature_2(i) = dist / k;
end
%% 3) compute GRANGER CAUSALITY
if model_par.features(3) == 1
% granger causality can be a bit tricky if you want to use it without
% violating its original meaning. the first assumption we want to make
% is that we are interested in evaluating if there is causality at all,
% so we'll just keep the biggest one of the two!
% model order: past information that will be used to predict future
% trends
granger_order = 4;
% run the functions both ways
warning('off','MATLAB:rankDeficientMatrix');
F1 = granger(path(members(a)).mts, path(members(b)).mts, granger_order);
F2 = granger(path(members(b)).mts, path(members(a)).mts, granger_order);
warning('on','MATLAB:rankDeficientMatrix');
% just keep the most informative causality
myfeature_3(i) = max(F1, F2);
end
%% 4) compute HEAT MAPS
if model_par.features(4) == 1 || model_par.useHMGroupDetection
[allHeatMaps{i}, myfeature_4(i)] = heatMap(path(members(a)).mts(:, 1:3), path(members(b)).mts(:, 1:3), video_par);
if model_par.features(4) ~= 1
myfeature_4(i) = 0;
end
end
end
myfeatures = [myfeature_1, myfeature_2, myfeature_3, myfeature_4];
myfeatures = myfeatures(:, model_par.features == 1);
%% HEAT MAPS COARSE GROUP DETECTION
% initialize the detectedGroups to all the couples, that is equivalent not
% to run the HM detection
detectedGroups{1} = couples;
% if specified, run this heuristic to remove the improbable groups from the
% scene
if model_par.useHMGroupDetection
detectedGroups = detectGroups(couples, allHeatMaps);
end
end