Setup

Prepare your development environment in a few easy steps

Index

A short example that shows how to easily index a folder containing images

Search

An example that shows how to search for images similar to a given example in an existing index

 

 

Setting up the development environment

A test project is provided here. It uses a Maven structure and can easily be imported into the Eclipse IDE. Start by downloading the file and uncompressing it to a folder on your computer :

Step 1 - Decompress ZIP

Launch Eclipse and Import the Maven project into your Workspace (FileImportMavenExisting Maven Projects). Select the folder where you decompressed the ZIP archive, then follow the steps of the Import wizard.

Step 2 - Import Project

You should now see the project and its structure :

Step 3 - Inspect Structure

The current version of the test project contains the following elements :

  • src/test/java - Folder containing test classes
    • TestDescriptors.java - Test class that creates descriptors for an image example
    • TestExtractors.java - Test class that extracts local features from an image
    • TestIndexers.java - Test class that indexes a given folder of images
    • TestSeekers.java - Test class that performs a similarity search
  • data/vocabularies/ - Directory containing 2 sample vocabularies
  • pom.xml - Project description file with dependency declarations

Indexing a folder of images

The TestIndexers.java class shows a simple example of how to create a visual index from a given set of images contained in a folder. It currently contains 2 methods :

  • serialIndexer - Performs the indexing using the serial method
  • getImagePathsFromDirectory - Gets a list of file paths from a directory

This example will create an index using the "Lab Miniature" local feature extractor, the "Bag-of-Visual-Words" global representation and stores the result in CSV format inside a subfolder of the project's root.

Let's first take a look at fields of the class, which are the only part that requires some changes in order for the class to work "out-of-the-box" :

public static final String DIR_TO_INDEX = "/path/to/directory/";
public static final String INDEX_ID = "testIndex";

The main change that is required is the value of the DIR_TO_INDEX field, which should point to a local directory containing a series of image files.

Optionally, the INDEX_ID can also be changed if a different name for the output file is desired.

The index, as well as a configuration file containing the used parameters, will be stored in the root folder of the Eclipse project, in the data directory (in the indices and conf subdirectories, respectively).


Now let's look at the the serialIndexer method :

@Test
public void serialIndexer() throws IOException {
    // Directory containing images to index
    String directoryPath = DIR_TO_INDEX;

    // Name of the index file (will be saved in the project's "data"
    // directory)
    String indexID = INDEX_ID;

    // Initialize the indexing manager, used to configure the
    // index creation object
    IndexingManager im = new IndexingManager();

    // Initialize the directory where the images are stored
    File directory = new File(directoryPath);

    // Check that given directory exists
    if (directory.exists()) {

            // Get image paths from directory
            List<String> imagePaths = getImagePathsFromDirectory(directory);
...

The first object being created is the IndexingManager. ParaDISE uses several of these "Manager" classes. The manager helps in creating a complex object such as the indexer by providing as few parameters as possible, using sensible default values where none are provided.

The rest of the code snippet is related to getting the list of image paths from the directory.


The getImagePathsFromDirectory method doesn't really require any changes, as it is simply a helper method to get a list of absolute files paths from the image directory. It could be made a bit more complex, for example to support subdirectories.


Finally, let's take a look at the rest of the serialIndexer method, which showcases several key mechanisms of ParaDISE :

/* 
 * Define extractor parameters (local visual features)
 * 
 * This example uses LAB_MINIATURE, a bag-of-colors local feature extractor 
 * on a miniature image in the Lab color space.
 * For more detailed information, see {@link LabMiniature}
 * For a list available parameters, see {@link LabMiniatureParameters}
 */
AbstractParameters extractorParams = new Parameters();
extractorParams.setMethodID(Names.EXTRACTOR_METHOD_LAB_MINIATURE);
...

The following section of code deals with the configuration of the individual components of the Indexer (Extractor, Descriptor, Storer). All these components are defined using Parameters objects, which have two configurable elements:

  • methodID - Defines the general method the object uses (examples : which visual feature to use, which storage system, etc.)
  • paramMap - Key-Value pairs that define more fine-grained options related to the selected method (examples : various constants for visual features, connection details for a MySQL database server, etc.)

For a basic usage of the system, it is usually sufficient to specify the methodID (as in the example above) and let the manager select the correct parameters to use.

For an exhaustive list of parameter classes and the options that can be configured for each, consult this page in the javadoc

The last section of the code actually creates the Indexer object and launches the indexing process :

//Create indexer parameters based on the previously defined
//parameter maps
IndexerParameters params = new IndexerParameters();
params.set(Names.INDEXER_MAP_EXTRACTOR, extractorParams);
params.set(Names.INDEXER_MAP_DESCRIPTOR, descriptorParams);
params.set(Names.INDEXER_MAP_STORER, storerParams);
params.set(Names.INDEXER_MAP_GENERAL, generalParams);

try {
    // Select the indexer based on the given parameters
    im.selectIndexer(imagePaths, params);

    // Create index
    im.getIndexer().createIndex();

    // Declare object for index file
    File index = new File(Defaults.PARADISE_INDEX_PATH + INDEX_ID + ".csv");

    // JUnit assertion - Check if index file was created
    assertTrue(index.exists() && index.length() > 0);

    System.out.println("Index " + indexID + " created.");
} catch (Exception e) {
    e.printStackTrace();
    fail("Couldn't create index");
}

First, a special type of parameter class, IndexerParameters, is instantiated. This "composite" parameter object will contain multiple Parameters objects. Notice that the methodID is not specified, as the example uses the default Indexer method called SerialIndexer.

The various parameter objects configured previously are then added to the indexer parameters. The indexer is then actually created by the selectIndexer method, using the list of image paths and the indexer parameters as arguments.

Finally, the index is created by calling the createIndex on the indexer, accessed through the getIndexer method of the indexing manager.

The rest of the code snippet deals with error handling and assessing whether the creation of the index was successful