├── .gitignore ├── README.markdown ├── config.m ├── data └── deleteme ├── derivative5.m ├── do_SfM.m ├── do_factorization.m ├── do_getKeypoints.m ├── do_trackFeatures.m ├── harris.m ├── predictTranslation.m ├── predictTranslationAll.m ├── supp ├── images │ ├── hotel.seq0.png │ ├── hotel.seq1.png │ ├── hotel.seq10.png │ ├── hotel.seq11.png │ ├── hotel.seq12.png │ ├── hotel.seq13.png │ ├── hotel.seq14.png │ ├── hotel.seq15.png │ ├── hotel.seq16.png │ ├── hotel.seq17.png │ ├── hotel.seq18.png │ ├── hotel.seq19.png │ ├── hotel.seq2.png │ ├── hotel.seq20.png │ ├── hotel.seq21.png │ ├── hotel.seq22.png │ ├── hotel.seq23.png │ ├── hotel.seq24.png │ ├── hotel.seq25.png │ ├── hotel.seq26.png │ ├── hotel.seq27.png │ ├── hotel.seq28.png │ ├── hotel.seq29.png │ ├── hotel.seq3.png │ ├── hotel.seq30.png │ ├── hotel.seq31.png │ ├── hotel.seq32.png │ ├── hotel.seq33.png │ ├── hotel.seq34.png │ ├── hotel.seq35.png │ ├── hotel.seq36.png │ ├── hotel.seq37.png │ ├── hotel.seq38.png │ ├── hotel.seq39.png │ ├── hotel.seq4.png │ ├── hotel.seq40.png │ ├── hotel.seq41.png │ ├── hotel.seq42.png │ ├── hotel.seq43.png │ ├── hotel.seq44.png │ ├── hotel.seq45.png │ ├── hotel.seq46.png │ ├── hotel.seq47.png │ ├── hotel.seq48.png │ ├── hotel.seq49.png │ ├── hotel.seq5.png │ ├── hotel.seq50.png │ ├── hotel.seq6.png │ ├── hotel.seq7.png │ ├── hotel.seq8.png │ └── hotel.seq9.png ├── initial_keypoints.mat └── tracked_points.mat └── tracked_points.mat /.gitignore: -------------------------------------------------------------------------------- 1 | # make git ignore these files: 2 | 3 | ### Project Specific ### 4 | supp/images/longer/ 5 | data/*.mat 6 | writeups 7 | 8 | ### Generic Stuff ### 9 | ## c++ stuff 10 | *.slo 11 | *.lo 12 | *.o 13 | *.so 14 | *.lai 15 | *.la 16 | *.a 17 | 18 | # emacs stuff 19 | *.*# 20 | 21 | # latex stuff 22 | *.aux 23 | *.bbl 24 | *.blg 25 | *.dvi 26 | *.fdb_latexmk 27 | *.glg 28 | *.glo 29 | *.gls 30 | *.idx 31 | *.ilg 32 | *.ind 33 | *.ist 34 | *.lof 35 | *.log 36 | *.lot 37 | *.nav 38 | *.nlo 39 | *.out 40 | *.pdfsync 41 | *.ps 42 | *.snm 43 | *.synctex.gz 44 | *.toc 45 | *.vrb 46 | *.maf 47 | *.mtc 48 | *.mtc0 49 | 50 | 51 | # other stuff 52 | .DS_Store 53 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | Affine Structure from Motion 2 | ---- 3 | 4 | A demo of the entire pipeline of basic affine structure from motion 5 | including 6 | 7 | 1. keypoint selection `do_getKeypoints.m` 8 | 2. feature tracking `do_trackFeatures.m` 9 | 3. the factorization algorithm `do_factorization.m` 10 | 11 | Specify experiment settings in the config file (location of the 12 | images, data, etc), then in matlab do 13 | 14 | `do_all('config')` 15 | 16 | 17 | -------------------------------------------------------------------------------- /config.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%% 2 | % The global configuration file 3 | % Holds all settings used in all parts of the affine Structure from Motion project, 4 | % enabling the exact reproduction of the experiment at some future 5 | % date. 6 | % 7 | % Use this file to set various options 8 | % 9 | % Angjoo Kanazawa 10 | 11 | %%%%% 12 | % DIRECTORIES 13 | %%%%% 14 | 15 | % Directory holding the experiment 16 | RUN_DIR = [ 'Structure-from-Motion/' ]; 17 | 18 | % Directory holding all the source images 19 | IMAGE_DIR = [ 'supp/images' ]; 20 | 21 | % Data directory - holds all intermediate .mat files 22 | DATA_DIR = [ 'data/' ]; 23 | 24 | 25 | %---------- 26 | %% EXPERIMENT SETTINGS 27 | %---------- 28 | VERBOSE = 1; 29 | 30 | %% Featuren Extraction method currently 'harris' or 'sift' 31 | Feature.method = 'harris'; %'sift'; 32 | 33 | if strcmp(Feature.method, 'harris') 34 | Feature.alpha = 0.05; % corner response size 35 | Feature.radius = 5; % window size 36 | Feature.sigma = 3; % size of the gaussian filter 37 | Feature.tau = 1000; % threshold for non-maxima supression 38 | else 39 | 40 | end 41 | 42 | %% FILE NAMES 43 | % name to save the tracked files 44 | tracked_pts_f = [DATA_DIR, Feature.method, '_tracked_points.mat']; 45 | % name to save the initial key points 46 | keypoints_f = [DATA_DIR, Feature.method, '_keypoints.mat']; 47 | -------------------------------------------------------------------------------- /data/deleteme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/data/deleteme -------------------------------------------------------------------------------- /derivative5.m: -------------------------------------------------------------------------------- 1 | % DERIVATIVE5 - 5-Tap 1st and 2nd discrete derivatives 2 | % 3 | % This function computes 1st and 2nd derivatives of an image using the 5-tap 4 | % coefficients given by Farid and Simoncelli. The results are significantly 5 | % more accurate than MATLAB's GRADIENT function on edges that are at angles 6 | % other than vertical or horizontal. This in turn improves gradient orientation 7 | % estimation enormously. If you are after extreme accuracy try using DERIVATIVE7. 8 | % 9 | % Usage: [gx, gy, gxx, gyy, gxy] = derivative5(im, derivative specifiers) 10 | % 11 | % Arguments: 12 | % im - Image to compute derivatives from. 13 | % derivative specifiers - A comma separated list of character strings 14 | % that can be any of 'x', 'y', 'xx', 'yy' or 'xy' 15 | % These can be in any order, the order of the 16 | % computed output arguments will match the order 17 | % of the derivative specifier strings. 18 | % Returns: 19 | % Function returns requested derivatives which can be: 20 | % gx, gy - 1st derivative in x and y 21 | % gxx, gyy - 2nd derivative in x and y 22 | % gxy - 1st derivative in y of 1st derivative in x 23 | % 24 | % Examples: 25 | % Just compute 1st derivatives in x and y 26 | % [gx, gy] = derivative5(im, 'x', 'y'); 27 | % 28 | % Compute 2nd derivative in x, 1st derivative in y and 2nd derivative in y 29 | % [gxx, gy, gyy] = derivative5(im, 'xx', 'y', 'yy') 30 | % 31 | % See also: DERIVATIVE7 32 | 33 | % Reference: Hany Farid and Eero Simoncelli "Differentiation of Discrete 34 | % Multi-Dimensional Signals" IEEE Trans. Image Processing. 13(4): 496-508 (2004) 35 | 36 | % Copyright (c) 2010 Peter Kovesi 37 | % Centre for Exploration Targeting 38 | % The University of Western Australia 39 | % http://www.csse.uwa.edu.au/~pk/research/matlabfns/ 40 | % 41 | % Permission is hereby granted, free of charge, to any person obtaining a copy 42 | % of this software and associated documentation files (the "Software"), to deal 43 | % in the Software without restriction, subject to the following conditions: 44 | % 45 | % The above copyright notice and this permission notice shall be included in 46 | % all copies or substantial portions of the Software. 47 | % 48 | % The Software is provided "as is", without warranty of any kind. 49 | % 50 | % April 2010 51 | 52 | function varargout = derivative5(im, varargin) 53 | 54 | varargin = varargin(:); 55 | varargout = cell(size(varargin)); 56 | 57 | % Check if we are just computing 1st derivatives. If so use the 58 | % interpolant and derivative filters optimized for 1st derivatives, else 59 | % use 2nd derivative filters and interpolant coefficients. 60 | % Detection is done by seeing if any of the derivative specifier 61 | % arguments is longer than 1 char, this implies 2nd derivative needed. 62 | secondDeriv = false; 63 | for n = 1:length(varargin) 64 | if length(varargin{n}) > 1 65 | secondDeriv = true; 66 | break 67 | end 68 | end 69 | 70 | if ~secondDeriv 71 | % 5 tap 1st derivative cofficients. These are optimal if you are just 72 | % seeking the 1st deriavtives 73 | p = [0.037659 0.249153 0.426375 0.249153 0.037659]; 74 | d1 =[0.109604 0.276691 0.000000 -0.276691 -0.109604]; 75 | else 76 | % 5-tap 2nd derivative coefficients. The associated 1st derivative 77 | % coefficients are not quite as optimal as the ones above but are 78 | % consistent with the 2nd derivative interpolator p and thus are 79 | % appropriate to use if you are after both 1st and 2nd derivatives. 80 | p = [0.030320 0.249724 0.439911 0.249724 0.030320]; 81 | d1 = [0.104550 0.292315 0.000000 -0.292315 -0.104550]; 82 | d2 = [0.232905 0.002668 -0.471147 0.002668 0.232905]; 83 | end 84 | 85 | % Compute derivatives. Note that in the 1st call below MATLAB's conv2 86 | % function performs a 1D convolution down the columns using p then a 1D 87 | % convolution along the rows using d1. etc etc. 88 | gx = false; 89 | 90 | for n = 1:length(varargin) 91 | if strcmpi('x', varargin{n}) 92 | varargout{n} = conv2(p, d1, im, 'same'); 93 | gx = true; % Record that gx is available for gxy if needed 94 | gxn = n; 95 | elseif strcmpi('y', varargin{n}) 96 | varargout{n} = conv2(d1, p, im, 'same'); 97 | elseif strcmpi('xx', varargin{n}) 98 | varargout{n} = conv2(p, d2, im, 'same'); 99 | elseif strcmpi('yy', varargin{n}) 100 | varargout{n} = conv2(d2, p, im, 'same'); 101 | elseif strcmpi('xy', varargin{n}) | strcmpi('yx', varargin{n}) 102 | if gx 103 | varargout{n} = conv2(d1, p, varargout{gxn}, 'same'); 104 | else 105 | gx = conv2(p, d1, im, 'same'); 106 | varargout{n} = conv2(d1, p, gx, 'same'); 107 | end 108 | else 109 | error(sprintf('''%s'' is an unrecognized derivative option',varargin{n})); 110 | end 111 | end 112 | 113 | -------------------------------------------------------------------------------- /do_SfM.m: -------------------------------------------------------------------------------- 1 | function do_SfM(config_file) 2 | %%%%%%%%%% 3 | % CMSC660 Fall'11 Final Project: Affine Structure from Motion(SfM) 4 | % doSfM.m 5 | % Driver script to do affine SfM, to run, do: 6 | % do_SfM('config'); where 'config' refers to the config.m in this directory 7 | % 8 | % Angjoo Kanazawa 11/23/'11 9 | %%%%%%%%%% 10 | 11 | %% Step 1: get initial keypoints 12 | 13 | [keyXs, keyYs] = do_getKeypoints(config_file); 14 | 15 | %% Step 2: track features 16 | 17 | [trackedXs, trackedYs] = do_trackFeatures(config_file); 18 | 19 | %% Step 3: Affine Structure for Motion via Factorization 20 | 21 | [M S] = do_factorization(config_file); 22 | 23 | -------------------------------------------------------------------------------- /do_factorization.m: -------------------------------------------------------------------------------- 1 | function [M S] = do_factorization(config_file, Xs, Ys) 2 | %%%%%%%%%% 3 | % do_factorization.m 4 | % Using tracked points, implement affine structure from motion 5 | % procedure described in 6 | % "Shape and Motion from Image Streams under Orthography: a 7 | % Factorization Method" 1992 by Tomasi and Kanade. 8 | % 9 | % INPUT - Xs, Ys (optional): tracked 2D points from sequences in 10 | % format F x P, where F is the number of frames and P is the 11 | % number of points tracked. If not supplied will load from the file specified in config.m 12 | % 13 | % OUTPUT - M: 2*F by 3 Motion matrix (Camera movements) 14 | % - S: 3 by P Shape matrix (3D world coordinates) 15 | % 16 | % ALGORITHM 17 | % 1. represent the input as a 2F x P measurement matrix W 18 | % 2. Compute SVD of W = USV' 19 | % 3. Define M' = U_3(S_3)^(1/2), S' = (S_3)^(1/2)V'_3 (U_3 means the 20 | % first 3 x 3 block, where M' and S' are liner transformations of 21 | % the actual M and S 22 | % 4. Compute Q by imposing the metric constraints i.e. let L = QQ' 23 | % and solve Gl = c for l, use cholseky to recover Q 24 | % 5. Compute M and S using M', S', and Q 25 | % 26 | % Angjoo Kanazawa 12/14/'11 27 | %%%%%%%%%% 28 | 29 | %% Evaluate the global configuration file and load parameters 30 | eval(config_file); 31 | 32 | if nargin == 1 33 | data = load(tracked_pts_f); 34 | Xs = data.trackedXs; Ys = data.trackedYs; 35 | %-- just for now use the trustworthy points... 36 | load 'supp/tracked_points'; 37 | %-- 38 | end 39 | 40 | [F P] = size(Xs); 41 | 42 | %%% 0. to eliminate translation, center all points. i.e. subtract 43 | %% mean of each row 44 | Xs = bsxfun(@minus, Xs, mean(Xs, 2)); 45 | Ys = bsxfun(@minus, Ys, mean(Ys, 2)); 46 | 47 | %%% 1. compute W 48 | W = [Xs; Ys]; 49 | % W = zeros(2*F, P); 50 | % for f = 1:F 51 | % W(2*f-1:2*f, :) = [Xs(f, :); Ys(f, :)]; 52 | % end 53 | 54 | %%% 2. SVD of W 55 | [U D V] = svd(W); 56 | 57 | %%% 3. make M', S' 58 | Mhat = U(:, 1:3)*sqrt(D(1:3, 1:3)); 59 | Shat = sqrt(D(1:3, 1:3))*V(:, 1:3)'; 60 | 61 | %%% 4. Compute Q, impose the metric constraints 62 | Is = Mhat(1:F, :); 63 | Js = Mhat(F+1:end, :); 64 | 65 | 66 | gfun = @(a, b)[ a(1)*b(1), a(1)*b(2)+a(2)*b(1), a(1)*b(3)+a(3)*b(1), ... 67 | a(2)*b(2), a(2)*b(3)+a(3)*b(2), a(3)*b(3)] ; 68 | G = zeros(3*F, 6); 69 | for f = 1:3*F 70 | if f <= F 71 | G(f, :) = gfun(Is(f,:), Is(f,:)); 72 | elseif f <= 2*F 73 | % fprintf('do j(%d) ', mod(f, F+1)+1); 74 | G(f, :) = gfun(Js(mod(f, F+1)+1, :), Js(mod(f, F+1)+1, :)); 75 | else 76 | % fprintf('\tdo i,j(%d)', mod(f, 2*F)); 77 | G(f, :) = gfun(Is(mod(f, 2*F),:), Js(mod(f, 2*F),:)); 78 | end 79 | end 80 | 81 | c = [ones(2*F, 1); zeros(F, 1)]; 82 | 83 | % solve Gl = c by SVD and mldivide 84 | [U S V] = svd(G); 85 | hatl = U'*c; 86 | y = [hatl(1)/S(1,1); hatl(2)/S(2,2); hatl(3)/S(3,3); hatl(4)/S(4,4); ... 87 | hatl(5)/S(5,5); hatl(6)/S(6,6)]; 88 | l = V*y; 89 | fprintf('resid with SVD= Gl - c, %g\n', norm(G*l - c)); 90 | l2 = G\c; 91 | fprintf('resid with mldivide = Gl - c, %g\n', norm(G*l2 - c)); 92 | % they give the same result because matlab is optimized 93 | 94 | % could be a programatic way, but hey we "see" 3D or 2D 95 | L = [l(1) l(2) l(3);... 96 | l(2) l(4) l(5);... 97 | l(3) l(5) l(6)] ; 98 | Q = chol(L); % finally! 99 | 100 | %fprintf('check %g\n', all(all(L = Q'*Q))); 101 | 102 | %%% 5. get M and S 103 | M = Mhat*Q; 104 | S = inv(Q)*Shat; 105 | 106 | if VERBOSE 107 | %% plot of 3D points 108 | sfigure; 109 | plot3(Shat(1, :), Shat(2,:), Shat(3,:),'k.'); hold on; 110 | plot3(S(1, :), S(2,:), S(3,:),'b.'); 111 | plot3(0,0,0,'gs'); 112 | grid on; 113 | title(['3D points from tracked points: before and after eliminating ' ... 114 | 'affine ambiguity upto orthography']); 115 | legend('before','after', 'origin'); 116 | %% plot of the predicted 3D path of the cameras 117 | %The camera position for each frame is given by the cross product 118 | %kf = if × jf. For consistent results, normalize all kf to be unit 119 | %vectors. Give three plots, one for each dimension of kf. 120 | 121 | camera_pos = zeros(F, 3); 122 | for f = 1:F 123 | kf = cross(M(f,:), M(f+F, :)); 124 | camera_pos(f,:) = kf/norm(kf); % in unit norm 125 | end 126 | 127 | % save this plot in 3 axis....... 128 | %sfigure; plot3(camera_pos(:, 1), camera_pos(:, 2), camera_pos(:, 3),'.-'); 129 | sfigure; 130 | subplot(131);plot(camera_pos(:, 1), camera_pos(:, 2), '.-'); 131 | grid on; title('XY axis'); 132 | subplot(132);plot(camera_pos(:, 1), camera_pos(:, 3),'.-'); 133 | grid on; title('XZ axis'); 134 | subplot(133); plot(camera_pos(:, 2), camera_pos(:, 3),'.-'); 135 | grid on; title('YZ axis'); 136 | suptitle('camera position over all frames on'); 137 | % triangulate..? 138 | % remove the floor keypoint index 480 for mesh 139 | X = S(1, :); 140 | Y = S(2, :); 141 | Z = S(3, :); 142 | X(480) = []; Y(480) = []; Z(480) = []; 143 | % tri = delaunay(X,Y); 144 | % trisurf(tri,Y,X,Z); 145 | imFiles = getImageSet(IMAGE_DIR); 146 | im = im2double(imread(imFiles{1})); 147 | keyboard 148 | % sfigure; surf(X,Y,Z,im,'FaceColor', 'texturemap'); 149 | % sfigure; trimesh(tri, X,Y,Z); 150 | % sfigure; trisurf(tri, X,Y,Z, im, 'FaceColor', 'texturemap'); 151 | end 152 | -------------------------------------------------------------------------------- /do_getKeypoints.m: -------------------------------------------------------------------------------- 1 | function [keyXs, keyYs] = do_getKeypoints(config_file) 2 | %%%%%%%%%% 3 | % getKeypoints.m 4 | % script to get the key points from im using Harris corner detector 5 | % INPUT - im: image to get the keypoint 6 | % tau: threshold to do non-maxima supression 7 | % 8 | % OUTPUT - keyXs, keyYs: keypoints found in the initial 9 | % frame. saves them in the file specified by config.m 10 | % 11 | % parts of script referenced from: http://www.csse.uwa.edu.au/~pk/research/matlabfns/ 12 | % 13 | % Angjoo Kanazawa 11/23/'11 14 | %%%%%%%%%% 15 | 16 | %% Evaluate the global configuration file and load parameters 17 | eval(config_file); 18 | 19 | imFiles = getImageSet(IMAGE_DIR); % gets cell array of frames (img files) 20 | F = length(imFiles); % number of frames 21 | fprintf('getting intial keypoints from %s\n', imFiles{1}); 22 | 23 | im = double(imread(imFiles{1})); 24 | 25 | if strcmp(Feature.method, 'harris') 26 | % compute image derivatives in x and y using Peter Kovesi's 27 | % accurate derivative 28 | [Ix Iy] = derivative5(im, 'x', 'y'); 29 | % old way 30 | % dx = [ -1 0 1 ; -1 0 1 ; -1 0 1]; 31 | % dy = dx'; 32 | % Ix = imfilter(im, dx, 'same'); 33 | % Iy = imfilter(im, dy, 'same'); 34 | 35 | % compute components of H 36 | Ix2 = Ix.^2; 37 | Iy2 = Iy.^2; 38 | IxIy = Ix.*Iy ; 39 | 40 | % smooth H using gaussian filter 41 | filt = fspecial('gaussian', 6*Feature.sigma, Feature.sigma); 42 | Ix2sm = imfilter(Ix2, filt, 'same'); 43 | Iy2sm = imfilter(Ix2, filt, 'same'); 44 | IxIysm = imfilter(IxIy, filt, 'same'); 45 | 46 | % display plot 47 | if VERBOSE 48 | sfigure; subplot(2,2,1); imagesc(im); title('original'); %colormap('gray'); 49 | subplot(2,2,2); imagesc(Ix); colormap('gray');title('der in x'); 50 | subplot(2,2,3); imagesc([Ix2 IxIy; IxIy Iy2]);title('hessian'); ... 51 | %colormap('gray'); 52 | subplot(2,2,4); imagesc([Ix2sm IxIysm; IxIysm Iy2sm]); ... 53 | title('smoothed hessian'); 54 | % colormap('gray'); 55 | end 56 | 57 | % compute the corner response matrix = det(H) - a*trace(H)^2 58 | M = Ix2sm.*Iy2sm - IxIy.^2 - Feature.alpha*(Ix2sm + Iy2sm).^2; 59 | 60 | % perform non-maxima supression over Feature.radius window size 61 | 62 | % Make mask to exclude points within Feature.radius of the image boundary. 63 | bordermask = zeros(size(im)); 64 | bordermask(Feature.radius+1:end-Feature.radius, Feature.radius+1:end-Feature.radius) = 1; 65 | % dilate image 66 | M_sup = ordfilt2(M, Feature.radius^2, ones(Feature.radius)); 67 | % find points that's still there in dilated image & stronger than Feature.tau 68 | corner = (M==M_sup) & M>Feature.tau & bordermask; 69 | 70 | % plot 71 | if VERBOSE 72 | sfigure; subplot(221); imagesc(M); title('corner response M'); 73 | subplot(222); imagesc(M_sup); title('max dilated'); 74 | colormap('gray'); 75 | subplot(223); imagesc(M> Feature.tau); title(['corner response > thresh']); 76 | colormap('gray'); 77 | subplot(224); imagesc(corner); title('corner response max suppressed'); 78 | colormap('gray'); 79 | end 80 | 81 | [keyXs, keyYs] = find(corner); % get the r, c index of key points 82 | 83 | else %do SIFT 84 | keyXs = []; 85 | keyYs = []; 86 | end 87 | 88 | if VERBOSE 89 | sfigure; 90 | imagesc(im); colormap('gray'); hold on; 91 | plot(keyYs, keyXs, 'y.'); 92 | title(['first frame overlayed with keypoints']); 93 | end 94 | 95 | save(keypoints_f, 'keyXs', 'keyYs'); 96 | -------------------------------------------------------------------------------- /do_trackFeatures.m: -------------------------------------------------------------------------------- 1 | function [trackedXs, trackedYs] = do_trackFeatures(config_file) 2 | %%%%%%%%%% 3 | % do_trackFeatures.m 4 | % Top level file to track freatures from the key points obtained in 5 | % do_getKeypoints.m 6 | % OUTPUT - trackedXs, trackedYs: the tracked points. Saves the 7 | % result in the file specified by config.m 8 | % 9 | % DESCRIPTION 10 | % for each keypoint at frame f, I(x,y,f), we want to compute 11 | % expected translation in the next frame I(x', y', f+1) 12 | % 13 | % Angjoo Kanazawa 12/16/'11 14 | %%%%%%%%%% 15 | 16 | %% Evaluate the global configuration file and load parameters 17 | eval(config_file); 18 | 19 | % load the data computed in do_getKeypoints.m 20 | load(keypoints_f, 'keyXs', 'keyYs'); 21 | 22 | % gets cell array of image file names (frames) 23 | imFiles = getImageSet(IMAGE_DIR); 24 | F = length(imFiles); 25 | P = numel(keyXs); 26 | if ~exist(tracked_pts_f); 27 | trackedXs = zeros(F, P); 28 | trackedYs = zeros(F, P); 29 | trackedXs(1, :) = keyXs; trackedYs(1, :) = keyYs; 30 | for i=2:F 31 | [trackedXs(i,:) trackedYs(i,:)] = predictTranslationAll(trackedXs(i-1, :), trackedYs(i-1, :),... 32 | imread(imFiles{i-1}), imread(imFiles{i})); 33 | end 34 | % remove nans i.e. points that went out of frame 35 | outFrame = find(isnan(trackedXs(end, :))); 36 | trackedXs(:, outFrame) = []; 37 | trackedYs(:, outFrame) = []; 38 | P = P - numel(outFrame); 39 | save(tracked_pts_f, 'trackedXs', 'trackedYs', 'P'); 40 | else 41 | load(tracked_pts_f); 42 | end 43 | 44 | 45 | %% Draw the path of random 30 tracked points over all frames 46 | if VERBOSE 47 | % frame 1, 15, 30, and 45 48 | sfigure; subplot(141); imagesc(imread(imFiles{1}));colormap('gray'); 49 | axis off; title('frame 1'); 50 | subplot(142); imagesc(imread(imFiles{15})); colormap('gray'); 51 | axis off; title('frame 15'); 52 | subplot(143); imagesc(imread(imFiles{30})); colormap('gray'); 53 | axis off; title('frame 30'); 54 | subplot(144); imagesc(imread(imFiles{45})); colormap('gray'); 55 | axis off; title('frame 45'); 56 | suptitle('frame 1, 15, 30, and 45 of the hotel sequence'); 57 | 58 | pts = randperm(P); 59 | pts = pts(1:30); 60 | 61 | sfigure; imagesc(imread(imFiles{1})); colormap('gray'); hold on; 62 | plot(trackedXs(1, pts), trackedYs(1,pts),'m*'); 63 | for f=2:F 64 | plot(trackedXs(f, pts), trackedYs(f,pts), 'b.'); 65 | end 66 | title('the path of random 30 points tracked over all frames'); 67 | % for f = 1:F-1 68 | % u = trackedXs(f+1, pts)- trackedXs(f, pts); 69 | % v = trackedYs(f+1, pts)-trackedYs(f, pts); 70 | % uv= [u;v]; 71 | % quiver(trackedYs(f, pts),trackedXs(f, pts),uv(2,:), uv(1,:)); 72 | % end 73 | end 74 | 75 | -------------------------------------------------------------------------------- /harris.m: -------------------------------------------------------------------------------- 1 | % HARRIS - Harris corner detector 2 | % 3 | % Usage: cim = harris(im, sigma) 4 | % [cim, r, c] = harris(im, sigma, thresh, radius, disp) 5 | % [cim, r, c, rsubp, csubp] = harris(im, sigma, thresh, radius, disp) 6 | % 7 | % Arguments: 8 | % im - image to be processed. 9 | % sigma - standard deviation of smoothing Gaussian. Typical 10 | % values to use might be 1-3. 11 | % thresh - threshold (optional). Try a value ~1000. 12 | % radius - radius of region considered in non-maximal 13 | % suppression (optional). Typical values to use might 14 | % be 1-3. 15 | % disp - optional flag (0 or 1) indicating whether you want 16 | % to display corners overlayed on the original 17 | % image. This can be useful for parameter tuning. This 18 | % defaults to 0 19 | % 20 | % Returns: 21 | % cim - binary image marking corners. 22 | % r - row coordinates of corner points. 23 | % c - column coordinates of corner points. 24 | % rsubp - If five return values are requested sub-pixel 25 | % csubp - localization of feature points is attempted and 26 | % returned as an additional set of floating point 27 | % coords. Note that you may still want to use the integer 28 | % valued coords to specify centres of correlation windows 29 | % for feature matching. 30 | % 31 | % If thresh and radius are omitted from the argument list only 'cim' is returned 32 | % as a raw corner strength image. You may then want to look at the values 33 | % within 'cim' to determine the appropriate threshold value to use. Note that 34 | % the Harris corner strength varies with the intensity gradient raised to the 35 | % 4th power. Small changes in input image contrast result in huge changes in 36 | % the appropriate threshold. 37 | % 38 | % Note that this code computes Noble's version of the detector which does not 39 | % require the parameter 'k'. See comments in code if you wish to use Harris' 40 | % original measure. 41 | % 42 | % See also: NONMAXSUPPTS, DERIVATIVE5 43 | 44 | % References: 45 | % C.G. Harris and M.J. Stephens. "A combined corner and edge detector", 46 | % Proceedings Fourth Alvey Vision Conference, Manchester. 47 | % pp 147-151, 1988. 48 | % 49 | % Alison Noble, "Descriptions of Image Surfaces", PhD thesis, Department 50 | % of Engineering Science, Oxford University 1989, p45. 51 | 52 | % Copyright (c) 2002-2010 Peter Kovesi 53 | % Centre for Exploration Targeting 54 | % The University of Western Australia 55 | % http://www.csse.uwa.edu.au/~pk/research/matlabfns/ 56 | % 57 | % Permission is hereby granted, free of charge, to any person obtaining a copy 58 | % of this software and associated documentation files (the "Software"), to deal 59 | % in the Software without restriction, subject to the following conditions: 60 | % 61 | % The above copyright notice and this permission notice shall be included in 62 | % all copies or substantial portions of the Software. 63 | % 64 | % The Software is provided "as is", without warranty of any kind. 65 | 66 | % March 2002 - Original version 67 | % December 2002 - Updated comments 68 | % August 2005 - Changed so that code calls nonmaxsuppts 69 | % August 2010 - Changed to use Farid and Simoncelli's derivative filters 70 | 71 | function [cim, r, c, rsubp, csubp] = harris(im, sigma, thresh, radius, disp) 72 | 73 | error(nargchk(2,5,nargin)); 74 | if nargin == 4 75 | disp = 0; 76 | end 77 | 78 | if ~isa(im,'double') 79 | im = double(im); 80 | end 81 | 82 | subpixel = nargout == 5; 83 | 84 | % Compute derivatives and elements of the structure tensor. 85 | [Ix, Iy] = derivative5(im, 'x', 'y'); 86 | Ix2 = gaussfilt(Ix.^2, sigma); 87 | Iy2 = gaussfilt(Iy.^2, sigma); 88 | Ixy = gaussfilt(Ix.*Iy, sigma); 89 | 90 | % Compute the Harris corner measure. Note that there are two measures 91 | % that can be calculated. I prefer the first one below as given by 92 | % Nobel in her thesis (reference above). The second one (commented out) 93 | % requires setting a parameter, it is commonly suggested that k=0.04 - I 94 | % find this a bit arbitrary and unsatisfactory. 95 | 96 | cim = (Ix2.*Iy2 - Ixy.^2)./(Ix2 + Iy2 + eps); % My preferred measure. 97 | % k = 0.04; 98 | % cim = (Ix2.*Iy2 - Ixy.^2) - k*(Ix2 + Iy2).^2; % Original Harris measure. 99 | 100 | if nargin > 2 % We should perform nonmaximal suppression and threshold 101 | 102 | if disp % Call nonmaxsuppts to so that image is displayed 103 | if subpixel 104 | [r,c,rsubp,csubp] = nonmaxsuppts(cim, radius, thresh, im); 105 | else 106 | [r,c] = nonmaxsuppts(cim, radius, thresh, im); 107 | end 108 | else % Just do the nonmaximal suppression 109 | if subpixel 110 | [r,c,rsubp,csubp] = nonmaxsuppts(cim, radius, thresh); 111 | else 112 | [r,c] = nonmaxsuppts(cim, radius, thresh); 113 | end 114 | end 115 | end 116 | 117 | -------------------------------------------------------------------------------- /predictTranslation.m: -------------------------------------------------------------------------------- 1 | function [newX newY] = predictTranslation(startX, startY,Ix, Iy,im0,im1); 2 | %%%%%%%%%% 3 | % implementation of the KLT tracker introduced in: 4 | % Carlo Tomasi and Takeo Kanade. Detection and Tracking of Point Features. Carnegie Mellon University Technical Report CMU-CS-91-132, April 1991. 5 | % predictTranslation.m 6 | % For a single X Y location, use Ix and Iy, im0 and im1 to compute 7 | % the new location X', Y' iteratively using Newton-Raphson style iteration 8 | % 9 | % Angjoo Kanazawa 11/23/'11 10 | %%%%%%%%%% 11 | 12 | % Using the brightness constancy assumption, we expect the pixel 13 | % intensity of location x, y at frame f is same as the pixel 14 | % instensiy of location x'=x+u, y'=y+v at frame f+1 15 | % i.e. I(x,y,f) = I(x', y', f+1), where u and v are displacement of 16 | % pixels in the next frame. 17 | 18 | % With an additional constraint that this must be true within w by w window, this amounts to solving the LSP: 19 | % -I_t(ps) = grad I(ps)[u; v] => Ax = b 20 | % where A = grad I(ps), b = -I_t(ps), x = [u;v] 21 | % - ps are all points in the w by w window 22 | % - I_t is the temporal gradient: I(x'y', f+1) - I(x,y,f) 23 | 24 | %% Step 1 compute the gradient of im0 25 | 26 | WINDOW = 15; 27 | % ignore points that are outside or close to the border (within 3) 28 | radius = 3; 29 | bordermask = zeros(size(im0)); 30 | bordermask(radius+1:end-radius, radius+1:end-radius) = 1; 31 | 32 | % all points in the window x window 33 | % make A: [sum_w Ix*Ix sum_w Ix*Iy; sum_w Ix*Iy sum_w Iy*Iy] 34 | 35 | % get the indices of the window grid we want to look at 36 | [x_w, y_w] = meshgrid(startX-WINDOW:startX+WINDOW, startY-WINDOW:startY+WINDOW); 37 | Img1_w = interp2(im0, x_w, y_w); 38 | Img2_w = interp2(im1, x_w, y_w); 39 | Ix_w = interp2(Ix, x_w, y_w); 40 | Ix_w = Ix_w(~isnan(Ix_w)); 41 | Iy_w = interp2(Iy, x_w, y_w); 42 | Iy_w = Iy_w(~isnan(Iy_w)); 43 | 44 | Ixy_w = interp2(Iy.*Ix, x_w, y_w); 45 | Ixy_w = Ixy_w(~isnan(Ixy_w)); 46 | 47 | A = [sum(Ix_w.^2) sum(Ixy_w); sum(Ixy_w) sum(Iy_w.^2)]; 48 | 49 | %% get It = I(x', y', t+1) - (x,y,t+1) 50 | % iteratively so the first one is, (x0', y0') = (x,y) 51 | 52 | diff = norm(Img2_w- Img1_w); 53 | dx = 100; 54 | uv = [0;0]; %(x',y') starts at (x0,y0) 55 | itr = 0; 56 | maxItr = 30; 57 | while dx > 0.01 & itr < maxItr 58 | Img2_w_new = interp2(im1, x_w+uv(1), y_w+uv(2)); 59 | It = Img2_w_new - Img1_w; 60 | % remove if point/window (X+uv) moves out of frame 61 | if length(find(isnan(It)))>0 62 | uv = [NaN; NaN]; 63 | break; 64 | end 65 | % calculate b = - [sum_w IxIt sum_w IyIt] 66 | b = - [sum(Ix_w.*It(:)); sum(Iy_w.*It(:))]; 67 | % estimate (u,v) 68 | keyboard 69 | uv_new = A\b; 70 | % update displacement 71 | uv = uv+uv_new; 72 | itr = itr + 1; 73 | diffNew =norm(Img2_w - Img2_w_new); 74 | if diff < diffNew 75 | break; 76 | end 77 | dx = abs(diff - diffNew); 78 | diff = diffNew; 79 | end 80 | if isnan(uv) 81 | newX = nan; newY=nan; 82 | else 83 | %maybe not needed but check if this computed uv sets key point 84 | %out of frame 85 | x_int = interp2(im1, startX+uv(1), startY+uv(2)); 86 | if isnan(x_int) 87 | newX = nan; newY=nan; 88 | fprintf('\nout of frame!\n'); 89 | else 90 | newX = startX+uv(1); newY = startY+uv(2); 91 | end 92 | end 93 | -------------------------------------------------------------------------------- /predictTranslationAll.m: -------------------------------------------------------------------------------- 1 | function [newXs newYs] = predictTranslationAll(startXs, startYs,im0,im1); 2 | %%%%%%%%%% 3 | % implementation of the KLT tracker introduced in: 4 | % Carlo Tomasi and Takeo Kanade. Detection and Tracking of Point Features. Carnegie Mellon University Technical Report CMU-CS-91-132, April 1991. 5 | % predictTranslationAll.m 6 | % script to get new X, Y, locations in im1 for all startXs and 7 | % startYs in im0 8 | % 9 | % Computes the gradients here, calls predictTranslation.m to get 10 | % predict eahc keypoint independently 11 | % 12 | % Angjoo Kanazawa 11/23/'11 13 | %%%%%%%%%% 14 | 15 | if ~isa(im0, 'double') im0 = double(im0); end 16 | if ~isa(im1, 'double') im1 = double(im1); end 17 | 18 | % Using the brightness constancy assumption, we expect the pixel 19 | % intensity of location x, y at frame f is same as the pixel 20 | % instensiy of location x'=x+u, y'=y+v at frame f+1 21 | % i.e. I(x,y,f) = I(x', y', f+1), where u and v are displacement of 22 | % pixels in the next frame. 23 | 24 | % With an additional constraint that this must be true within w by w window, this amounts to solving the LSP: 25 | % -I_t(ps) = grad I(ps)[u; v] => Ax = b 26 | % where A = grad I(ps), b = -I_t(ps), x = [u;v] 27 | % - ps are all points in the w by w window 28 | % - I_t is the temporal gradient: I(x'y', f+1) - I(x,y,f) 29 | 30 | %% Step 1 compute the gradient of im0 31 | 32 | [Ix Iy] = derivative5(im0, 'x', 'y'); 33 | numPoints = length(startXs); 34 | newXs = zeros(numPoints, 1); newYs = zeros(numPoints, 1); 35 | for i=1:numPoints 36 | fprintf('.'); 37 | if ~isnan(startXs(i)) || ~isnan(startYs(i)) 38 | [newX newY] = predictTranslation(startXs(i), startYs(i), Ix, Iy, ... 39 | im0, im1); 40 | else 41 | newX = nan; newY= nan; 42 | end 43 | newXs(i) = newX; 44 | newYs(i) = newY; 45 | end 46 | end 47 | 48 | -------------------------------------------------------------------------------- /supp/images/hotel.seq0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq0.png -------------------------------------------------------------------------------- /supp/images/hotel.seq1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq1.png -------------------------------------------------------------------------------- /supp/images/hotel.seq10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq10.png -------------------------------------------------------------------------------- /supp/images/hotel.seq11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq11.png -------------------------------------------------------------------------------- /supp/images/hotel.seq12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq12.png -------------------------------------------------------------------------------- /supp/images/hotel.seq13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq13.png -------------------------------------------------------------------------------- /supp/images/hotel.seq14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq14.png -------------------------------------------------------------------------------- /supp/images/hotel.seq15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq15.png -------------------------------------------------------------------------------- /supp/images/hotel.seq16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq16.png -------------------------------------------------------------------------------- /supp/images/hotel.seq17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq17.png -------------------------------------------------------------------------------- /supp/images/hotel.seq18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq18.png -------------------------------------------------------------------------------- /supp/images/hotel.seq19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq19.png -------------------------------------------------------------------------------- /supp/images/hotel.seq2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq2.png -------------------------------------------------------------------------------- /supp/images/hotel.seq20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq20.png -------------------------------------------------------------------------------- /supp/images/hotel.seq21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq21.png -------------------------------------------------------------------------------- /supp/images/hotel.seq22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq22.png -------------------------------------------------------------------------------- /supp/images/hotel.seq23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq23.png -------------------------------------------------------------------------------- /supp/images/hotel.seq24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq24.png -------------------------------------------------------------------------------- /supp/images/hotel.seq25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq25.png -------------------------------------------------------------------------------- /supp/images/hotel.seq26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq26.png -------------------------------------------------------------------------------- /supp/images/hotel.seq27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq27.png -------------------------------------------------------------------------------- /supp/images/hotel.seq28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq28.png -------------------------------------------------------------------------------- /supp/images/hotel.seq29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq29.png -------------------------------------------------------------------------------- /supp/images/hotel.seq3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq3.png -------------------------------------------------------------------------------- /supp/images/hotel.seq30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq30.png -------------------------------------------------------------------------------- /supp/images/hotel.seq31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq31.png -------------------------------------------------------------------------------- /supp/images/hotel.seq32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq32.png -------------------------------------------------------------------------------- /supp/images/hotel.seq33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq33.png -------------------------------------------------------------------------------- /supp/images/hotel.seq34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq34.png -------------------------------------------------------------------------------- /supp/images/hotel.seq35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq35.png -------------------------------------------------------------------------------- /supp/images/hotel.seq36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq36.png -------------------------------------------------------------------------------- /supp/images/hotel.seq37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq37.png -------------------------------------------------------------------------------- /supp/images/hotel.seq38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq38.png -------------------------------------------------------------------------------- /supp/images/hotel.seq39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq39.png -------------------------------------------------------------------------------- /supp/images/hotel.seq4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq4.png -------------------------------------------------------------------------------- /supp/images/hotel.seq40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq40.png -------------------------------------------------------------------------------- /supp/images/hotel.seq41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq41.png -------------------------------------------------------------------------------- /supp/images/hotel.seq42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq42.png -------------------------------------------------------------------------------- /supp/images/hotel.seq43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq43.png -------------------------------------------------------------------------------- /supp/images/hotel.seq44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq44.png -------------------------------------------------------------------------------- /supp/images/hotel.seq45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq45.png -------------------------------------------------------------------------------- /supp/images/hotel.seq46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq46.png -------------------------------------------------------------------------------- /supp/images/hotel.seq47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq47.png -------------------------------------------------------------------------------- /supp/images/hotel.seq48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq48.png -------------------------------------------------------------------------------- /supp/images/hotel.seq49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq49.png -------------------------------------------------------------------------------- /supp/images/hotel.seq5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq5.png -------------------------------------------------------------------------------- /supp/images/hotel.seq50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq50.png -------------------------------------------------------------------------------- /supp/images/hotel.seq6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq6.png -------------------------------------------------------------------------------- /supp/images/hotel.seq7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq7.png -------------------------------------------------------------------------------- /supp/images/hotel.seq8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq8.png -------------------------------------------------------------------------------- /supp/images/hotel.seq9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/images/hotel.seq9.png -------------------------------------------------------------------------------- /supp/initial_keypoints.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/initial_keypoints.mat -------------------------------------------------------------------------------- /supp/tracked_points.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/supp/tracked_points.mat -------------------------------------------------------------------------------- /tracked_points.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akanazawa/Structure-from-Motion/c345910325804e0a73bac6234f0b611f85e63ece/tracked_points.mat --------------------------------------------------------------------------------