gal.udc.fic.muei.tfm.dap.flipper.service.util.cbir.LireBuilder.java Source code

Java tutorial

Introduction

Here is the source code for gal.udc.fic.muei.tfm.dap.flipper.service.util.cbir.LireBuilder.java

Source

package gal.udc.fic.muei.tfm.dap.flipper.service.util.cbir;

import gal.udc.fic.muei.tfm.dap.flipper.domain.enumeration.FeatureEnumerate;
import net.semanticmetadata.lire.DocumentBuilder;
import net.semanticmetadata.lire.DocumentBuilderFactory;
import net.semanticmetadata.lire.ImageSearchHits;
import net.semanticmetadata.lire.ImageSearcher;
import net.semanticmetadata.lire.impl.GenericFastImageSearcher;
import net.semanticmetadata.lire.utils.LuceneUtils;
import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.*;
import org.apache.lucene.store.FSDirectory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 *
 * Lire indexer and search in Apache Lucene
 *
 * This file is part of Flipper Open Reverse Image Search.
    
 Flipper Open Reverse Image Search 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 3 of the License, or
 (at your option) any later version.
    
 Flipper Open Reverse Image Search 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 Flipper Open Reverse Image Search.  If not, see <http://www.gnu.org/licenses/>.
 */
public class LireBuilder {

    private static final Logger log = LoggerFactory.getLogger(LireBuilder.class);

    private static final String INDEX_DIR = "index";
    private static final int MIN_DESCRIPTORS = 4;

    /**
     * Index for each builder type
     * @param image
     * @param picture_id
     * @param prefix
     * @param builder
     * @param conf
     * @throws IOException
     */
    private static void luceneIndexer(BufferedImage image, UUID picture_id, String prefix, DocumentBuilder builder,
            IndexWriterConfig conf) throws IOException {
        File path = getPath(prefix);
        log.debug("creating indexed path " + path.getAbsolutePath());
        IndexWriter iw = new IndexWriter(FSDirectory.open(path), conf);

        try {
            Document document = builder.createDocument(image, picture_id.toString());
            iw.addDocument(document);

        } catch (Exception e) {
            System.err.println("Error reading image or indexing it.");
            e.printStackTrace();
        }

        // closing the IndexWriter
        iw.close();
    }

    /**
     * Search a picture
     *
     * @param imageBytes
     * @param maxHits
     * @param feature
     * @param pictures
     * @return
     * @throws IOException
     */
    public static List<LirePictureSortable> search(byte[] imageBytes, int maxHits, FeatureEnumerate feature,
            List<LirePictureSortable> pictures) throws IOException {
        File path = getPath(feature.getText());
        log.debug("reading from indexed path " + path.getAbsolutePath());
        List<LirePictureSortable> result = new ArrayList<>();

        try {
            IndexReader ir = DirectoryReader.open(FSDirectory.open(path));
            ImageSearcher searcher = new GenericFastImageSearcher(maxHits, feature.getValueClass());

            // searching with a image file ...
            InputStream in = new ByteArrayInputStream(imageBytes);

            ImageSearchHits hits = searcher.search(in, ir);

            float score = 0.0F;
            for (int i = 0; i < hits.length(); i++) {
                score = hits.score(i);
                LirePictureSortable lp = new LirePictureSortable(
                        UUID.fromString(hits.doc(i).getValues(DocumentBuilder.FIELD_NAME_IDENTIFIER)[0]), score,
                        feature);

                /* check is its a picture was repeated by picture UUID */
                if (pictures.contains(lp)) {
                    lp = pictures.get(pictures.indexOf(lp));
                    lp.addDescriptor(feature, score);
                    lp.addScore(score);
                } else {
                    result.add(lp);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * Delete a term document
     * @param pictureId
     * @param conf
     * @throws IOException
     */
    public static void delete(UUID pictureId, IndexWriterConfig conf) throws IOException {

        /* create term to delete document */
        Term term = new Term(DocumentBuilder.FIELD_NAME_IDENTIFIER, pictureId.toString());

        for (FeatureEnumerate f : FeatureEnumerate.values()) {
            deleteFromFeature(pictureId, term, f.getText(), conf);
        }
    }

    /**
     * Index a picture
     * @param source
     * @param picture_id
     * @param conf
     * @throws IOException
     */
    public static void index(byte[] source, UUID picture_id, IndexWriterConfig conf) throws IOException {
        ByteArrayInputStream in = new ByteArrayInputStream(source);
        BufferedImage image = ImageIO.read(in);

        // Creating an Lucene IndexWriter
        log.debug("Is Lucene configured? " + (conf == null));
        if (conf == null) {
            conf = new IndexWriterConfig(LuceneUtils.LUCENE_VERSION,
                    new WhitespaceAnalyzer(LuceneUtils.LUCENE_VERSION));
            conf.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
        }

        luceneIndexer(image, picture_id, FeatureEnumerate.AutoColorCorrelogram.getText(),
                DocumentBuilderFactory.getAutoColorCorrelogramDocumentBuilder(), conf);
        luceneIndexer(image, picture_id, FeatureEnumerate.CEDD.getText(),
                DocumentBuilderFactory.getCEDDDocumentBuilder(), conf);
        luceneIndexer(image, picture_id, FeatureEnumerate.ColorLayout.getText(),
                DocumentBuilderFactory.getColorLayoutBuilder(), conf);
        luceneIndexer(image, picture_id, FeatureEnumerate.EdgeHistogram.getText(),
                DocumentBuilderFactory.getEdgeHistogramBuilder(), conf);
        luceneIndexer(image, picture_id, FeatureEnumerate.ColorHistogram.getText(),
                DocumentBuilderFactory.getColorHistogramDocumentBuilder(), conf);
        luceneIndexer(image, picture_id, FeatureEnumerate.PHOG.getText(),
                DocumentBuilderFactory.getPHOGDocumentBuilder(), conf);

    }

    private static void deleteFromFeature(UUID pictureId, Term term, String prefix, IndexWriterConfig conf)
            throws IOException {

        File file = getPath(prefix);

        // Creating an Lucene IndexWriter
        log.debug("Is Lucene configured: " + (conf == null));
        if (conf == null) {
            conf = new IndexWriterConfig(LuceneUtils.LUCENE_VERSION,
                    new WhitespaceAnalyzer(LuceneUtils.LUCENE_VERSION));
            conf.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
        }
        IndexWriter iw = new IndexWriter(FSDirectory.open(file), conf);

        iw.deleteDocuments(term);

        iw.close();
    }

    private static File getPath(String prefix) throws IOException {
        File path = new File(INDEX_DIR + File.separator + prefix);
        if (!(path.exists() && path.isDirectory()) && !path.mkdirs()) {
            throw new IOException(path.getName() + " not exists.");
        }

        return path;
    }

    /**
     * Search pictures that appear in all features
     *
     * @param source
     * @param maxHist
     * @param featureEnumerates
     * @return
     * @throws IOException
     */
    public static List<LirePictureSortable> searchAllFeatures(byte[] source, int maxHist,
            List<FeatureEnumerate> featureEnumerates) throws IOException {

        /* extract pictures sortable info from Lucene indexes */
        /* only from extract features from picture search */
        List<LirePictureSortable> result = new ArrayList<>();
        for (FeatureEnumerate feature : featureEnumerates) {
            result.addAll(LireBuilder.search(source, maxHist, feature, result));
        }

        /* save UUID from pictures ordered by score */
        Collections.sort(result);

        return result;
    }
}