/*
* This file is part of the LIRE project: http://lire-project.net
* LIRE is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* LIRE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LIRE; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* We kindly ask you to refer the any or one of the following publications in
* any publication mentioning or employing Lire:
*
* Lux Mathias, Savvas A. Chatzichristofis. Lire: Lucene Image Retrieval -
* An Extensible Java CBIR Library. In proceedings of the 16th ACM International
* Conference on Multimedia, pp. 1085-1088, Vancouver, Canada, 2008
* URL: http://doi.acm.org/10.1145/1459359.1459577
*
* Lux Mathias. Content Based Image Retrieval with LIRE. In proceedings of the
* 19th ACM International Conference on Multimedia, pp. 735-738, Scottsdale,
* Arizona, USA, 2011
* URL: http://dl.acm.org/citation.cfm?id=2072432
*
* Mathias Lux, Oge Marques. Visual Information Retrieval using Java and LIRE
* Morgan & Claypool, 2013
* URL: http://www.morganclaypool.com/doi/abs/10.2200/S00468ED1V01Y201301ICR025
*/
package net.semanticmetadata.lire.builders;
import junit.framework.TestCase;
import net.semanticmetadata.lire.aggregators.AbstractAggregator;
import net.semanticmetadata.lire.aggregators.BOVW;
import net.semanticmetadata.lire.classifiers.Cluster;
import net.semanticmetadata.lire.imageanalysis.features.GlobalFeature;
import net.semanticmetadata.lire.imageanalysis.features.LocalFeature;
import net.semanticmetadata.lire.imageanalysis.features.LocalFeatureExtractor;
import net.semanticmetadata.lire.imageanalysis.features.global.CEDD;
import net.semanticmetadata.lire.imageanalysis.features.local.opencvfeatures.CvSurfExtractor;
import net.semanticmetadata.lire.imageanalysis.features.local.simple.SimpleExtractor;
import net.semanticmetadata.lire.utils.FileUtils;
import org.apache.lucene.document.Document;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
* Created by Nektarios on 28/5/2015.
*
* @author Nektarios Anagnostopoulos, nek.anag@gmail.com
* (c) 2015 by Nektarios Anagnostopoulos
*/
public class TestBuilders extends TestCase {
Class<? extends GlobalFeature> globalFeatureClass = CEDD.class;
Class<? extends LocalFeatureExtractor> localFeatureClass = CvSurfExtractor.class;
SimpleExtractor.KeypointDetector keypointDetector = SimpleExtractor.KeypointDetector.CVSURF;
Class<? extends AbstractAggregator> aggregatorClass = BOVW.class;
String imagePath = "./src/test/resources/images/";
String codebookPath = "./src/test/resources/codebooks/";
public void testAllBuilders() throws IllegalAccessException, IOException, InstantiationException {
ArrayList<String> images = FileUtils.readFileLines(new File(imagePath), true);
System.out.println();
testGlobal(images);
testLocal(images);
testSimple(images);
}
public void testGlobal() throws IOException, IllegalAccessException, InstantiationException {
ArrayList<String> images = FileUtils.readFileLines(new File(imagePath), true);
testGlobal(images);
}
public void testGlobal(ArrayList<String> images) throws IOException, IllegalAccessException, InstantiationException {
GlobalFeature feature = globalFeatureClass.newInstance();
GlobalFeature cachedInstance1 = globalFeatureClass.newInstance();
GlobalFeature cachedInstance2 = globalFeatureClass.newInstance();
GlobalFeature cachedInstance3 = globalFeatureClass.newInstance();
GlobalFeature cachedInstance4 = globalFeatureClass.newInstance();
GlobalFeature cachedInstance5 = globalFeatureClass.newInstance();
String fieldName = feature.getFieldName();
//Ways to create GlobalDocumentBuilder
GlobalDocumentBuilder globalDocumentBuilder = new GlobalDocumentBuilder();
GlobalDocumentBuilder globalDocumentBuilder1 = new GlobalDocumentBuilder();
globalDocumentBuilder1.addExtractor(globalFeatureClass);
GlobalDocumentBuilder globalDocumentBuilder2 = new GlobalDocumentBuilder(globalFeatureClass);
GlobalDocumentBuilder globalDocumentBuilder3 = new GlobalDocumentBuilder(globalFeatureClass, false);
GlobalDocumentBuilder globalDocumentBuilder4 = new GlobalDocumentBuilder(true); //Using hashing
globalDocumentBuilder4.addExtractor(globalFeatureClass);
GlobalDocumentBuilder globalDocumentBuilder5 = new GlobalDocumentBuilder(globalFeatureClass, true); //Using hashing
BufferedImage image;
double[] featureVector, featureVector1, featureVector2, featureVector3, featureVector4, featureVector5;
Document document1, document2, document3, document4, document5;
double distance1, distance2, distance3, distance4;
boolean bool, bool1, bool2, bool3, bool4, bool5;
for (String path : images) {
image = ImageIO.read(new FileInputStream(path));
globalDocumentBuilder.extractGlobalFeature(image, feature);
featureVector = feature.getFeatureVector();
document1 = globalDocumentBuilder1.createDocument(image, imagePath);
cachedInstance1.setByteArrayRepresentation(document1.getField(fieldName).binaryValue().bytes, document1.getField(fieldName).binaryValue().offset, document1.getField(fieldName).binaryValue().length);
featureVector1 = cachedInstance1.getFeatureVector();
document2 = globalDocumentBuilder2.createDocument(image, imagePath);
cachedInstance2.setByteArrayRepresentation(document2.getField(fieldName).binaryValue().bytes, document2.getField(fieldName).binaryValue().offset, document2.getField(fieldName).binaryValue().length);
featureVector2 = cachedInstance2.getFeatureVector();
document3 = globalDocumentBuilder3.createDocument(image, imagePath);
cachedInstance3.setByteArrayRepresentation(document3.getField(fieldName).binaryValue().bytes, document3.getField(fieldName).binaryValue().offset, document3.getField(fieldName).binaryValue().length);
featureVector3 = cachedInstance3.getFeatureVector();
document4 = globalDocumentBuilder4.createDocument(image, imagePath);
cachedInstance4.setByteArrayRepresentation(document4.getField(fieldName).binaryValue().bytes, document4.getField(fieldName).binaryValue().offset, document4.getField(fieldName).binaryValue().length);
featureVector4 = cachedInstance4.getFeatureVector();
document5 = globalDocumentBuilder5.createDocument(image, imagePath);
cachedInstance5.setByteArrayRepresentation(document5.getField(fieldName).binaryValue().bytes, document5.getField(fieldName).binaryValue().offset, document5.getField(fieldName).binaryValue().length);
featureVector5 = cachedInstance5.getFeatureVector();
distance1 = cachedInstance1.getDistance(cachedInstance2);
distance2 = cachedInstance2.getDistance(cachedInstance3);
distance3 = cachedInstance3.getDistance(cachedInstance4);
distance4 = cachedInstance4.getDistance(cachedInstance5);
bool = (distance1 == 0.0) && (distance1 == distance2) && (distance2 == distance3) && (distance3 == distance4);
bool1 = Arrays.equals(featureVector, featureVector1);
bool2 = Arrays.equals(featureVector1, featureVector2);
bool3 = Arrays.equals(featureVector2, featureVector3);
bool4 = Arrays.equals(featureVector3, featureVector4);
bool5 = Arrays.equals(featureVector4, featureVector5);
if (!(bool && bool1 && bool2 && bool3 && bool4 && bool5)) System.err.println("ERROR using " + path);
}
System.out.println("Global done...");
}
public void testLocal() throws IOException, IllegalAccessException, InstantiationException {
ArrayList<String> images = FileUtils.readFileLines(new File(imagePath), true);
testLocal(images);
}
public void testLocal(ArrayList<String> images) throws IOException, IllegalAccessException, InstantiationException {
AbstractAggregator aggregator = aggregatorClass.newInstance();
Cluster[] codebook32 = Cluster.readClusters(codebookPath + "CvSURF32");
Cluster[] codebook128 = Cluster.readClusters(codebookPath + "CvSURF128");
LinkedList<Cluster[]> listOfCodebooks = new LinkedList<Cluster[]>();
listOfCodebooks.add(codebook32);
listOfCodebooks.add(codebook128);
LocalFeatureExtractor localFeatureExtractor = localFeatureClass.newInstance();
LocalFeature feature = localFeatureClass.newInstance().getClassOfFeatures().newInstance();
LocalFeature cachedInstance1 = localFeatureClass.newInstance().getClassOfFeatures().newInstance();
LocalFeature cachedInstance2 = localFeatureClass.newInstance().getClassOfFeatures().newInstance();
LocalFeature cachedInstance3 = localFeatureClass.newInstance().getClassOfFeatures().newInstance();
LocalFeature cachedInstance4 = localFeatureClass.newInstance().getClassOfFeatures().newInstance();
LocalFeature cachedInstance5 = localFeatureClass.newInstance().getClassOfFeatures().newInstance();
LocalFeature cachedInstance6 = localFeatureClass.newInstance().getClassOfFeatures().newInstance();
String fieldName = feature.getFieldName() + aggregator.getFieldName() + "32";
//Ways to create LocalDocumentBuilder
LocalDocumentBuilder localDocumentBuilder = new LocalDocumentBuilder();
localDocumentBuilder.addExtractor(localFeatureClass, codebook32);
LocalDocumentBuilder localDocumentBuilder1 = new LocalDocumentBuilder();
localDocumentBuilder1.addExtractor(localFeatureClass, listOfCodebooks);
LocalDocumentBuilder localDocumentBuilder2 = new LocalDocumentBuilder(localFeatureClass, codebook32);
LocalDocumentBuilder localDocumentBuilder3 = new LocalDocumentBuilder(localFeatureClass, listOfCodebooks);
LocalDocumentBuilder localDocumentBuilder4 = new LocalDocumentBuilder(aggregatorClass);
localDocumentBuilder4.addExtractor(localFeatureClass, listOfCodebooks);
LocalDocumentBuilder localDocumentBuilder5 = new LocalDocumentBuilder(localFeatureClass, codebook32, aggregatorClass);
LocalDocumentBuilder localDocumentBuilder6 = new LocalDocumentBuilder(localFeatureClass, listOfCodebooks, aggregatorClass);
BufferedImage image;
double[] featureVector, featureVector1, featureVector2, featureVector3, featureVector4, featureVector5, featureVector6;
Document document1, document2, document3, document4, document5, document6;
double distance1, distance2, distance3, distance4, distance5;
boolean bool, bool1, bool2, bool3, bool4, bool5, bool6;
List<? extends LocalFeature> listOfLocalFeatures;
for (String path : images) {
image = ImageIO.read(new FileInputStream(path));
localDocumentBuilder.extractLocalFeatures(image, localFeatureExtractor);
listOfLocalFeatures = localFeatureExtractor.getFeatures();
aggregator.createVectorRepresentation(listOfLocalFeatures, codebook32);
featureVector = aggregator.getVectorRepresentation();
document1 = localDocumentBuilder1.createDocument(image, imagePath);
cachedInstance1.setByteArrayRepresentation(document1.getField(fieldName).binaryValue().bytes, document1.getField(fieldName).binaryValue().offset, document1.getField(fieldName).binaryValue().length);
featureVector1 = cachedInstance1.getFeatureVector();
document2 = localDocumentBuilder2.createDocument(image, imagePath);
cachedInstance2.setByteArrayRepresentation(document2.getField(fieldName).binaryValue().bytes, document2.getField(fieldName).binaryValue().offset, document2.getField(fieldName).binaryValue().length);
featureVector2 = cachedInstance2.getFeatureVector();
document3 = localDocumentBuilder3.createDocument(image, imagePath);
cachedInstance3.setByteArrayRepresentation(document3.getField(fieldName).binaryValue().bytes, document3.getField(fieldName).binaryValue().offset, document3.getField(fieldName).binaryValue().length);
featureVector3 = cachedInstance3.getFeatureVector();
document4 = localDocumentBuilder4.createDocument(image, imagePath);
cachedInstance4.setByteArrayRepresentation(document4.getField(fieldName).binaryValue().bytes, document4.getField(fieldName).binaryValue().offset, document4.getField(fieldName).binaryValue().length);
featureVector4 = cachedInstance4.getFeatureVector();
document5 = localDocumentBuilder5.createDocument(image, imagePath);
cachedInstance5.setByteArrayRepresentation(document5.getField(fieldName).binaryValue().bytes, document5.getField(fieldName).binaryValue().offset, document5.getField(fieldName).binaryValue().length);
featureVector5 = cachedInstance5.getFeatureVector();
document6 = localDocumentBuilder6.createDocument(image, imagePath);
cachedInstance6.setByteArrayRepresentation(document6.getField(fieldName).binaryValue().bytes, document6.getField(fieldName).binaryValue().offset, document6.getField(fieldName).binaryValue().length);
featureVector6 = cachedInstance6.getFeatureVector();
distance1 = cachedInstance1.getDistance(cachedInstance2);
distance2 = cachedInstance2.getDistance(cachedInstance3);
distance3 = cachedInstance3.getDistance(cachedInstance4);
distance4 = cachedInstance4.getDistance(cachedInstance5);
distance5 = cachedInstance5.getDistance(cachedInstance6);
bool = (distance1 == 0.0) && (distance1 == distance2) && (distance2 == distance3) && (distance3 == distance4) && (distance4 == distance5);
bool1 = Arrays.equals(featureVector, featureVector1);
bool2 = Arrays.equals(featureVector1, featureVector2);
bool3 = Arrays.equals(featureVector2, featureVector3);
bool4 = Arrays.equals(featureVector3, featureVector4);
bool5 = Arrays.equals(featureVector4, featureVector5);
bool6 = Arrays.equals(featureVector5, featureVector6);
if (!(bool && bool1 && bool2 && bool3 && bool4 && bool5 && bool6)) System.err.println("ERROR using " + path);
}
System.out.println("Local done...");
}
public void testSimple() throws IOException, IllegalAccessException, InstantiationException {
ArrayList<String> images = FileUtils.readFileLines(new File(imagePath), true);
testSimple(images);
}
public void testSimple(ArrayList<String> images) throws IOException, IllegalAccessException, InstantiationException {
AbstractAggregator aggregator = aggregatorClass.newInstance();
Cluster[] codebook32 = Cluster.readClusters(codebookPath + "SIMPLEdetCVSURFCEDD32");
Cluster[] codebook128 = Cluster.readClusters(codebookPath + "SIMPLEdetCVSURFCEDD128");
LinkedList<Cluster[]> listOfCodebooks = new LinkedList<Cluster[]>();
listOfCodebooks.add(codebook32);
listOfCodebooks.add(codebook128);
SimpleExtractor simpleExtractor = new SimpleExtractor(globalFeatureClass.newInstance(), keypointDetector);
LocalFeature cachedInstance1 = simpleExtractor.getClassOfFeatures().newInstance();
LocalFeature cachedInstance2 = simpleExtractor.getClassOfFeatures().newInstance();
LocalFeature cachedInstance3 = simpleExtractor.getClassOfFeatures().newInstance();
LocalFeature cachedInstance4 = simpleExtractor.getClassOfFeatures().newInstance();
LocalFeature cachedInstance5 = simpleExtractor.getClassOfFeatures().newInstance();
LocalFeature cachedInstance6 = simpleExtractor.getClassOfFeatures().newInstance();
String fieldName = simpleExtractor.getFieldName() + aggregator.getFieldName() + "32";
//Ways to create SimpleDocumentBuilder
SimpleDocumentBuilder simpleDocumentBuilder = new SimpleDocumentBuilder();
simpleDocumentBuilder.addExtractor(globalFeatureClass, keypointDetector, codebook32);
SimpleDocumentBuilder simpleDocumentBuilder1 = new SimpleDocumentBuilder();
simpleDocumentBuilder1.addExtractor(globalFeatureClass, keypointDetector, listOfCodebooks);
SimpleDocumentBuilder simpleDocumentBuilder2 = new SimpleDocumentBuilder(globalFeatureClass, keypointDetector, codebook32);
SimpleDocumentBuilder simpleDocumentBuilder3 = new SimpleDocumentBuilder(globalFeatureClass, keypointDetector, listOfCodebooks);
SimpleDocumentBuilder simpleDocumentBuilder4 = new SimpleDocumentBuilder(aggregatorClass);
simpleDocumentBuilder4.addExtractor(globalFeatureClass, keypointDetector, listOfCodebooks);
SimpleDocumentBuilder simpleDocumentBuilder5 = new SimpleDocumentBuilder(globalFeatureClass, keypointDetector, codebook32, aggregatorClass);
SimpleDocumentBuilder simpleDocumentBuilder6 = new SimpleDocumentBuilder(globalFeatureClass, keypointDetector, listOfCodebooks, aggregatorClass);
BufferedImage image;
double[] featureVector, featureVector1, featureVector2, featureVector3, featureVector4, featureVector5, featureVector6;
Document document1, document2, document3, document4, document5, document6;
double distance1, distance2, distance3, distance4, distance5;
boolean bool, bool1, bool2, bool3, bool4, bool5, bool6;
List<? extends LocalFeature> listOfLocalFeatures;
for (String path : images) {
image = ImageIO.read(new FileInputStream(path));
simpleDocumentBuilder.extractLocalFeatures(image, simpleExtractor);
listOfLocalFeatures = simpleExtractor.getFeatures();
aggregator.createVectorRepresentation(listOfLocalFeatures, codebook32);
featureVector = aggregator.getVectorRepresentation();
document1 = simpleDocumentBuilder1.createDocument(image, imagePath);
cachedInstance1.setByteArrayRepresentation(document1.getField(fieldName).binaryValue().bytes, document1.getField(fieldName).binaryValue().offset, document1.getField(fieldName).binaryValue().length);
featureVector1 = cachedInstance1.getFeatureVector();
document2 = simpleDocumentBuilder2.createDocument(image, imagePath);
cachedInstance2.setByteArrayRepresentation(document2.getField(fieldName).binaryValue().bytes, document2.getField(fieldName).binaryValue().offset, document2.getField(fieldName).binaryValue().length);
featureVector2 = cachedInstance2.getFeatureVector();
document3 = simpleDocumentBuilder3.createDocument(image, imagePath);
cachedInstance3.setByteArrayRepresentation(document3.getField(fieldName).binaryValue().bytes, document3.getField(fieldName).binaryValue().offset, document3.getField(fieldName).binaryValue().length);
featureVector3 = cachedInstance3.getFeatureVector();
document4 = simpleDocumentBuilder4.createDocument(image, imagePath);
cachedInstance4.setByteArrayRepresentation(document4.getField(fieldName).binaryValue().bytes, document4.getField(fieldName).binaryValue().offset, document4.getField(fieldName).binaryValue().length);
featureVector4 = cachedInstance4.getFeatureVector();
document5 = simpleDocumentBuilder5.createDocument(image, imagePath);
cachedInstance5.setByteArrayRepresentation(document5.getField(fieldName).binaryValue().bytes, document5.getField(fieldName).binaryValue().offset, document5.getField(fieldName).binaryValue().length);
featureVector5 = cachedInstance5.getFeatureVector();
document6 = simpleDocumentBuilder6.createDocument(image, imagePath);
cachedInstance6.setByteArrayRepresentation(document6.getField(fieldName).binaryValue().bytes, document6.getField(fieldName).binaryValue().offset, document6.getField(fieldName).binaryValue().length);
featureVector6 = cachedInstance6.getFeatureVector();
distance1 = cachedInstance1.getDistance(cachedInstance2);
distance2 = cachedInstance2.getDistance(cachedInstance3);
distance3 = cachedInstance3.getDistance(cachedInstance4);
distance4 = cachedInstance4.getDistance(cachedInstance5);
distance5 = cachedInstance5.getDistance(cachedInstance6);
bool = (distance1 == 0.0) && (distance1 == distance2) && (distance2 == distance3) && (distance3 == distance4) && (distance4 == distance5);
bool1 = Arrays.equals(featureVector, featureVector1);
bool2 = Arrays.equals(featureVector1, featureVector2);
bool3 = Arrays.equals(featureVector2, featureVector3);
bool4 = Arrays.equals(featureVector3, featureVector4);
bool5 = Arrays.equals(featureVector4, featureVector5);
bool6 = Arrays.equals(featureVector5, featureVector6);
if (!(bool && bool1 && bool2 && bool3 && bool4 && bool5 && bool6)) System.err.println("ERROR using " + path);
}
System.out.println("Simple done...");
}
}