View Javadoc

1   /**
2    * Copyright (c) 2011, The University of Southampton and the individual contributors.
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without modification,
6    * are permitted provided that the following conditions are met:
7    *
8    *   * 	Redistributions of source code must retain the above copyright notice,
9    * 	this list of conditions and the following disclaimer.
10   *
11   *   *	Redistributions in binary form must reproduce the above copyright notice,
12   * 	this list of conditions and the following disclaimer in the documentation
13   * 	and/or other materials provided with the distribution.
14   *
15   *   *	Neither the name of the University of Southampton nor the names of its
16   * 	contributors may be used to endorse or promote products derived from this
17   * 	software without specific prior written permission.
18   *
19   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
23   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package org.openimaj.tools.cbir;
31  
32  import java.io.File;
33  import java.io.IOException;
34  import java.util.ArrayList;
35  import java.util.List;
36  import java.util.regex.Pattern;
37  
38  import org.kohsuke.args4j.CmdLineException;
39  import org.kohsuke.args4j.CmdLineParser;
40  import org.kohsuke.args4j.Option;
41  import org.openimaj.feature.local.LocalFeature;
42  import org.openimaj.feature.local.LocalFeatureExtractor;
43  import org.openimaj.image.MBFImage;
44  import org.openimaj.image.feature.local.aggregate.VLAD;
45  import org.openimaj.image.indexing.vlad.VLADIndexerDataBuilder;
46  import org.openimaj.io.IOUtils;
47  
48  /**
49   * Tool to build a {@link VLAD} object and serialise it to a file.
50   * 
51   * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
52   * 
53   */
54  public class VLADBuilder {
55  	@Option(
56  			name = "--extractor-file",
57  			aliases = "-ef",
58  			required = true,
59  			usage = "the local feature extractor used to generate the input features")
60  	protected File extractorFile;
61  
62  	@Option(
63  			name = "--features-dir",
64  			required = true,
65  			usage = "directory of the files containing the input local features (one per image)")
66  	protected File localFeaturesDir;
67  
68  	@Option(
69  			name = "--features-regex",
70  			required = false,
71  			usage = "regular expression to match the feature filenames against")
72  	protected String regex;
73  
74  	@Option(
75  			name = "--normalise",
76  			aliases = "-norm",
77  			required = false,
78  			usage = "should the resultant VLAD features be l2 normalised?")
79  	protected boolean normalise = false;
80  
81  	@Option(
82  			name = "--sample-proportion", required = false,
83  			usage = "the proportion of features to sample for the clustering the VLAD centroids")
84  	protected float sampleProp = 0.1f;
85  
86  	@Option(
87  			name = "--num-vlad-centroids",
88  			aliases = "-n",
89  			required = false,
90  			usage = "the number of centroids for VLAD (16~64). Defaults to 64.")
91  	protected int numVladCentroids = 64;
92  
93  	@Option(
94  			name = "--num-iterations",
95  			aliases = "-ni",
96  			required = false,
97  			usage = "the number of clustering iterations (~100). Defaults to 100.")
98  	protected int numIterations = 100;
99  
100 	@Option(
101 			name = "--output",
102 			aliases = "-o",
103 			required = true,
104 			usage = "the output file")
105 	protected File output;
106 
107 	/**
108 	 * Main method
109 	 * 
110 	 * @param args
111 	 *            arguments
112 	 * @throws IOException
113 	 *             if an error occurs during reading or writing
114 	 */
115 	public static void main(String[] args) throws IOException {
116 		final VLADBuilder builder = new VLADBuilder();
117 		final CmdLineParser parser = new CmdLineParser(builder);
118 
119 		try {
120 			parser.parseArgument(args);
121 		} catch (final CmdLineException e) {
122 			System.err.println(e.getMessage());
123 			System.err.println("Usage: java -jar CBIRTool.jar VLADBuilder [options]");
124 			parser.printUsage(System.err);
125 			return;
126 		}
127 
128 		final LocalFeatureExtractor<LocalFeature<?, ?>, MBFImage> extractor = IOUtils.readFromFile(builder.extractorFile);
129 
130 		final List<File> localFeatures = new ArrayList<File>();
131 		getInputFiles(localFeatures, builder.localFeaturesDir,
132 				builder.regex == null ? null : Pattern.compile(builder.regex));
133 
134 		final VLADIndexerDataBuilder vladBuilder = new VLADIndexerDataBuilder(extractor, localFeatures,
135 				builder.normalise,
136 				builder.numVladCentroids, builder.numIterations, 0, 0, 0, builder.sampleProp, 1, null);
137 
138 		final VLAD<float[]> vlad = vladBuilder.buildVLAD();
139 
140 		IOUtils.writeToFile(vlad, builder.output);
141 	}
142 
143 	protected static void getInputFiles(List<File> localFeatures, File dir, Pattern pattern) {
144 		for (final File f : dir.listFiles()) {
145 			if (f.isDirectory()) {
146 				getInputFiles(localFeatures, f, pattern);
147 			} else {
148 				if (pattern == null || pattern.matcher(f.getName()).matches()) {
149 					localFeatures.add(f);
150 				}
151 			}
152 		}
153 	}
154 }