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.cbir;
031
032import java.io.File;
033import java.io.IOException;
034import java.util.ArrayList;
035import java.util.List;
036import java.util.regex.Pattern;
037
038import org.kohsuke.args4j.CmdLineException;
039import org.kohsuke.args4j.CmdLineParser;
040import org.kohsuke.args4j.Option;
041import org.openimaj.feature.local.LocalFeature;
042import org.openimaj.feature.local.LocalFeatureExtractor;
043import org.openimaj.image.MBFImage;
044import org.openimaj.image.indexing.vlad.VLADIndexerData;
045import org.openimaj.image.indexing.vlad.VLADIndexerDataBuilder;
046import org.openimaj.image.indexing.vlad.VLADIndexerDataBuilder.StandardPostProcesses;
047import org.openimaj.io.IOUtils;
048
049/**
050 * Tool to build a {@link VLADIndexerData} which can be used to build efficient
051 * Product-quantised PCA-VLAD indexes.
052 * 
053 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
054 * 
055 */
056public class VLADIndexerBuilder extends VLADBuilder {
057        @Option(
058                        name = "--num-pca-dims",
059                        aliases = "-npca",
060                        usage = "the number of dimensions to project down to using PCA (~128 for normal SIFT)")
061        protected int numPcaDims = 128;
062
063        @Option(
064                        name = "--pca-sample-proportion",
065                        usage = "the percentage of images to use for computing the PCA basis")
066        protected float pcaSampleProp = 1.0f;
067
068        @Option(
069                        name = "--num-pq-iterations",
070                        aliases = "-npqi",
071                        usage = "the number of iterations for clustering the product quantisers (~100)")
072        protected int numPqIterations = 100;
073
074        @Option(name = "--num-pq-assigners", aliases = "-na", usage = "the number of product quantiser assigners (~16)")
075        protected int numPqAssigners = 16;
076
077        @Option(
078                        name = "--post-process",
079                        aliases = "-pp",
080                        usage = "the post-processing to apply to the raw features before input to VLAD")
081        protected StandardPostProcesses postProcess = StandardPostProcesses.NONE;
082
083        /**
084         * Main method
085         * 
086         * @param args
087         *            arguments
088         * @throws IOException
089         *             if an error occurs during reading or writing
090         */
091        public static void main(String[] args) throws IOException {
092                final VLADIndexerBuilder builder = new VLADIndexerBuilder();
093                final CmdLineParser parser = new CmdLineParser(builder);
094
095                try {
096                        parser.parseArgument(args);
097                } catch (final CmdLineException e) {
098                        System.err.println(e.getMessage());
099                        System.err.println("Usage: java -jar CBIRTool.jar VLADBuilder [options]");
100                        parser.printUsage(System.err);
101                        return;
102                }
103
104                final LocalFeatureExtractor<LocalFeature<?, ?>, MBFImage> extractor = IOUtils.readFromFile(builder.extractorFile);
105
106                final List<File> localFeatures = new ArrayList<File>();
107                getInputFiles(localFeatures, builder.localFeaturesDir,
108                                builder.regex == null ? null : Pattern.compile(builder.regex));
109
110                final VLADIndexerDataBuilder vladBuilder = new VLADIndexerDataBuilder(extractor, localFeatures,
111                                builder.normalise, builder.numVladCentroids, builder.numIterations, builder.numPcaDims,
112                                builder.numPqIterations, builder.numPqAssigners, builder.sampleProp, builder.pcaSampleProp,
113                                builder.postProcess);
114
115                final VLADIndexerData vlad = vladBuilder.buildIndexerData();
116
117                IOUtils.writeToFile(vlad, builder.output);
118        }
119}