1 | % * This code was used in the following articles:
|
---|
2 | % * [1] Learning 3-D Scene Structure from a Single Still Image,
|
---|
3 | % * Ashutosh Saxena, Min Sun, Andrew Y. Ng,
|
---|
4 | % * In ICCV workshop on 3D Representation for Recognition (3dRR-07), 2007.
|
---|
5 | % * (best paper)
|
---|
6 | % * [2] 3-D Reconstruction from Sparse Views using Monocular Vision,
|
---|
7 | % * Ashutosh Saxena, Min Sun, Andrew Y. Ng,
|
---|
8 | % * In ICCV workshop on Virtual Representations and Modeling
|
---|
9 | % * of Large-scale environments (VRML), 2007.
|
---|
10 | % * [3] 3-D Depth Reconstruction from a Single Still Image,
|
---|
11 | % * Ashutosh Saxena, Sung H. Chung, Andrew Y. Ng.
|
---|
12 | % * International Journal of Computer Vision (IJCV), Aug 2007.
|
---|
13 | % * [6] Learning Depth from Single Monocular Images,
|
---|
14 | % * Ashutosh Saxena, Sung H. Chung, Andrew Y. Ng.
|
---|
15 | % * In Neural Information Processing Systems (NIPS) 18, 2005.
|
---|
16 | % *
|
---|
17 | % * These articles are available at:
|
---|
18 | % * http://make3d.stanford.edu/publications
|
---|
19 | % *
|
---|
20 | % * We request that you cite the papers [1], [3] and [6] in any of
|
---|
21 | % * your reports that uses this code.
|
---|
22 | % * Further, if you use the code in image3dstiching/ (multiple image version),
|
---|
23 | % * then please cite [2].
|
---|
24 | % *
|
---|
25 | % * If you use the code in third_party/, then PLEASE CITE and follow the
|
---|
26 | % * LICENSE OF THE CORRESPONDING THIRD PARTY CODE.
|
---|
27 | % *
|
---|
28 | % * Finally, this code is for non-commercial use only. For further
|
---|
29 | % * information and to obtain a copy of the license, see
|
---|
30 | % *
|
---|
31 | % * http://make3d.stanford.edu/publications/code
|
---|
32 | % *
|
---|
33 | % * Also, the software distributed under the License is distributed on an
|
---|
34 | % * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
---|
35 | % * express or implied. See the License for the specific language governing
|
---|
36 | % * permissions and limitations under the License.
|
---|
37 | % *
|
---|
38 | % */
|
---|
39 | function h = dispMatchSearchRegin(I1,I2,P1,P2,ConS1, ConS2, F, ... |
---|
40 | x1_2Max, MaxD1, x1_2Min, MinD1,... |
---|
41 | x2_1Max, MaxD2, x2_1Min, MinD2, ... |
---|
42 | FlagRotate, varargin) |
---|
43 | % PLOTMATCHES Plot keypoint matches |
---|
44 | % PLOTMATCHES(I1,I2,P1,P2,MATCHES) plots the two images I1 and I2 |
---|
45 | % and lines connecting the frames (keypoints) P1 and P2 as specified |
---|
46 | % by MATCHES. |
---|
47 | % |
---|
48 | % P1 and P2 specify two sets of frames, one per column. The first |
---|
49 | % two elements of each column specify the X,Y coordinates of the |
---|
50 | % corresponding frame. Any other element is ignored. |
---|
51 | % |
---|
52 | % ConS specifies Constrain for each features serach region, |
---|
53 | % one per column. The 4 elementes of each column are max and min |
---|
54 | % boundary in x y respectively. |
---|
55 | % [xmin; xmax; ymin; ymax] |
---|
56 | % |
---|
57 | % The images I1 and I2 might be either both grayscale or both color |
---|
58 | % and must have DOUBLE storage class. If they are color the range |
---|
59 | % must be normalized in [0,1]. |
---|
60 | % |
---|
61 | % The function accepts the following option-value pairs: |
---|
62 | % |
---|
63 | % 'Stacking' ['h'] |
---|
64 | % Stacking of images: horizontal ['h'], vertical ['v'], diagonal |
---|
65 | % ['h'], overlap ['o'] |
---|
66 | % |
---|
67 | % 'Interactive' [1] (always to 1) |
---|
68 | % In this mode the |
---|
69 | % program lets the user browse the constrain region by moving the mouse: |
---|
70 | % Click to select and highlight feature point; press any key to end. |
---|
71 | % |
---|
72 | % See also PLOTSIFTDESCRIPTOR(), PLOTSIFTFRAME(), PLOTSS(). |
---|
73 | |
---|
74 | % AUTORIGHTS |
---|
75 | % Copyright (c) 2006 The Regents of the University of California. |
---|
76 | % All Rights Reserved. |
---|
77 | % |
---|
78 | % Created by Andrea Vedaldi |
---|
79 | % UCLA Vision Lab - Department of Computer Science |
---|
80 | % |
---|
81 | % Permission to use, copy, modify, and distribute this software and its |
---|
82 | % documentation for educational, research and non-profit purposes, |
---|
83 | % without fee, and without a written agreement is hereby granted, |
---|
84 | % provided that the above copyright notice, this paragraph and the |
---|
85 | % following three paragraphs appear in all copies. |
---|
86 | % |
---|
87 | % This software program and documentation are copyrighted by The Regents |
---|
88 | % of the University of California. The software program and |
---|
89 | % documentation are supplied "as is", without any accompanying services |
---|
90 | % from The Regents. The Regents does not warrant that the operation of |
---|
91 | % the program will be uninterrupted or error-free. The end-user |
---|
92 | % understands that the program was developed for research purposes and |
---|
93 | % is advised not to rely exclusively on the program for any reason. |
---|
94 | % |
---|
95 | % This software embodies a method for which the following patent has |
---|
96 | % been issued: "Method and apparatus for identifying scale invariant |
---|
97 | % features in an image and use of same for locating an object in an |
---|
98 | % image," David G. Lowe, US Patent 6,711,293 (March 23, |
---|
99 | % 2004). Provisional application filed March 8, 1999. Asignee: The |
---|
100 | % University of British Columbia. |
---|
101 | % |
---|
102 | % IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY |
---|
103 | % FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, |
---|
104 | % INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND |
---|
105 | % ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN |
---|
106 | % ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF |
---|
107 | % CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT |
---|
108 | % LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
---|
109 | % A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" |
---|
110 | % BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE |
---|
111 | % MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
---|
112 | |
---|
113 | % -------------------------------------------------------------------- |
---|
114 | % Modified by Min to show interactive between features and constrain region |
---|
115 | % April 29th, 2007 |
---|
116 | % -------------------------------------------------------------------- |
---|
117 | |
---|
118 | % -------------------------------------------------------------------- |
---|
119 | % Check the arguments |
---|
120 | % -------------------------------------------------------------------- |
---|
121 | |
---|
122 | stack='h' ; |
---|
123 | interactive=0 ; |
---|
124 | only_interactive=0 ; |
---|
125 | dodist=0; |
---|
126 | |
---|
127 | for k=1:2:length(varargin) |
---|
128 | switch lower(varargin{k}) |
---|
129 | case 'stacking' |
---|
130 | stack=varargin{k+1} ; |
---|
131 | case 'interactive' |
---|
132 | interactive=varargin{k+1}; |
---|
133 | case 'dist' |
---|
134 | dist = varargin{k+1}; |
---|
135 | dodist=1; |
---|
136 | otherwise |
---|
137 | error(['[Unknown option ''', varargin{k}, '''.']) ; |
---|
138 | end |
---|
139 | end |
---|
140 | |
---|
141 | % -------------------------------------------------------------------- |
---|
142 | % Do the job |
---|
143 | % -------------------------------------------------------------------- |
---|
144 | |
---|
145 | [M1,N1,K1]=size(I1) ; |
---|
146 | [M2,N2,K2]=size(I2) ; |
---|
147 | |
---|
148 | switch stack |
---|
149 | case 'h' |
---|
150 | N3=N1+N2 ; |
---|
151 | M3=max(M1,M2) ; |
---|
152 | oj=N1 ; |
---|
153 | oi=0 ; |
---|
154 | case 'v' |
---|
155 | M3=M1+M2 ; |
---|
156 | N3=max(N1,N2) ; |
---|
157 | oj=0 ; |
---|
158 | oi=M1 ; |
---|
159 | case 'd' |
---|
160 | M3=M1+M2 ; |
---|
161 | N3=N1+N2 ; |
---|
162 | oj=N1 ; |
---|
163 | oi=M1 ; |
---|
164 | case 'o' |
---|
165 | M3=max(M1,M2) ; |
---|
166 | N3=max(N1,N2) ; |
---|
167 | oj=0; |
---|
168 | oi=0; |
---|
169 | otherwise |
---|
170 | error(['Unkown stacking type '''], stack, ['''.']) ; |
---|
171 | end |
---|
172 | |
---|
173 | % Combine the two images. In most cases just place one image next to |
---|
174 | % the other. If the stacking is 'o', however, combine the two images |
---|
175 | % linearly. |
---|
176 | I=zeros(M3,N3,K1) ; |
---|
177 | if stack ~= 'o' |
---|
178 | I(1:M1,1:N1,:) = I1 ; |
---|
179 | I(oi+(1:M2),oj+(1:N2),:) = I2 ; |
---|
180 | else |
---|
181 | I(oi+(1:M2),oj+(1:N2),:) = I2 ; |
---|
182 | I(1:M1,1:N1,:) = I(1:M1,1:N1,:) + I1 ; |
---|
183 | I(1:min(M1,M2),1:min(N1,N2),:) = 0.5 * I(1:min(M1,M2),1:min(N1,N2),:) ; |
---|
184 | end |
---|
185 | |
---|
186 | axes('Position', [0 0 1 1]) ; |
---|
187 | imagesc(I) ; colormap gray ; hold on ; axis image ; axis off ; |
---|
188 | |
---|
189 | % K = size(P1, 2) ; |
---|
190 | %K = size(matches, 2) ; |
---|
191 | % nans = NaN * ones(1,K) ; |
---|
192 | |
---|
193 | x = [ P1(1,:)' ; P2(1,:)'+oj] ; |
---|
194 | y = [ P1(2,:)' ; P2(2,:)'+oi] ; |
---|
195 | %x = [ P1(1,matches(1,:)) ; P2(1,matches(2,:))+oj ; nans ] ; |
---|
196 | %y = [ P1(2,matches(1,:)) ; P2(2,matches(2,:))+oi ; nans ] ; |
---|
197 | |
---|
198 | % if interactive > 1 we do not drive lines, but just points. |
---|
199 | %if(interactive > 1) |
---|
200 | h = plot(x(:),y(:),'g.') ; |
---|
201 | %else |
---|
202 | % h = line(x(:)', y(:)') ; |
---|
203 | %end |
---|
204 | set(h,'Marker','.','Color','g') ; |
---|
205 | |
---|
206 | % -------------------------------------------------------------------- |
---|
207 | % Interactive |
---|
208 | % -------------------------------------------------------------------- |
---|
209 | |
---|
210 | %if(~interactive || interactive==3), return ; end |
---|
211 | |
---|
212 | %sel1 = unique(matches(1,:)) ; |
---|
213 | %sel2 = unique(matches(2,:)) ; |
---|
214 | |
---|
215 | K1 = size(P1,2) ; |
---|
216 | K2 = size(P2,2) ; |
---|
217 | %K1 = length(sel1) ; %size(P1,2) ; |
---|
218 | %K2 = length(sel2) ; %size(P2,2) ; |
---|
219 | X = [ P1(1,:) P2(1,:)+oj ; |
---|
220 | P1(2,:) P2(2,:)+oi ; ] ; |
---|
221 | %X = [ P1(1,sel1) P2(1,sel2)+oj ; |
---|
222 | % P1(2,sel1) P2(2,sel2)+oi ; ] ; |
---|
223 | |
---|
224 | fig = gcf ; |
---|
225 | is_hold = ishold ; |
---|
226 | hold on ; |
---|
227 | |
---|
228 | % save the handlers for later to restore --------| define the interactive function| |
---|
229 | dhandler = get(fig,'WindowButtonDownFcn') ; |
---|
230 | uhandler = get(fig,'WindowButtonUpFcn') ; |
---|
231 | mhandler = get(fig,'WindowButtonMotionFcn') ; |
---|
232 | khandler = get(fig,'KeyPressFcn') ; |
---|
233 | pointer = get(fig,'Pointer') ; |
---|
234 | |
---|
235 | set(fig,'KeyPressFcn', @key_handler) ; |
---|
236 | set(fig,'WindowButtonDownFcn',@click_down_handler) ; |
---|
237 | set(fig,'WindowButtonUpFcn', @click_up_handler) ; |
---|
238 | set(fig,'Pointer','crosshair') ; |
---|
239 | % -------------------------------------------------------------------------------- |
---|
240 | |
---|
241 | data.exit = 0 ; % signal exit to the interactive mode |
---|
242 | data.selected = [] ; % currently selected feature |
---|
243 | data.X = X ; % feature anchors |
---|
244 | |
---|
245 | highlighted = [] ; % currently highlighted feature |
---|
246 | hh = [] ; % hook of the highlight plot |
---|
247 | |
---|
248 | guidata(fig,data) ; |
---|
249 | while ~ data.exit |
---|
250 | uiwait(fig) ; |
---|
251 | data = guidata(fig) ; |
---|
252 | if(any(size(highlighted) ~= size(data.selected)) || ... |
---|
253 | any(highlighted ~= data.selected) ) |
---|
254 | |
---|
255 | highlighted = data.selected ; |
---|
256 | |
---|
257 | % delete previous highlight |
---|
258 | if( ~isempty(hh) ) |
---|
259 | delete(hh) ; |
---|
260 | end |
---|
261 | |
---|
262 | hh=[] ; |
---|
263 | |
---|
264 | % each selected feature uses its own color |
---|
265 | c=1 ; |
---|
266 | colors=[1.0 0.0 0.0 ; |
---|
267 | 0.0 1.0 0.0 ; |
---|
268 | 0.0 0.0 1.0 ; |
---|
269 | 1.0 1.0 0.0 ; |
---|
270 | 0.0 1.0 1.0 ; |
---|
271 | 1.0 0.0 1.0 ] ; |
---|
272 | |
---|
273 | % more than one feature might be seleted at one time... |
---|
274 | for this=highlighted |
---|
275 | % ------------------------------------------------------------------------------------------- |
---|
276 | |
---|
277 | % find matches |
---|
278 | if( this <= K1 ) |
---|
279 | sele = this ; |
---|
280 | % --------Min------- |
---|
281 | disp('Matches selected Index'); |
---|
282 | sele |
---|
283 | % ------------------ |
---|
284 | %sel=find(matches(1,:)== sel1(this)); |
---|
285 | if FlagRotate |
---|
286 | ConSSel = ConS1(:,sele)+[oj; oi; oj; oi; oj; oi; oj; oi]; |
---|
287 | else |
---|
288 | ConSSel = ConS1(:,sele)+[oj; oj; oi; oi]; |
---|
289 | end |
---|
290 | % --------- Max and Min Point |
---|
291 | disp('MaxD1'); |
---|
292 | MaxD1(sele) |
---|
293 | x1_2Max(:,sele) |
---|
294 | disp('MinD1'); |
---|
295 | MinD1(sele) |
---|
296 | x1_2Min(:,sele) |
---|
297 | xMaxSel = round(x1_2Max(:,sele))+[oj; oi]; |
---|
298 | xMinSel = round(x1_2Min(:,sele))+[oj; oi]; |
---|
299 | % --------------------------- |
---|
300 | Point_sel = P1(1:2,sele); |
---|
301 | l1 = F*P1(:,sele); |
---|
302 | % try four combination to find 2 point |
---|
303 | q = 1; |
---|
304 | % x biggest case |
---|
305 | y_cand(q) = (-l1(3) - l1(1)*N1)/l1(2); |
---|
306 | if (y_cand(q) <= M2) && (y_cand(q) >= 1) |
---|
307 | x_cand(q) = N1; |
---|
308 | q = q+1; |
---|
309 | end |
---|
310 | % x smallest case |
---|
311 | y_cand(q) = (-l1(3) - l1(1)*1)/l1(2); |
---|
312 | if (y_cand(q) <= M2) && (y_cand(q) >= 1) |
---|
313 | x_cand(q) = 1; |
---|
314 | q = q+1; |
---|
315 | end |
---|
316 | % y biggest case |
---|
317 | x_cand(q) = (-l1(3) - l1(2)*M1)/l1(1); |
---|
318 | if (x_cand(q) <= N2) && (x_cand(q) >= 1) |
---|
319 | y_cand(q) = M1; |
---|
320 | q = q+1; |
---|
321 | end |
---|
322 | % y smallest case |
---|
323 | x_cand(q) = (-l1(3) - l1(2)*1)/l1(1); |
---|
324 | if (x_cand(q) <= N2) && (x_cand(q) >= 1) |
---|
325 | y_cand(q) = 1; |
---|
326 | q = q+1; |
---|
327 | end |
---|
328 | if size(x_cand,2) > size(y_cand,2) |
---|
329 | x_cand(end) = []; |
---|
330 | elseif size(x_cand,2) < size(y_cand,2) |
---|
331 | y_cand(end) = []; |
---|
332 | end |
---|
333 | x_cand = x_cand+oj; |
---|
334 | y_cand = y_cand+oi; |
---|
335 | else % -------------------( this > K1 ) |
---|
336 | sele = this - K1; |
---|
337 | % --------Min------- |
---|
338 | disp('Matches selected Index'); |
---|
339 | sele |
---|
340 | % ------------------ |
---|
341 | Point_sel = P2(1:2,sele) + [oj; oi]; |
---|
342 | K=length(sele); |
---|
343 | sele = sele(1); |
---|
344 | ConSSel = ConS2(:,sele); |
---|
345 | % --------- Max and Min Point |
---|
346 | disp('MaxD1'); |
---|
347 | MaxD2(sele) |
---|
348 | x2_1Max(:,sele) |
---|
349 | disp('MinD1'); |
---|
350 | MinD2(sele) |
---|
351 | x2_1Min(:,sele) |
---|
352 | xMaxSel = round(x2_1Max(:,sele)); |
---|
353 | xMinSel = round(x2_1Min(:,sele)); |
---|
354 | % --------------------------- |
---|
355 | l2 = F'*P2(:,sele); |
---|
356 | % x biggest case |
---|
357 | q = 1; |
---|
358 | y_cand(q) = (-l2(3) - l2(1)*N2)/l2(2); |
---|
359 | if (y_cand(q) <= M1) && (y_cand(q) >= 1) |
---|
360 | x_cand(q) = N2; |
---|
361 | q = q+1; |
---|
362 | end |
---|
363 | % x smallest case |
---|
364 | y_cand(q) = (-l2(3) - l2(1)*1)/l2(2); |
---|
365 | if (y_cand(q) <= M1) && (y_cand(q) >= 1) |
---|
366 | x_cand(q) = 1; |
---|
367 | q = q+1; |
---|
368 | end |
---|
369 | % y biggest case |
---|
370 | x_cand(q) = (-l2(3) - l2(2)*M2)/l2(1); |
---|
371 | if (x_cand(q) <= N1) && (x_cand(q) >= 1) |
---|
372 | y_cand(q) = M2; |
---|
373 | q = q+1; |
---|
374 | end |
---|
375 | % y smallest case |
---|
376 | x_cand(q) = (-l2(3) - l2(2)*1)/l2(1); |
---|
377 | if (x_cand(q) <= N1) && (x_cand(q) >= 1) |
---|
378 | y_cand(q) = 1; |
---|
379 | q = q+1; |
---|
380 | end |
---|
381 | if size(x_cand,2) > size(y_cand,2) |
---|
382 | x_cand(end) = []; |
---|
383 | elseif size(x_cand,2) < size(y_cand,2) |
---|
384 | y_cand(end) = []; |
---|
385 | end |
---|
386 | %sel=find(matches(2,:)== sel2(this-K1)) ; |
---|
387 | end |
---|
388 | if(dodist) |
---|
389 | d=dist(sele) |
---|
390 | end |
---|
391 | |
---|
392 | % plot matches |
---|
393 | if FlagRotate |
---|
394 | x = [ ConSSel(1) ConSSel(3) ConSSel(5) ConSSel(7) ConSSel(1)]; |
---|
395 | y = [ ConSSel(2) ConSSel(4) ConSSel(6) ConSSel(8) ConSSel(2)]; |
---|
396 | else |
---|
397 | x = [ ConSSel(2) ConSSel(1) ConSSel(1) ConSSel(2) ConSSel(2)]; |
---|
398 | y = [ ConSSel(4) ConSSel(4) ConSSel(3) ConSSel(3) ConSSel(4)]; |
---|
399 | end |
---|
400 | %x = [ P1(1,matches(1,sel)) ; P2(1,matches(2,sel))+oj ; nan*ones(1,K) ] ; |
---|
401 | %y = [ P1(2,matches(1,sel)) ; P2(2,matches(2,sel))+oi ; nan*ones(1,K) ] ; |
---|
402 | |
---|
403 | if q >= 3 |
---|
404 | % draw epiploar line and selected features |
---|
405 | hh = [hh line(x(:)', y(:)',... |
---|
406 | 'Marker','*',... |
---|
407 | 'Color',colors(c,:),... |
---|
408 | 'LineWidth',3)... |
---|
409 | line(x_cand(:)', y_cand(:)',... |
---|
410 | 'Marker','*',... |
---|
411 | 'Color',colors(c+5,:),... |
---|
412 | 'LineWidth',1)... |
---|
413 | scatter(Point_sel(1), Point_sel(2), 4,'r')... |
---|
414 | scatter(xMinSel(1), xMinSel(2), 50,'y')...% --------plot xMaxSel and xMinSel------ |
---|
415 | scatter(xMaxSel(1), xMaxSel(2), 50,'b')]; |
---|
416 | % -------------------------------------- |
---|
417 | else |
---|
418 | hh = [hh line(x(:)', y(:)',... |
---|
419 | 'Marker','*',... |
---|
420 | 'Color',colors(c,:),... |
---|
421 | 'LineWidth',3)]; |
---|
422 | end |
---|
423 | |
---|
424 | if( size(P1,1) == 4 ) |
---|
425 | f1 = unique(P1(:,matches(1,sel))','rows')' ; |
---|
426 | hp=plotsiftframe(f1); |
---|
427 | set(hp,'Color',colors(c,:)) ; |
---|
428 | hh=[hh hp] ; |
---|
429 | end |
---|
430 | |
---|
431 | if( size(P2,1) == 4 ) |
---|
432 | f2 = unique(P2(:,matches(2,sel))','rows')' ; |
---|
433 | f2(1,:)=f2(1,:)+oj ; |
---|
434 | f2(2,:)=f2(2,:)+oi ; |
---|
435 | hp=plotsiftframe(f2); |
---|
436 | set(hp,'Color',colors(c,:)) ; |
---|
437 | hh=[hh hp] ; |
---|
438 | end |
---|
439 | |
---|
440 | c=c+1; |
---|
441 | % ------------------------------------------------------------------------------------------- |
---|
442 | end |
---|
443 | |
---|
444 | drawnow ; |
---|
445 | end |
---|
446 | end |
---|
447 | |
---|
448 | if( ~isempty(hh) ) |
---|
449 | delete(hh) ; |
---|
450 | end |
---|
451 | |
---|
452 | if ~is_hold |
---|
453 | hold off ; |
---|
454 | end |
---|
455 | |
---|
456 | set(fig,'WindowButtonDownFcn', dhandler) ; |
---|
457 | set(fig,'WindowButtonUpFcn', uhandler) ; |
---|
458 | set(fig,'WindowButtonMotionFcn',mhandler) ; |
---|
459 | set(fig,'KeyPressFcn', khandler) ; |
---|
460 | set(fig,'Pointer', pointer ) ; |
---|
461 | |
---|
462 | % ==================================================================== |
---|
463 | function data=selection_helper(data) |
---|
464 | % -------------------------------------------------------------------- |
---|
465 | P = get(gca, 'CurrentPoint') ; |
---|
466 | P = [P(1,1); P(1,2)] ; |
---|
467 | |
---|
468 | d = (data.X(1,:) - P(1)).^2 + (data.X(2,:) - P(2)).^2 ; |
---|
469 | dmin=min(d) ; |
---|
470 | idx=find(d==dmin) ; |
---|
471 | |
---|
472 | data.selected = idx ; |
---|
473 | |
---|
474 | % ==================================================================== |
---|
475 | function click_down_handler(obj,event) |
---|
476 | % -------------------------------------------------------------------- |
---|
477 | % select a feature and change motion handler for dragging |
---|
478 | |
---|
479 | [obj,fig]=gcbo ; |
---|
480 | data = guidata(fig) ; |
---|
481 | data.mhandler = get(fig,'WindowButtonMotionFcn') ; |
---|
482 | set(fig,'WindowButtonMotionFcn',@motion_handler) ; |
---|
483 | data = selection_helper(data) ; |
---|
484 | guidata(fig,data) ; |
---|
485 | uiresume(obj) ; |
---|
486 | |
---|
487 | % ==================================================================== |
---|
488 | function click_up_handler(obj,event) |
---|
489 | % -------------------------------------------------------------------- |
---|
490 | % stop dragging |
---|
491 | |
---|
492 | [obj,fig]=gcbo ; |
---|
493 | data = guidata(fig) ; |
---|
494 | set(fig,'WindowButtonMotionFcn',data.mhandler) ; |
---|
495 | guidata(fig,data) ; |
---|
496 | uiresume(obj) ; |
---|
497 | |
---|
498 | % ==================================================================== |
---|
499 | function motion_handler(obj,event) |
---|
500 | % -------------------------------------------------------------------- |
---|
501 | % select features while dragging |
---|
502 | |
---|
503 | data = guidata(obj) ; |
---|
504 | data = selection_helper(data); |
---|
505 | guidata(obj,data) ; |
---|
506 | uiresume(obj) ; |
---|
507 | |
---|
508 | % ==================================================================== |
---|
509 | function key_handler(obj,event) |
---|
510 | % -------------------------------------------------------------------- |
---|
511 | % use keypress to exit |
---|
512 | |
---|
513 | data = guidata(gcbo) ; |
---|
514 | data.exit = 1 ; |
---|
515 | guidata(obj,data) ; |
---|
516 | uiresume(gcbo) ; |
---|
517 | |
---|