001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.tools.clusterquantiser; 031 032import java.io.File; 033import java.io.IOException; 034import java.io.InputStream; 035import java.util.Arrays; 036import java.util.Scanner; 037 038/** 039 * Utility functions for reading lowe-style keypoint files and the (similar) files produced by the MSER and oxford tools 040 * 041 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 042 * @author Sina Samangooei (ss@ecs.soton.ac.uk) 043 */ 044public class AsciiInterestPoint { 045 /** 046 * Number of location elements for ellipse files 047 */ 048 public static final int NUM_ELLIPSE_LOC_FEATS = 5; 049 /** 050 * Number of location elements for circle files 051 */ 052 public static final int NUM_CIRCLE_LOC_FEATS = 4; 053 /** 054 * Number of location features for ASIFT files 055 */ 056 public static final int NUM_ASIFT_LOC_FEATS = 7; 057 058 /** 059 * Read the header 060 * 061 * @param file 062 * @param reverse 063 * @return the header info 064 * @throws IOException 065 */ 066 public static Header readHeader(File file, boolean reverse) throws IOException { 067 Scanner scanner = null; 068 try { 069 scanner = new Scanner(file); 070 return readHeader(scanner, reverse); 071 } finally { 072 scanner.close(); 073 } 074 } 075 076 /** 077 * Read the data 078 * 079 * @param file 080 * @param reverse 081 * @param nLocationFeatures 082 * @return the data 083 * @throws IOException 084 */ 085 public static byte [][] readData(File file, boolean reverse, int nLocationFeatures) throws IOException { 086 Scanner scanner = null; 087 088 try { 089 scanner = new Scanner(file); 090 Header header = readHeader(scanner, reverse); 091 return readData(scanner, header, nLocationFeatures); 092 } finally { 093 scanner.close(); 094 } 095 } 096 097 /** 098 * Read the data 099 * @param file 100 * @param indices 101 * @param reverse 102 * @param nLocationFeatures 103 * @return the data 104 * @throws IOException 105 */ 106 public static byte [][] readData(File file, int [] indices, boolean reverse, int nLocationFeatures) throws IOException { 107 Scanner scanner = null; 108 109 try { 110 byte [][] data = new byte[indices.length][]; 111 112 scanner = new Scanner(file); 113 114 Arrays.sort(indices); 115 116 Header header = readHeader(scanner, reverse); 117 118 if (indices[indices.length-1] >= header.nfeatures) 119 throw new IllegalArgumentException("Invalid index"); 120 121 int currentIdx = 0; 122 for (int i=0; i<=indices[indices.length-1]; i++) { 123 if (i == indices[currentIdx]) { 124 data[currentIdx] = readLine(scanner, header, nLocationFeatures); 125 currentIdx++; 126 } else { 127 skipLine(scanner, header, nLocationFeatures); 128 } 129 } 130 return data; 131 } finally { 132 scanner.close(); 133 } 134 } 135 136 /** 137 * Read the file 138 * @param source 139 * @param reverse 140 * @param nLocationFeatures 141 * @return the data 142 * @throws IOException 143 */ 144 public static FeatureFile read(InputStream source, boolean reverse,int nLocationFeatures) throws IOException { 145 146 Scanner scanner = null; 147 try { 148 scanner = new Scanner(source); 149 Header header = readHeader(scanner, reverse); 150 151 152 153 byte[][] data = new byte[header.nfeatures][header.ndims]; 154 String[] locations = new String[header.nfeatures]; 155 156 for (int i=0; i<header.nfeatures; i++) { 157 String location = ""; 158 for (int j=0; j<nLocationFeatures; j++) 159 location += scanner.nextFloat() + " "; 160 locations[i] = location; 161 162 for (int j=0; j<header.ndims; j++) 163 data[i][j] = (byte)(scanner.nextInt()-128); 164 } 165 FeatureFile ff = new MemoryFeatureFile(data,locations); 166 return ff; 167 } finally { 168 scanner.close(); 169 } 170 } 171 172 /** 173 * Read the file 174 * @param file 175 * @param reverse 176 * @param nLocationFeatures 177 * @return the data 178 * @throws IOException 179 */ 180 public static FeatureFile read(File file, boolean reverse, int nLocationFeatures) throws IOException { 181 Scanner scanner = null; 182 183 try { 184 scanner = new Scanner(file); 185 Header header = readHeader(scanner, reverse); 186 187 188 byte[][] data = new byte[header.nfeatures][header.ndims]; 189 String[] locations = new String[header.nfeatures]; 190 191 for (int i=0; i<header.nfeatures; i++) { 192 String location = ""; 193 for (int j=0; j<nLocationFeatures; j++) 194 location += scanner.nextFloat() + " "; 195 locations[i] = location; 196 197 for (int j=0; j<header.ndims; j++) 198 data[i][j] = (byte) (scanner.nextInt()-128); 199 } 200 FeatureFile ff = new MemoryFeatureFile(data,locations); 201 return ff; 202 } finally { 203 scanner.close(); 204 } 205 } 206 207 protected static Header readHeader(Scanner scanner, boolean reverse) throws IOException { 208 Header header = new Header(); 209 210 if (reverse) { 211 header.ndims = scanner.nextInt(); 212 header.nfeatures = scanner.nextInt(); 213 } else { 214 header.nfeatures = scanner.nextInt(); 215 header.ndims = scanner.nextInt(); 216 } 217 218 return header; 219 } 220 221 protected static byte [][] readData(Scanner scanner, Header header, int nLocationFeatures) { 222 byte [][] data = new byte[header.nfeatures][header.ndims]; 223 224 for (int i=0; i<header.nfeatures; i++) { 225 data[i] = readLine(scanner, header, nLocationFeatures); 226 } 227 228 return data; 229 } 230 231 protected static byte [] readLine(Scanner scanner, Header header, int nLocationFeatures) { 232 byte [] data = new byte[header.ndims]; 233 234 //skip the location data 235 for (int j=0; j<nLocationFeatures; j++) 236 scanner.nextFloat(); 237 238 for (int j=0; j<header.ndims; j++) 239 data[j] = (byte) (scanner.nextInt() - 128); 240 241 return data; 242 } 243 244 protected static void skipLine(Scanner scanner, Header header, int nLocationFeatures) { 245 //skip the location data 246 for (int j=0; j<nLocationFeatures; j++) 247 scanner.next(); 248// scanner.nextFloat(); 249 250 for (int j=0; j<header.ndims; j++) 251 scanner.next(); 252// scanner.nextInt(); 253 } 254 255 256}