|
14 | 14 | % Options: |
15 | 15 | % 'euclidean' Use Euclidean (L2) distance metric (default) |
16 | 16 | % 'cityblock' Use cityblock or Manhattan (L1) distance metric |
17 | | -% 'show',D Show the iterations of the computation, with a delay of D seconds |
18 | | -% between frames. |
| 17 | +% |
| 18 | +% 'animate' Show the iterations of the computation |
| 19 | +% 'delay',D Delay of D seconds between animation frames (default 0.2s) |
| 20 | +% 'movie',M Save animation to a movie file or folder |
| 21 | +% |
19 | 22 | % 'noipt' Don't use Image Processing Toolbox, even if available |
20 | 23 | % 'novlfeat' Don't use VLFeat, even if available |
21 | 24 | % 'nofast' Don't use IPT, VLFeat or imorph, even if available. |
22 | 25 | % |
| 26 | +% 'delay' |
| 27 | +% |
23 | 28 | % Notes:: |
24 | 29 | % - For the first case Image Processing Toolbox (IPT) or VLFeat will be used if |
25 | 30 | % available, searched for in that order. They use a 2-pass rather than |
26 | 31 | % iterative algorithm and are much faster. |
27 | 32 | % - Options can be used to disable use of IPT or VLFeat. |
28 | 33 | % - If IPT or VLFeat are not available, or disabled, then imorph is used. |
29 | 34 | % - If IPT, VLFeat or imorph are not available a slower M-function is used. |
30 | | -% - If the 'show' option is given then imorph is used. |
31 | | -% - Using imorph requires iteration and is slow. |
| 35 | +% - If the 'animate' option is given then the MATLAB implementation is used. |
| 36 | +% - Using imorph requires iteration and is slow. |
32 | 37 | % - For the second case the Machine Vision Toolbox function imorph is required. |
33 | 38 | % - imorph is a mex file and must be compiled. |
34 | 39 | % - The goal is given as [X,Y] not MATLAB [row,col] format. |
35 | 40 | % |
36 | | -% See also IMORPH, DXform. |
| 41 | +% See also IMORPH, DXform, Animate. |
37 | 42 |
|
38 | 43 |
|
39 | 44 |
|
|
58 | 63 |
|
59 | 64 | function dx = distancexform(occgrid, varargin) |
60 | 65 |
|
61 | | - opt.show = 0; |
| 66 | + opt.delay = 0.2; |
62 | 67 | opt.ipt = true; |
63 | 68 | opt.vlfeat = true; |
64 | 69 | opt.fast = true; |
65 | 70 | opt.metric = {'euclidean', 'cityblock'}; |
| 71 | + opt.animate = false; |
| 72 | + opt.movie = []; |
66 | 73 | [opt,args] = tb_optparse(opt, varargin); |
67 | | - if opt.show |
| 74 | + if opt.movie |
| 75 | + opt.animate = true; |
| 76 | + end |
| 77 | + if opt.animate |
| 78 | + opt.fast = false; |
68 | 79 | opt.ipt = false; |
69 | 80 | opt.vlfeat = false; |
| 81 | + clf |
70 | 82 | end |
71 | 83 | count = []; |
72 | 84 | switch opt.metric |
|
111 | 123 |
|
112 | 124 | occgrid = imorph(occgrid, m, 'plusmin'); |
113 | 125 | count = count+1; |
114 | | - if opt.show |
| 126 | + if opt.animate |
115 | 127 | cmap = [1 0 0; gray(count)]; |
116 | 128 | colormap(cmap) |
117 | 129 | image(occgrid+1, 'CDataMapping', 'direct'); |
118 | 130 | set(gca, 'Ydir', 'normal'); |
119 | 131 | xlabel('x'); |
120 | 132 | ylabel('y'); |
121 | | - pause(opt.show); |
| 133 | + pause(opt.delay); |
122 | 134 | end |
123 | 135 |
|
124 | 136 | ninfnow = sum( isinf(occgrid(:)) ); % current number of Infs |
|
152 | 164 |
|
153 | 165 | count = 0; |
154 | 166 | ninf = Inf; % number of infinities in the map |
| 167 | + anim = Animate(opt.movie); |
155 | 168 | while 1 |
156 | 169 |
|
157 | 170 | occgrid = dxstep(occgrid, m); |
158 | 171 | occgrid(nans) = NaN; |
159 | 172 |
|
160 | 173 | count = count+1; |
161 | | - if opt.show |
| 174 | + if opt.animate |
162 | 175 | cmap = [1 0 0; gray(count)]; |
163 | 176 | colormap(cmap) |
164 | 177 | image(occgrid+1, 'CDataMapping', 'direct'); |
165 | 178 | set(gca, 'Ydir', 'normal'); |
166 | 179 | xlabel('x'); |
167 | 180 | ylabel('y'); |
168 | | - pause(opt.show); |
| 181 | + if opt.animate |
| 182 | + anim.add(); |
| 183 | + else |
| 184 | + pause(opt.delay); |
| 185 | + end |
169 | 186 | end |
170 | 187 |
|
171 | 188 | ninfnow = sum( isinf(occgrid(:)) ); % current number of Infs |
|
176 | 193 | end |
177 | 194 | ninf = ninfnow; |
178 | 195 | end |
| 196 | + anim.close(); |
179 | 197 | dx = occgrid; |
180 | 198 | end |
181 | 199 |
|
182 | | - if opt.show && ~isempty(count) |
| 200 | + if opt.animate && ~isempty(count) |
183 | 201 | fprintf('%d iterations, %d unreachable cells\n', count, ninf); |
184 | 202 | end |
185 | 203 |
|
|
200 | 218 | occgrid(isfinite(occgrid)) = 0; |
201 | 219 |
|
202 | 220 | count = 0; |
| 221 | + anim = Animate(opt.movie); |
203 | 222 | while 1 |
204 | 223 | occgrid = imorph(occgrid, m, 'plusmin'); |
205 | 224 | count = count+1; |
|
210 | 229 | set(gca, 'Ydir', 'normal'); |
211 | 230 | xlabel('x'); |
212 | 231 | ylabel('y'); |
213 | | - pause(opt.show); |
| 232 | + if opt.animate |
| 233 | + anim.add(); |
| 234 | + else |
| 235 | + pause(opt.delay); |
| 236 | + end |
214 | 237 | end |
215 | 238 |
|
216 | 239 | ninfnow = sum( isinf(occgrid(:)) ); % current number of Infs |
|
219 | 242 | break; |
220 | 243 | end |
221 | 244 | end |
| 245 | + anim.close(); |
222 | 246 | dx = occgrid; |
223 | 247 | elseif exist('bwdist') && opt.ipt |
224 | 248 | if opt.verbose |
|
0 commit comments