[37] | 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 | |
---|