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 <etienne@laposte.net>, 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.pgm >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.pgm >tmp.key'];
+  system(command);
 end
-command = [command ' <tmp.pgm >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
