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 SiftKeyfileReaderLowe { 023 024 public List<SiftKeypoint> readKeypointFile(String filename) { 025 List<SiftKeypoint> keypoints = new ArrayList<SiftKeypoint>(); 026 File keyfile = new File(filename); 027 028 Scanner sc = null; 029 try { 030 FileReader fr = new FileReader(keyfile); 031 sc = new Scanner(fr); 032 } catch (FileNotFoundException e) { 033 return null; 034 } 035 036 sc.useLocale(Locale.US); 037 038 try { 039 int nKeypoints = sc.nextInt(); 040 int descriptorLength = sc.nextInt(); 041 042 IJ.log("keypoints: " + nKeypoints); 043 IJ.log("descriptorLength: " + descriptorLength); 044 045 while(sc.hasNext()) { 046 // read one keypoint: 047 double ypos = sc.nextDouble(); //NOTE: x/y swapped! 048 double xpos = sc.nextDouble(); 049 double scale = sc.nextDouble(); 050 double orientation = -sc.nextDouble(); //NOTE: angle in opposite direction! 051 int[] descriptor = new int[descriptorLength]; 052 for (int i=0; i<descriptorLength; i++) { 053 descriptor[i] = sc.nextInt(); 054 } 055 keypoints.add(new SiftKeypoint(xpos, ypos, scale, orientation, descriptor)); 056 } 057 } 058 catch (Exception e) { 059 IJ.log("Exception: " + e); 060 } 061 062 sc.close(); 063 return keypoints; 064 } 065} 066 067 068/* Lowe's file format for SIFT keys: 069The file format starts with 2 integers giving the total number of 070keypoints and the length of the descriptor vector for each keypoint 071(128). Then the location of each keypoint in the image is specified by 0724 floating point numbers giving subpixel row and column location, 073scale, and orientation (in radians from -PI to PI). Obviously, these 074numbers are not invariant to viewpoint, but can be used in later 075stages of processing to check for geometric consistency among matches. 076Finally, the invariant descriptor vector for the keypoint is given as 077a list of 128 integers in range [0,255]. Keypoints from a new image 078can be matched to those from previous images by simply looking for the 079descriptor vector with closest Euclidean distance among all vectors 080from previous images. 081*/ 082