public VLADIndexer(VLADIndexerData indexerData, IncrementalMetaIndex<DATA, METADATA> metaStore) { this.indexerData = indexerData; this.nn = indexerData.createIncrementalIndex(); this.metaStore = metaStore; }
/** * Extract the PCA-projected VLAD feature from the given image. The local * features will be post-processed before being aggregated using * {@link VLAD} and projected by the PCA basis. * * @param image * the image to extract from * @return the pca-vlad aggregated representation of the image */ public float[] extractPcaVlad(MBFImage image) { return extractPcaVlad(extractor.extractFeature(image)); }
@Override protected void setup(Context context) throws IOException, InterruptedException { indexer = VLADIndexerData.read(new File("./" + context.getConfiguration().get(VLAD_INDEXER_DATA_PATH_KEY))); }
final VLAD<float[]> vlad = buildVLAD(); final List<MultidimensionalFloatFV> vlads = computeVLADs(vlad); final Matrix whitening = createRandomWhitening(numPcaDims); pca.getBasis().setMatrix(0, numPcaDims - 1, 0, numPcaDims - 1, pca.getBasis().times(whitening)); final float[][] pcaVlads = projectFeatures(pca, vlads); final FloatProductQuantiser pq = FloatProductQuantiserUtilities.train(pcaVlads, numPqAssigners, numPqIterations); return new VLADIndexerData(vlad, pca, pq, extractor, postProcess);
/** * Build a {@link VLAD} using the information provided at construction time. * The following steps are taken: * <p> * <ol> * <li>A sample of the features is loaded * <li>The sample is clustered using k-means * </ol> * * @return the {@link VLAD} */ public VLAD<float[]> buildVLAD() { // Load the data and normalise System.out.println("Loading Data from " + localFeatures.size() + " files"); final List<FloatLocalFeatureAdaptor<?>> samples = loadSample(); // cluster System.out.println("Clustering " + samples.size() + " Data Points"); final FloatCentroidsResult centroids = cluster(samples); // build vlads System.out.println("Building VLADs"); return new VLAD<float[]>(new ExactFloatAssigner(centroids), centroids, normalise); }
/** * Extract the product-quantisedPCA-projected VLAD feature from the given * image. The local features will be post-processed before being aggregated * using {@link VLAD} and projected by the PCA basis. * * @param image * the image to extract from * @return the product-quantised pca-vlad aggregated representation of the * image */ public byte[] extractPQPcaVlad(MBFImage image) { return extractPQPcaVlad(extractor.extractFeature(image)); }
@Override public void indexImage(DATA image) { final int id = indexerData.index(image.getImage(), nn); metaStore.put(id, image); }
/** * Index the given image into the given nearest neighbours object by * extracting the PCA-VLAD representation and then product-quantising. * * @param image * the image to index * @param nn * the nearest neighbours object * @return the index at which the features were added in the nearest * neighbours object */ public int index(MBFImage image, IncrementalFloatADCNearestNeighbours nn) { return nn.add(extractPcaVlad(image)); }
@Override protected void setup(Context context) throws IOException, InterruptedException { indexer = VLADIndexerData.read(new File("vlad-data.bin")); mos = new MultipleOutputs<Text, BytesWritable>(context); }
/** * Index the given features into the given nearest neighbours object by * converting them to the PCA-VLAD representation and then * product-quantising. * * @param features * the features to index * @param nn * the nearest neighbours object * @return the index at which the features were added in the nearest * neighbours object */ public int index(List<? extends LocalFeature<?, ?>> features, IncrementalFloatADCNearestNeighbours nn) { return nn.add(extractPcaVlad(features)); }
public static void index() throws IOException { final VLADIndexerData indexer = VLADIndexerData.read(new File("/Users/jsh2/vlad-indexer-ukbench-2x-nohell.dat")); final List<IntObjectPair<float[]>> index = new ArrayList<IntObjectPair<float[]>>(); final List<IntObjectPair<float[]>> syncList = Collections.synchronizedList(index); Parallel.forEach(Arrays.asList(new File("/Users/jsh2/Data/ukbench/sift/").listFiles()), new Operation<File>() { @Override public void perform(File f) { try { System.out.println(f); final int id = Integer.parseInt(f.getName().replace("ukbench", "").replace(".jpg", "")); final MemoryLocalFeatureList<Keypoint> keys = MemoryLocalFeatureList.read(f, Keypoint.class); syncList.add(new IntObjectPair<float[]>(id, indexer.extractPcaVlad(keys))); } catch (final Exception e) { e.printStackTrace(); } } }); IOUtils.writeToFile(index, new File("/Users/jsh2/Desktop/ukb-nohell.idx")); }
@Override public void perform(Integer i) { try { System.out.println("Loading " + i); final File file = new File(String.format("/Users/jsh2/Data/ukbench/sift/ukbench%05d.jpg", i)); final List<Keypoint> keys = MemoryLocalFeatureList.read(file, Keypoint.class); vlads[i] = indexer.extractPcaVlad(keys); } catch (final Exception e) { e.printStackTrace(); } } });
public static void index() throws IOException { final VLADIndexerData indexer = VLADIndexerData.read(new File("/Users/jsh2/vlad-indexer-ukbench-2x-nohell.dat")); final List<IntObjectPair<float[]>> index = new ArrayList<IntObjectPair<float[]>>(); final List<IntObjectPair<float[]>> syncList = Collections.synchronizedList(index); Parallel.forEach(Arrays.asList(new File("/Users/jsh2/Data/ukbench/sift/").listFiles()), new Operation<File>() { @Override public void perform(File f) { try { System.out.println(f); final int id = Integer.parseInt(f.getName().replace("ukbench", "").replace(".jpg", "")); final MemoryLocalFeatureList<Keypoint> keys = MemoryLocalFeatureList.read(f, Keypoint.class); syncList.add(new IntObjectPair<float[]>(id, indexer.extractPcaVlad(keys))); } catch (final Exception e) { e.printStackTrace(); } } }); IOUtils.writeToFile(index, new File("/Users/jsh2/Desktop/ukb-nohell.idx")); }
@Override public void perform(Integer i) { try { System.out.println("Loading " + i); final File file = new File(String.format("/Users/jsh2/Data/ukbench/sift/ukbench%05d.jpg", i)); final List<Keypoint> keys = MemoryLocalFeatureList.read(file, Keypoint.class); vlads[i] = indexer.extractPcaVlad(keys); } catch (final Exception e) { e.printStackTrace(); } } });
final VLADIndexerData indexer = VLADIndexerData.read(new File("/Users/jsh2/vlad-indexer-ukbench-2x.dat"));
@Override public void perform(File f) { try { System.out.println(f); final int id = Integer.parseInt(f.getName().replace("ukbench", "").replace(".jpg", "")); final MemoryLocalFeatureList<Keypoint> keys = MemoryLocalFeatureList.read(f, Keypoint.class); syncList.add(new IntObjectPair<float[]>(id, indexer.extractPcaVlad(keys))); } catch (final Exception e) { e.printStackTrace(); } } });
final VLADIndexerData indexer = VLADIndexerData.read(new File("/Users/jsh2/vlad-indexer-ukbench-2x.dat"));
@Override public void perform(File f) { try { System.out.println(f); final int id = Integer.parseInt(f.getName().replace("ukbench", "").replace(".jpg", "")); final MemoryLocalFeatureList<Keypoint> keys = MemoryLocalFeatureList.read(f, Keypoint.class); syncList.add(new IntObjectPair<float[]>(id, indexer.extractPcaVlad(keys))); } catch (final Exception e) { e.printStackTrace(); } } });
@Override public List<ImageSearchResult<METADATA>> search(ImageProvider<MBFImage> query) { final List<IntFloatPair> res = nn.searchKNN(indexerData.extractPcaVlad(query.getImage()), DEFAULT_MAX_RESULTS); final List<ImageSearchResult<METADATA>> results = new ArrayList<ImageSearchResult<METADATA>>(res.size()); for (int i = 0; i < res.size(); i++) { final IntFloatPair r = res.get(i); results.add(new ImageSearchResult<METADATA>(metaStore.get(r.first), r.second)); } return results; } }
@Override protected void map(Text key, BytesWritable value, Context context) throws IOException, InterruptedException { final List<Keypoint> keys = MemoryLocalFeatureList.read(new ByteArrayInputStream(value.getBytes()), Keypoint.class); final float[] vladData = indexer.extractPcaVlad(keys); if (vladData == null) { context.getCounter(COUNTERS.NULL).increment(1L); return; } final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final DataOutputStream dos = new DataOutputStream(baos); for (final float f : vladData) dos.writeFloat(f); context.write(key, new BytesWritable(baos.toByteArray())); context.getCounter(COUNTERS.EMIT).increment(1L); } }