Java tutorial
/* * This file is part of the LIRE project: http://www.semanticmetadata.net/lire * 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 * * Copyright statement: * ==================== * (c) 2002-2013 by Mathias Lux (mathias@juggle.at) * http://www.semanticmetadata.net/lire, http://www.lire-project.net * * Updated: 11.07.13 10:51 */ package net.semanticmetadata.lire.impl.searcher; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import net.semanticmetadata.lire.AbstractImageSearcher; import net.semanticmetadata.lire.DocumentBuilder; import net.semanticmetadata.lire.ImageDuplicates; import net.semanticmetadata.lire.ImageSearchHits; import net.semanticmetadata.lire.impl.SimpleImageSearchHits; import net.semanticmetadata.lire.impl.SimpleResult; import net.semanticmetadata.lire.indexing.parallel.ImageInfo; import net.semanticmetadata.lire.indexing.parallel.WorkItem; import net.semanticmetadata.lire.utils.GeoUtils; import org.apache.commons.lang3.StringUtils; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.MultiFields; import org.apache.lucene.util.Bits; /** * @author mc * */ public class LocationBasedImageSearcher extends AbstractImageSearcher { protected Logger logger = Logger.getLogger(getClass().getName()); //? private int maxHits = 20; // protected List<SimpleResult> docs; //? private float threshold = 3; public LocationBasedImageSearcher(int maxHits) { this.maxHits = maxHits; docs = new ArrayList<SimpleResult>(); } public ImageSearchHits search(BufferedImage image, ImageInfo imageInfo, IndexReader reader) throws IOException { if (StringUtils.isEmpty(imageInfo.getLng()) || StringUtils.isEmpty(imageInfo.getLat())) return null; //?? float maxDistance = findSimilar(reader, imageInfo); // SimpleImageSearchHits searchHits = new SimpleImageSearchHits(this.docs, maxDistance); return searchHits; } /** * @param reader * @param lireFeature * @return the maximum distance found for normalizing. * @throws java.io.IOException */ protected float findSimilar(IndexReader reader, ImageInfo imageInfo) throws IOException { float maxDistance = -1f, allMaxDistance = -1f; float tmpDistance = 0f; docs.clear(); //???? Bits liveDocs = MultiFields.getLiveDocs(reader); int docNumber = reader.numDocs(); Document d = null; for (int i = 0; i < docNumber; i++) { if (reader.hasDeletions() && !liveDocs.get(i)) continue; //? d = reader.document(i);//? tmpDistance = getDistance(d, imageInfo);//? //???? if (tmpDistance < 0 || tmpDistance > this.threshold) continue; //???? if (allMaxDistance < tmpDistance) { allMaxDistance = tmpDistance; } //?? if (maxDistance < 0) { maxDistance = tmpDistance; } //???? if (this.docs.size() < maxHits) { this.docs.add(new SimpleResult(tmpDistance, d, i)); if (tmpDistance > maxDistance) maxDistance = tmpDistance; //????? } else if (tmpDistance < maxDistance) { //??? this.docs.remove(this.docs.size() - 1); this.docs.add(new SimpleResult(tmpDistance, d, i)); //? maxDistance = tmpDistance; Collections.sort(docs); } } //? return maxDistance; } //???? protected float getDistance(Document doc, ImageInfo imageInfo) { //?????? String latText = doc.get(DocumentBuilder.FIELD_NAME_LAT); String lngText = doc.get(DocumentBuilder.FIELD_NAME_LNG); if (StringUtils.isEmpty(latText) || StringUtils.isEmpty(lngText) || StringUtils.isEmpty(imageInfo.getLat()) || StringUtils.isEmpty(imageInfo.getLng())) { return -1; } //????? double lat = Double.parseDouble(latText); double lng = Double.parseDouble(lngText); //?????? double latQuery = Double.parseDouble(imageInfo.getLat()); double lngQuery = Double.parseDouble(imageInfo.getLng()); if (Math.abs(lat - latQuery) >= 1 || Math.abs(lng - lngQuery) >= 1) { return Integer.MAX_VALUE; } if (logger.isLoggable(Level.INFO)) { logger.info("calcute distance:(" + latText + ", " + lngText + ") and (" + imageInfo.getLat() + ", " + imageInfo.getLng() + ")"); } //? return (float) GeoUtils.getGeoDistance(lat, lng, latQuery, lngQuery); } public ImageDuplicates findDuplicates(IndexReader reader) throws IOException { throw new UnsupportedOperationException(); } public ImageSearchHits search(Document doc, IndexReader reader) throws IOException { WorkItem imageInfo = new WorkItem(); imageInfo.setLat(doc.get(DocumentBuilder.FIELD_NAME_LAT)); imageInfo.setLng(doc.get(DocumentBuilder.FIELD_NAME_LNG)); BufferedImage image = null; return this.search(image, imageInfo, reader); } public ImageSearchHits search(BufferedImage image, IndexReader reader) throws IOException { return this.search(image, null, reader); } public String toString() { return "Location based searcher"; } }