package gr.iti.mklab.visual.examples;
import gr.iti.mklab.visual.datastructures.AbstractSearchStructure;
import gr.iti.mklab.visual.datastructures.Linear;
import gr.iti.mklab.visual.vectorization.ImageVectorizationResult;
import gr.iti.mklab.visual.vectorization.ImageVectorizer;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Date;
/**
* This class demonstrates multi-threaded VLAD vectorization and @{link Linear} indexing of the images in a
* given folder.
*
* @author Eleftherios Spyromitros-Xioufis
*
*/
public class FolderIndexingMT {
/** A maximum size for the index */
public static final int maxIndexSize = 10000000;
/**
* @param args
* [0] directory that contains the image files
* @param args
* [1] directory where the index will be created
* @param args
* [2] a comma separated list with full paths to the codebook files (also works for 1 codebook)
* @param args
* [3] a comma separated list with the sizes of the codebooks
* @param args
* [4] path to the file containing the pca projection matrix (an empty String can be given if
* no projection is needed)
* @param args
* [5] projection length (if projection length = initial length, no projection will be
* performed)
* @param args
* [6] images will be scaled at this maximum number of pixels before vectorization
* @param args
* [7] number of processor threads to be used for vectorization (compute-intensive task)
* @param args
* [8] type of features to be extracted (surf/sift/rootsift/csurf)
* @param args
* [9] whether whitening should be applied along with PCA projection (true/false)
*/
public static void main(String[] args) throws Exception {
String imagesFolder = args[0];
String indexFolder = args[1];
String[] codebookFiles = args[2].split(",");
String[] numCentroidsString = args[3].split(",");
int[] numCentroids = new int[numCentroidsString.length];
for (int i = 0; i < numCentroidsString.length; i++) {
numCentroids[i] = Integer.parseInt(numCentroidsString[i]);
}
String pcaFile = args[4];
int projectionLength = Integer.parseInt(args[5]);
int maxImageSizeInPixels = Integer.parseInt(args[6]);
// suggestion for compute-intensive tasks by
// http://codeidol.com/java/java-concurrency/Applying-Thread-Pools/Sizing-Thread-Pools/
// int numVectorizationThreads = Runtime.getRuntime().availableProcessors() + 1;
int numVectorizationThreads = Integer.parseInt(args[7]);
String featureType = args[8];
boolean whitening = Boolean.parseBoolean(args[9]);
// Initialize the vectorizer and the indexer
ImageVectorizer vectorizer = new ImageVectorizer(featureType, codebookFiles, numCentroids,
projectionLength, pcaFile, whitening, numVectorizationThreads);
vectorizer.setMaxImageSizeInPixels(maxImageSizeInPixels);
String BDBEnvHome = indexFolder + "BDB_" + maxImageSizeInPixels + "_" + featureType + "_"
+ vectorizer.getInitialVectorLength();
if (projectionLength < vectorizer.getInitialVectorLength()) {
BDBEnvHome += "to" + projectionLength;
}
if (whitening) {
BDBEnvHome += "w";
}
AbstractSearchStructure index = new Linear(projectionLength, maxIndexSize, false, BDBEnvHome, false,
true, 0);
// load the images
File dir = new File(imagesFolder);
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
if (name.toLowerCase().endsWith(".jpeg") || name.toLowerCase().endsWith(".jpg")
|| name.toLowerCase().endsWith(".png") || name.toLowerCase().endsWith(".gif"))
return true;
else
return false;
}
};
String[] files = dir.list(filter);
// scheduling!!!
System.out.println("Indexing started!");
long start = System.currentTimeMillis();
int submittedVectorizationsCounter = 0;
int completedCounter = 0;
int failedCounter = 0;
while (true) {
// if we can submit more tasks to the vectorizer then do it
if (submittedVectorizationsCounter < files.length && vectorizer.canAcceptMoreTasks()) {
// avoid extraction if an image is already indexed
String imageName = files[submittedVectorizationsCounter];
if (index.isIndexed(imageName)) { // this image has been already indexed
System.out.println("image:" + imageName + " already indexed");
completedCounter++;
} else {
vectorizer.submitImageVectorizationTask(imagesFolder, imageName);
}
submittedVectorizationsCounter++;
System.out.println("Submitted vectorization tasks: " + submittedVectorizationsCounter
+ " image:" + imageName);
}
// try to get an image vectorization result and to index the vector
ImageVectorizationResult imvr = null;
// try {
imvr = vectorizer.getImageVectorizationResult();
// } catch (Exception e) {
// // this code will probably be never executed because getImageVectorizationResult() does not
// // throw Exceptions anymore!
// failedCounter++;
// e.printStackTrace();
// System.out.println(e.toString());
// System.out.println("" + new Date() + ": " + failedCounter + " vectors failed");
// System.out.println("Image: " + imvr.getImageName());
// }
if (imvr != null) {
String name = imvr.getImageName();
name = name.split("\\.")[0] + ".jpg";
if (imvr.getExceptionMessage() == null) {
// vectorization completed with success!s
double[] vector = imvr.getImageVector();
if (index.indexVector(name, vector)) {
completedCounter++;
} else {
failedCounter++;
}
System.out.println("" + new Date() + ": " + completedCounter + " vectors indexed");
} else {
// something bad happened during vectorization
System.out.println("Something bad happened when vectorizing image: " + name);
System.out.println("Exception message: " + imvr.getExceptionMessage());
failedCounter++;
System.out.println("" + new Date() + ": " + failedCounter + " vectors failed");
}
}
// check loop termination condition
if ((completedCounter + failedCounter == files.length)) {
System.out.println("Shutdown sequence has started!");
vectorizer.shutDown();
index.close();
break;
}
}
long end = System.currentTimeMillis();
System.out.println("Total time: " + (end - start) + " ms");
System.out.println(completedCounter + " indexing tasks completed!");
}
}