1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
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  
50  
51  
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 
109 
110 
111 
112 
113 
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 }