-
Notifications
You must be signed in to change notification settings - Fork 0
/
osl.m
131 lines (106 loc) · 3.44 KB
/
osl.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
function [cl,CC] = osl_c(w, CC, Constraints,PARAM)
% Suppress warning
%#ok<*FNDSB>
% Online constrained single linkage
% The reference set is the previous window only
L = min(PARAM.L, size(w,1)); % number of clusers
if ~isempty(Constraints)
MLindex = Constraints(:,3) == 1;
ML = Constraints(MLindex,[1,2]);
CL = Constraints(~MLindex,[1,2]);
CL = sort(CL,2);
else
ML= [];
CL = [];
end
K = size(w,1); % window size
cl = zeros(size(w,1),1); % cluster labels
if isempty(CC)
% first iteration - use cop-kmeans
maxiter = 100;
initialmeans = w(1:L,:);
cl = cop_kmeans(w, ML, CL, maxiter, initialmeans);
CC.RefSet = w;
CC.RefLab = cl;
CC.MaxClusters = L;
else
Ref = CC.RefSet;
Lab = CC.RefLab;
maxc = CC.MaxClusters; % maximum number of clusters
% We assume that constraints do not encrouch different windows.
if ~isempty(Constraints)
% Find the tracks
MLC = Constraints(:,3) == 1;
% To include all nodes in the graph, even those without
% constraints, we need to add 1:K to the graph definition
aux = 1:K;
G = graph([aux'; Constraints(MLC,1)],...
[aux';Constraints(MLC,2)]);
tl = conncomp(G); % track labels in the window
else
tl = 1:K;
end
NT = max(tl); % number of tracks in the window
% (conncomp in MATLAB returns labels 1, 2, 3, ...)
for i = 1:NT % for each track in w
% Process in order of appearance
in_component = find(tl == i); % objects from w in the compoinent
dtc = distance_to_clusters(w(in_component,:),Ref,Lab);
u = unique(Lab);
[~,sorted_clusters] = sort(dtc);
u = u(sorted_clusters); % order of clusters from closest to
% farthest
flag_fitted = false; % try to fit the connected component
for j = 1:numel(u)
% Check compatibility
if ~isempty(CL)
comp = check_compatibility(cl,in_component,CL,u(j));
else
comp = true;
end
if comp
% Add to RefTemp and tidy up
cl(in_component) = u(j);
Ref = [Ref;w(in_component,:)];
Lab = [Lab;ones(numel(in_component),1)*u(j)];
flag_fitted = true;
break
end
end
if ~flag_fitted
% New cluster
Ref = [Ref;w(in_component,:)];
maxc = maxc + 1;
Lab = [Lab; ones(numel(in_component),1)*maxc];
cl(in_component) = maxc;
end
end
CC.Ref = w;
CC.Lab = cl;
CC.MaxClusters = maxc;
end
end
% ====================================================================
function dtc = distance_to_clusters(a,Ref,Lab)
% Calculate distance between a and all clusters (labels)
u = unique(Lab);
for i = 1:numel(u)
t = pdist2(a,Ref(Lab == u(i),:));
dtc(i) = min(t(:));
end
end
%---------------------------------------------------------------------
function out = check_compatibility(current_labels,in_complonent,...
CL,chosen_class)
out = true;
z = find(current_labels == chosen_class);
for k1 = 1:numel(in_complonent)
for k2 = 1:numel(z)
pair = sort([in_complonent(k1),z(k2)]);
if ismember(pair,CL,'rows')
out = false;
break
end
end
end
end