diff -u -N siftDemoV4/find_in_path.m siftDemoV4-mine/find_in_path.m --- siftDemoV4/find_in_path.m 1969-12-31 16:00:00.000000000 -0800 +++ siftDemoV4-mine/find_in_path.m 2007-01-16 09:17:10.000000000 -0800 @@ -0,0 +1,23 @@ +## f2 = find_in_path (f[, p=path()]) - Find f in path +## +## Returns the full name (path and filename) of the first file named f that can +## be found in one of the directories listed in p. Directories should be +## separated by the character pathsep(). If only one argument is passed to +## find_in_path(), p is set to path(). Returns "" if no file is found. +## +function f2 = find_in_path (f, pp) + +if nargin < 2, pp = path(); endif + +ii = [0, find(pathsep() == pp), length(pp)]; + +fs = filesep(); + +for i = 1:length(ii)-1 + if !isempty (stat ([pp(ii(i)+1:ii(i+1)-1),fs,f])) + f2 = [pp(ii(i)+1:ii(i+1)-1),fs,f]; + return; + endif +endfor +f2 = ""; + diff -u -N siftDemoV4/imglines.m siftDemoV4-mine/imglines.m --- siftDemoV4/imglines.m 1969-12-31 16:00:00.000000000 -0800 +++ siftDemoV4-mine/imglines.m 2007-01-15 14:24:01.000000000 -0800 @@ -0,0 +1,34 @@ +## im2 = imglines (im, [r1,c1,r2,c2], col) - Plot line segments on a bitmap +## +## im : R x C : Greylevel image +## r1c1r2c2 : N x 4 : Enpoint coordinates of segments +## col : N x 1 : Color (default: lightest color of image, or +## lightest+1, if image is uniform) +## +## im2 : R x C : Output image +## +## TODO: Clip segments that stick out of image. +## Do color images too. +## +## Author: Etienne Grossmann , 2005 +function im = imglines (im, pts, col) + +sz = size (im); + +if nargin < 3, col = max (im(:)); col += (col==min(im(:))); end + +if all (size(col) == 1), col = col*ones(rows(pts),1); end + +for i = 1:rows (pts) # Draw line segments + waitbar (i/rows(pts)); + p = pts(i,:); + + len = round (1+max(abs(p(3)-p(1)),abs(p(4)-p(2)))); + + ii = sub2ind (sz, \ + round (linspace(p(1),p(3),len)),\ + round (linspace(p(2),p(4),len))); + + im(ii) = col(i); +endfor + diff -u -N siftDemoV4/Makefile siftDemoV4-mine/Makefile --- siftDemoV4/Makefile 2005-07-07 21:54:12.000000000 -0700 +++ siftDemoV4-mine/Makefile 2007-01-15 14:24:01.000000000 -0800 @@ -25,5 +25,9 @@ match: ${OBJ} ${CC} -o $@ ${CFLAGS} ${OBJ} ${LIBS} +clean: + rm -f *.o *~ + # Implicit rule used by Gnu Make: $(CC) -c $(CPPFLAGS) $(CFLAGS) ${OBJ}: ${DEFS} + Binary files siftDemoV4/match and siftDemoV4-mine/match differ diff -u -N siftDemoV4/match.m siftDemoV4-mine/match.m --- siftDemoV4/match.m 2005-07-07 21:54:12.000000000 -0700 +++ siftDemoV4-mine/match.m 2007-02-27 16:13:07.000000000 -0800 @@ -1,4 +1,4 @@ -% num = match(image1, image2) +% [num, loc1, loc2, matches, des1, des2] = match(image1, image2) % % This function reads two images, finds their SIFT features, and % displays lines connecting the matched keypoints. A match is accepted @@ -6,9 +6,30 @@ % second closest match. % It returns the number of matches displayed. % -% Example: match('scene.pgm','book.pgm'); +% # Try it! These images are put in your loadpath by sift. +% Example: match('scene.pgm','book.pgm'); -function num = match(image1, image2) +function [num, loc1, loc2, match, des1, des2] = match (image1, image2) + +running_octave = exist ('OCTAVE_VERSION'); + % Find image in loadpath if needed. This is + % mostly so that example code works as-is. +if running_octave + if ischar (image1) + if isempty(stat (image1)) + tmp = find_in_path (image1); + if ~ tmp, error ('can''t find %s',image1); end + image1 = tmp; + end + end + if ischar (image2) + if isempty(stat (image2)) + tmp = find_in_path (image2); + if ~ tmp, error ('can''t find %s',image2); end + image2 = tmp; + end + end +end % Find SIFT keypoints for each image [im1, des1, loc1] = sift(image1); @@ -25,6 +46,8 @@ % For each descriptor in the first image, select its match to second image. des2t = des2'; % Precompute matrix transpose +match = zeros(size(des1,1),1); + for i = 1 : size(des1,1) dotprods = des1(i,:) * des2t; % Computes vector of dot products [vals,indx] = sort(acos(dotprods)); % Take inverse cosine and sort results @@ -41,21 +64,29 @@ im3 = appendimages(im1,im2); % Show a figure with lines joining the accepted matches. -figure('Position', [100 100 size(im3,2) size(im3,1)]); -colormap('gray'); -imagesc(im3); -hold on; -cols1 = size(im1,2); -for i = 1: size(des1,1) - if (match(i) > 0) - line([loc1(i,2) loc2(match(i),2)+cols1], ... - [loc1(i,1) loc2(match(i),1)], 'Color', 'c'); + +if ~running_octave % Matlab code + figure('Position', [100 100 size(im3,2) size(im3,1)]); + colormap('gray'); + imagesc(im3); + hold on; + cols1 = size(im1,2); + for i = 1: size(des1,1) + if (match(i) > 0) + line([loc1(i,2) loc2(match(i),2)+cols1], ... + [loc1(i,1) loc2(match(i),1)], 'Color', 'c'); + end end + hold off; + num = sum(match > 0); + fprintf('Found %d matches.\n', num); + +else % Octave code + num = sum(match > 0); + ii = find (match>0); + im3 = imglines (im3, [loc1(ii,1), loc1(ii,2), loc2(match(ii),1), loc2(match(ii),2)+columns(im1)]); + imagesc(im3); + end -hold off; -num = sum(match > 0); -fprintf('Found %d matches.\n', num); - - diff -u -N siftDemoV4/match_mine.m siftDemoV4-mine/match_mine.m --- siftDemoV4/match_mine.m 1969-12-31 16:00:00.000000000 -0800 +++ siftDemoV4-mine/match_mine.m 2007-01-18 13:44:54.000000000 -0800 @@ -0,0 +1,99 @@ +% [num, loc1, loc2, matches, des1, des2] = match(image1, image2) +% +% This function reads two images, finds their SIFT features, and +% displays lines connecting the matched keypoints. A match is accepted +% only if its distance is less than distRatio times the distance to the +% second closest match. +% It returns the number of matches displayed. +% +% # Try it! These images are put in your loadpath by sift. +% Example: match('scene.pgm','book.pgm'); +% +% Plot only first 20 matches. +function [num, loc1, loc2, match, des1, des2] = match (image1, image2) + +running_octave = exist ('OCTAVE_VERSION'); + % Find image in loadpath if needed. This is + % mostly so that example code works as-is. +if running_octave + if isempty(stat (image1)) + tmp = find_in_path (image1); + if ~ tmp, error ('can''t find %s',image1); end + image1 = tmp; + end + if isempty(stat (image2)) + tmp = find_in_path (image2); + if ~ tmp, error ('can''t find %s',image2); end + image2 = tmp; + end +end + +% Find SIFT keypoints for each image +[im1, des1, loc1] = sift(image1); +[im2, des2, loc2] = sift(image2); + +% For efficiency in Matlab, it is cheaper to compute dot products between +% unit vectors rather than Euclidean distances. Note that the ratio of +% angles (acos of dot products of unit vectors) is a close approximation +% to the ratio of Euclidean distances for small angles. +% +% distRatio: Only keep matches in which the ratio of vector angles from the +% nearest to second nearest neighbor is less than distRatio. +distRatio = 0.6; + +% For each descriptor in the first image, select its match to second image. +des2t = des2'; % Precompute matrix transpose +match = zeros(size(des1,1),1); +goodness = zeros(size(des1,1),1); +for i = 1 : size(des1,1) + dotprods = des1(i,:) * des2t; % Computes vector of dot products + [vals,indx] = sort(acos(dotprods)); % Take inverse cosine and sort results + + % Check if nearest neighbor has angle less than distRatio times 2nd. + if (vals(1) < distRatio * vals(2)) + match(i) = indx(1); + goodness(i) = vals(1); + else + match(i) = 0; + end +end +goodness(~match) = inf; +maxmatches = 20; +if length(goodness)>maxmatches + goodthreshold = sort (goodness)(maxmatches); +else + goodthreshold = max(goodness); +endif +selected = goodness <= goodthreshold; +keyboard + +% Create a new image showing the two images side by side. +im3 = appendimages(appendimages(im1,zeros(1,100)),im2); + +% Show a figure with lines joining the accepted matches. + +if ~running_octave % Matlab code + figure('Position', [100 100 size(im3,2) size(im3,1)]); + colormap('gray'); + imagesc(im3); + hold on; + cols1 = size(im1,2); + for i = 1: size(des1,1) + if (match(i) > 0) + line([loc1(i,2) loc2(match(i),2)+cols1], ... + [loc1(i,1) loc2(match(i),1)], 'Color', 'c'); + end + end + hold off; + num = sum(match > 0); + fprintf('Found %d matches.\n', num); + +else % Octave code + ii = find (match>0 & selected); + num = length (ii); + im3 = imglines (im3, [loc1(ii,1), loc1(ii,2), loc2(match(ii),1), loc2(match(ii),2)+columns(im1)+100]); + imagesc(im3); + +end + + diff -u -N siftDemoV4/showkeys.m siftDemoV4-mine/showkeys.m --- siftDemoV4/showkeys.m 2005-07-07 21:54:12.000000000 -0700 +++ siftDemoV4-mine/showkeys.m 2007-01-15 14:24:01.000000000 -0800 @@ -11,19 +11,37 @@ disp('Drawing SIFT keypoints ...'); % Draw image with keypoints -figure('Position', [50 50 size(image,2) size(image,1)]); -colormap('gray'); -imagesc(image); -hold on; -imsize = size(image); -for i = 1: size(locs,1) +if ~ exist('OCTAVE_VERSION') % If under Matlab + + figure('Position', [50 50 size(image,2) size(image,1)]); + colormap('gray'); + imagesc(image); + hold on; + imsize = size(image); + for i = 1: size(locs,1) % Draw an arrow, each line transformed according to keypoint parameters. TransformLine(imsize, locs(i,:), 0.0, 0.0, 1.0, 0.0); TransformLine(imsize, locs(i,:), 0.85, 0.1, 1.0, 0.0); TransformLine(imsize, locs(i,:), 0.85, -0.1, 1.0, 0.0); -end -hold off; + end + hold off; + +else % If running Octave + imsize = size(image); + lines = zeros (3*size(locs,1),4); + for i = 1: size(locs,1) + % Draw an arrow, each line transformed according to keypoint parameters. + waitbar (i/size(locs,1)); + lines(3*i-2,:) = TransformLineCoords(imsize, locs(i,:), 0.0, 0.0, 1.0, 0.0); + lines(3*i-1,:) = TransformLineCoords(imsize, locs(i,:), 0.85, 0.1, 1.0, 0.0); + lines(3*i-0,:) = TransformLineCoords(imsize, locs(i,:), 0.85, -0.1, 1.0, 0.0); + end + lines = min (lines,ones(rows(lines),1)*imsize([1 2 1 2])); + lines = max (lines,1); + image = imglines (image,lines); + imagesc(image); +end % ------ Subroutine: TransformLine ------- % Draw the given line in the image, but first translate, rotate, and diff -u -N siftDemoV4/sift.m siftDemoV4-mine/sift.m --- siftDemoV4/sift.m 2005-07-07 21:54:12.000000000 -0700 +++ siftDemoV4-mine/sift.m 2007-02-27 16:14:26.000000000 -0800 @@ -19,8 +19,24 @@ function [image, descriptors, locs] = sift(imageFile) % Load image -image = imread(imageFile); - +if ischar (imageFile) + image = imread(imageFile); +else + image = imageFile; +end +if !isnumeric (image) + error ('Image should be numeric. Got a %s.',typeinfo(image)); +end +if length (size (image)) ~= 2 + image = squeeze (image); + if length (size (image)) == 3 + image = (image(:,:,1)+image(:,:,2)+image(:,:,3))/3; + elseif length (size (image)) ~= 2 + szstr = sprintf('%i x',size(image)); + error (['Image should be either a H x W greylevel matrix ',... + 'or a H x W x 3 RGB array. Got a ',szstr(1:end-2),' array']); + end +end % If you have the Image Processing Toolbox, you can uncomment the following % lines to allow input of color images, which will be converted to grayscale. % if isrgb(image) @@ -38,14 +54,30 @@ fwrite(f, image', 'uint8'); fclose(f); -% Call keypoints executable -if isunix + +if ~ exist ('OCTAVE_VERSION') % Running Matlab + % Call keypoints executable + if isunix command = '!./sift '; -else + else command = '!siftWin32 '; + end + command = [command ' tmp.key']; + eval(command); +else + tmp = octave_config_info('canonical_host_type'); + if index (tmp,'linux'), islinux = 1; + elseif index (tmp,'win'), islinux = 0; + else error ('sift: Can''t run on system %s',tmp); end + if islinux + command = 'sift'; + else + command = 'siftWin32'; + end + command = find_in_path (command); + command = [command, ' tmp.key']; + system(command); end -command = [command ' tmp.key']; -eval(command); % Open tmp.key and check its header g = fopen('tmp.key', 'r'); diff -u -N siftDemoV4/TransformLineCoords.m siftDemoV4-mine/TransformLineCoords.m --- siftDemoV4/TransformLineCoords.m 1969-12-31 16:00:00.000000000 -0800 +++ siftDemoV4-mine/TransformLineCoords.m 2007-01-15 14:24:01.000000000 -0800 @@ -0,0 +1,35 @@ +% coords = TransformLine(imsize, keypoint, x1, y1, x2, y2) +% +% Draw the given line in the image, but first translate, rotate, and +% scale according to the keypoint parameters. +% +% Parameters: +% Arrays: +% imsize = [rows columns] of image +% keypoint = [subpixel_row subpixel_column scale orientation] +% +% Scalars: +% x1, y1; begining of vector +% x2, y2; ending of vector +% +% This function is called only by showkeys.m + +function coords = TransformLineCoords(imsize, keypoint, x1, y1, x2, y2) + +% The scaling of the unit length arrow is set to approximately the radius +% of the region used to compute the keypoint descriptor. +len = 6 * keypoint(3); + +% Rotate the keypoints by 'ori' = keypoint(4) +s = sin(keypoint(4)); +c = cos(keypoint(4)); + +% Apply transform +r1 = keypoint(1) - len * (c * y1 + s * x1); +c1 = keypoint(2) + len * (- s * y1 + c * x1); +r2 = keypoint(1) - len * (c * y2 + s * x2); +c2 = keypoint(2) + len * (- s * y2 + c * x2); + +%% line([c1 c2], [r1 r2], 'Color', 'c'); +coords = [r1 c1 r2 c2]; +endfunction