001/*******************************************************************************
002 * This software is provided as a supplement to the authors' textbooks on digital
003 *  image processing published by Springer-Verlag in various languages and editions.
004 * Permission to use and distribute this software is granted under the BSD 2-Clause 
005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 
006 * Copyright (c) 2006-2016 Wilhelm Burger, Mark J. Burge. All rights reserved. 
007 * Visit http://imagingbook.com for additional details.
008 *******************************************************************************/
009
010package imagingbook.pub.sift.util;
011
012import ij.IJ;
013
014import java.io.File;
015import java.io.FileNotFoundException;
016import java.io.FileReader;
017import java.util.ArrayList;
018import java.util.List;
019import java.util.Locale;
020import java.util.Scanner;
021
022public class SiftKeyfileReaderVLFEAT {
023        
024        private int descriptorLength = 128;
025        
026        public List<SiftKeypoint> readKeypointFile(String filename) {
027                List<SiftKeypoint> keypoints = new ArrayList<SiftKeypoint>();
028                File keyfile = new File(filename);
029
030                Scanner sc = null;
031                try {
032                        FileReader fr = new FileReader(keyfile);
033                        sc = new Scanner(fr);
034                } catch (FileNotFoundException e) {
035                        return null;
036                }
037
038                sc.useLocale(Locale.US);
039
040                try {
041//                      int nKeypoints = sc.nextInt();
042//                      int descriptorLength = sc.nextInt();
043
044//                      IJ.log("keypoints: " + nKeypoints);
045//                      IJ.log("descriptorLength: " + descriptorLength);
046
047                        while(sc.hasNext()) {
048                                // read one keypoint:
049                                double xpos = sc.nextDouble(); //NOTE: x/y not sapped
050                                double ypos = sc.nextDouble();
051                                double scale = sc.nextDouble(); //NOTE: orientation OK
052                                double orientation = sc.nextDouble();
053                                int[] descriptor = new int[descriptorLength];
054                                for (int i=0; i<descriptorLength; i++) {
055                                        descriptor[i] = sc.nextInt();
056                                }
057                                keypoints.add(new SiftKeypoint(xpos, ypos, scale, orientation, descriptor));
058                        }
059                }
060                catch (Exception e) {
061                        IJ.log("Exception: " + e);
062                }
063                
064                sc.close();
065                return keypoints;
066        }
067}
068
069
070/* Lowe's file format for SIFT keys:
071The file format starts with 2 integers giving the total number of
072keypoints and the length of the descriptor vector for each keypoint
073(128). Then the location of each keypoint in the image is specified by
0744 floating point numbers giving subpixel row and column location,
075scale, and orientation (in radians from -PI to PI).  Obviously, these
076numbers are not invariant to viewpoint, but can be used in later
077stages of processing to check for geometric consistency among matches.
078Finally, the invariant descriptor vector for the keypoint is given as
079a list of 128 integers in range [0,255].  Keypoints from a new image
080can be matched to those from previous images by simply looking for the
081descriptor vector with closest Euclidean distance among all vectors
082from previous images.
083*/
084