|
| 1 | +% [image, descriptors, locs] = sift(imageFile) |
| 2 | +% |
| 3 | +% This function reads an image and returns its SIFT keypoints. |
| 4 | +% Input parameters: |
| 5 | +% imageFile: the file name for the image. |
| 6 | +% |
| 7 | +% Returned: |
| 8 | +% image: the image array in double format |
| 9 | +% descriptors: a K-by-128 matrix, where each row gives an invariant |
| 10 | +% descriptor for one of the K keypoints. The descriptor is a vector |
| 11 | +% of 128 values normalized to unit length. |
| 12 | +% locs: K-by-4 matrix, in which each row has the 4 values for a |
| 13 | +% keypoint location (row, column, scale, orientation). The |
| 14 | +% orientation is in the range [-PI, PI] radians. |
| 15 | +% |
| 16 | +% Credits: Thanks for initial version of this program to D. Alvaro and |
| 17 | +% J.J. Guerrero, Universidad de Zaragoza (modified by D. Lowe) |
| 18 | + |
| 19 | +function [image, descriptors, locs] = sift(imageFile) |
| 20 | + |
| 21 | +% Load image |
| 22 | + |
| 23 | +image = imread(imageFile); |
| 24 | + |
| 25 | +% If you have the Image Processing Toolbox, you can uncomment the following |
| 26 | +% lines to allow input of color images, which will be converted to grayscale. |
| 27 | +if ndims(image) == 3 |
| 28 | + image = rgb2gray(image); |
| 29 | +end |
| 30 | + |
| 31 | +[rows, cols] = size(image); |
| 32 | + |
| 33 | +% Convert into PGM imagefile, readable by "keypoints" executable |
| 34 | +f = fopen('tmp.pgm', 'w'); |
| 35 | +if f == -1 |
| 36 | + error('Could not create file tmp.pgm.'); |
| 37 | +end |
| 38 | +fprintf(f, 'P5\n%d\n%d\n255\n', cols, rows); |
| 39 | +fwrite(f, image, 'uint8'); |
| 40 | +fclose(f); |
| 41 | + |
| 42 | +% Call keypoints executable |
| 43 | +if isunix |
| 44 | + command = '!./sift '; |
| 45 | +else |
| 46 | + command = '!siftWin32.exe '; |
| 47 | +end |
| 48 | +command = [command ' <tmp.pgm >tmp.key']; |
| 49 | +eval(command); |
| 50 | + |
| 51 | +% Open tmp.key and check its header |
| 52 | +g = fopen('tmp.key', 'r'); |
| 53 | +if g == -1 |
| 54 | + error('Could not open file tmp.key.'); |
| 55 | +end |
| 56 | +[header, count] = fscanf(g, '%d %d', [1 2]); |
| 57 | +if count ~= 2 |
| 58 | + error('Invalid keypoint file beginning.'); |
| 59 | +end |
| 60 | +num = header(1); |
| 61 | +len = header(2); |
| 62 | +if len ~= 128 |
| 63 | + error('Keypoint descriptor length invalid (should be 128).'); |
| 64 | +end |
| 65 | + |
| 66 | +% Creates the two output matrices (use known size for efficiency) |
| 67 | +locs = double(zeros(num, 4)); |
| 68 | +descriptors = double(zeros(num, 128)); |
| 69 | + |
| 70 | +% Parse tmp.key |
| 71 | +for i = 1:num |
| 72 | + [vector, count] = fscanf(g, '%f %f %f %f', [1 4]); %row col scale ori |
| 73 | + if count ~= 4 |
| 74 | + error('Invalid keypoint file format'); |
| 75 | + end |
| 76 | + locs(i, :) = vector(1, :); |
| 77 | + |
| 78 | + [descrip, count] = fscanf(g, '%d', [1 len]); |
| 79 | + if (count ~= 128) |
| 80 | + error('Invalid keypoint file value.'); |
| 81 | + end |
| 82 | + % Normalize each input vector to unit length |
| 83 | + descrip = descrip / sqrt(sum(descrip.^2)); |
| 84 | + descriptors(i, :) = descrip(1, :); |
| 85 | +end |
| 86 | +fclose(g); |
| 87 | + |
| 88 | + |
0 commit comments