-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathfmmanisopropagation_base.m
192 lines (161 loc) · 7.26 KB
/
fmmanisopropagation_base.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
function [D, V] = fmmanisopropagation_base(W, start_pts, method, L, niter)
% FMMANISOPROPAGATION_BASE - Perform anisotropic fast marching following the
% approach in [SKDCCRRA07,BPC08,PC09] and using [GCM] implementation of the
% papers [PLPWDFS06a,PLPWDFS06b].
%
% D = FMMANISOPROPAGATION_BASE(W, start_pts, L);
% [D, V] = FMMANISOPROPAGATION_BASE(W, start_pts, method, L, niter);
%
% Inputs:
% W : cost function; it should be a (m x n x 2) (for 2D vector field) or
% a (m x n x 2 x 2) (for tensor field) weight matrix.
% start_pts : a (2 x k) matrix where k is the number of starting points.
% end_pts : a (2 x l) matrix where l is the number of ending points; the
% FMM propagation stops when these points are reached.
% method : logical boolean used for selecting the method: true for using
% FMMANISOPROPAGATION_MEX and false for using FM2DANISO_MEX.
% L : optional constraint map used when method=true to reduce the set of
% explored points, as only points with current distance smaller than
% their values in L will be visited; set entries to -Inf in L if you do
% not want points to be visited by FMM; default: L=Inf, ie. all points
% are visited.
% niter : maximum number of iterations; default: niter=Inf.
%
% Outputs:
% D : a 2D array containing the value of the distance function to seed.
% V : optional variable returned when method=true; index of the closest
% point from the set of starting points (0 for points which have not
% been reached); V provide a Voronoi decomposition of the domain.
%
% Remark:
% if the Voronoi diagram V is desired in output (see above), the function
% FM2DANISO_MEX should be called, hence the option method should be set to
% false.
%
% References:
% [PLPWDFS06a] E. Prados, C. Lenglet, J. Pons, N. Wotawa, R. Deriche, O.
% Faugeras, S. Soatto: "Control theory and fast marching methods for
% brain connectivity mapping", INRIA Research Report 5845, 2006.
% [PLPWDFS06b] E. Prados, C. Lenglet, J. Pons, N. Wotawa, R. Deriche, O.
% Faugeras, S. Soatto: "Control theory and fast marching methods for
% brain connectivity mapping", Proc. IEEE CVPR, pp. 1076?1083, 2006.
% [SKDCCRRA07] M. Sermesant, E. Konukoglu, H. Delingette, Y. Coudiere,
% P. Chinchapatnam, K. Rhode, R. Razavi and N. Ayache: "An anisotropic
% multi-front fast marching method for real-time simulation of cardiac
% electrophysiology, Proc. FIMH, LNCS 4466, pp. 160-169, 2007,
% [BPC08] S. Bougleux, G. Peyre, and L. Cohen: "Anisotropic geodesics for
% perceptual grouping and domain meshing", Proc. ECCV, vol. 2, pp.
% 129-142, 2008.
% [PC09] G. Peyre, and L. Cohen: "Geodesic methods for shape and surface
% processing", in "Advances in Computational Vision and Medical Image
% Processing: Methods and Applications", vol. 13 of "Computational
% Methods in Applied Sciences", pp. 29-56, Springer, 2009.
% [GCM] See GCM - Geodesic Connectivity Mapping source code available at
% http://gcm.gforge.inria.fr/GCM-Publications.html
%
% See also
% Related: FMM, FMM_BASE, FMMISOPROPAGATION_BASE, DIJKSTRAPROPAGATION_BASE,
% IM2FRONT_BASE, POTENTIAL2FRONT_BASE --
% Called: FMMANISOPROPAGATION_MEX, FM2DANISO_MEX.
% we allow variable number of inputs
if nargin <=4, niter = Inf;
if nargin<=3, L = [];
if nargin<=2, method = true; end
end
end
% ensure this outside the function
% if size(start_pts,1)~=2
% error('fmmanisopropagation_base:inputerror', ...
% 'seed points should be (2 x k) dimensional');
% end
%% Check/set the input tensor field used for anisotropic propagation via
% FMM
d = nb_dims(W);
m = size(W,1);
n = size(W,2);
if d==2 % a scalar field has been passed: use isotropic FMM instead
warning('fmmanisopropagation_base:inputwarning', ...
'use isotropic FMM approach with scalar cost field');
% W = gstfeature(W(:,:,1,1),W(:,:,2,2),W(:,:,1,2),'norm');
% TODO: rather call isotropic FMM with FMMISOPROPAGATION_BASE
return;
elseif d==3 % a vector field has been passed
V = cat(3, -W(:,:,2), W(:,:,1)); % orthogonal vector
W = gstdecomp(W, V, ones(m,n), ones(m,n) );
elseif d~=4 % all other cases: hope not to reach this point
error('fmmanisopropagation_base:inputerror', ...
'input cost function should be a vector of a tensor field');
end
% !!! The following code runs with square matrices (ie. size(w,1)==size(w,2)),
% therefore we have to transform the input !!!
if m~=n
M = max([m n]);
W = padarray(W, [M-m M-n], 1, 'post');
else
M = m;
end
pad = 0;
% pad = 1;
if pad, W = padarray(W,[pad pad], 1, 'both'); end %#ok
%% Launch the mex files
if method && exist('fmmanisopropagation_mex','file')
% at that point, we should have d=4: W is a structure tensor field
% in order to use fmmanisopropagation_mex (see [GCM] source code), we
% need to inject the 2D space into a 3D space
% % practical issue: how to deal with null tensor
% [l1, l2, e1, e2] = gstdecomp(W);
% I = l1==0;
% l1(I) = 1e-9; % eps for C implementation
% % l2(I) = 0;
% % v = e1(:,:,1); v(I) = 1; e1(:,:,1) = v;
% % v = e1(:,:,2); v(I) = 0; e1(:,:,2) = v;
% % v = e2(:,:,1); v(I) = 0; e2(:,:,1) = v;
% % v = e2(:,:,2); v(I) = 1; e2(:,:,2) = v;
% W = gstdecomp(l1, l2, e1, e2);
if size(W,3)==2 && size(W,4)==2
% we transform the 2D vector field into a 3D field
W1 = zeros(M+2*pad, M+2*pad, 3, 3);
W1(:,:,1:2,1:2) = W;
W1(:,:,3,3) = 1;
W = reshape(W1, [M+2*pad M+2*pad, 1 3 3]);
% convert to correct size
W = cat(4, W(:,:,:,1,1), W(:,:,:,1,2), W(:,:,:,1,3), ...
W(:,:,:,2,2), W(:,:,:,2,3), W(:,:,:,3,3) );
end
% padd to avoid boundary problem
W = cat(1, W(1,:,:,:), W, W(end,:,:,:));
W = cat(2, W(:,1,:,:), W, W(:,end,:,:));
W = cat(3, W(:,:,1,:), W, W(:,:,end,:));
% prepare the set of points
start_pts(end+1,:) = 1; % we represent the point in a 3D space
% launch the anisotropic FMM
% start_pts = start_pts-1;
if isempty(L), L = Inf(size(W,1), size(W,2), 3); % ones
end
% if pad, L = padarray(L, [pad pad], -Inf, 'both'); end
alpha = 0; % euclidean norm: see source code [GCM], functions
% AnisotropicTensorDistanceConfidence.h and AnisotropicTensorDistance.h
[D, V] = fmmanisopropagation_mex(W, L, alpha, start_pts, niter);
% remove boundary problems
D = D(2:end-1, 2:end-1, 2);
if sum(V(:))==0, V = []; % no Voronoi output... problem here!!!
else V = V(2:end-1, 2:end-1, 2); end
elseif ~method && exist('fm2daniso_mex','file')
step = [1; 1];
% step = [1/size(W,1), 1/size(W,2)];
[D, dum1, dum2, V] = fm2daniso_mex(step, W, start_pts);
else % hope not to reach this point either
error('fmmanisopropagation_base:libraryerror',...
'method fmmanisopropagation_base not available');
end
%% The final touch...
if pad % get rid of the boundary pad
D = D(1+pad:end-pad, 1+pad:end-pad); %#ok
end
if m~=n % get rid of the dimension pad: finally reset to the correct size
D = D(1:m,1:n);
if ~isempty(V), V = V(1:m,1:n); end
end
% reset to Matlab Inf values
D(D>1e16) = Inf;
end