现在好多网站都有图片搜索的功能
现在java有个开源项目 为Lire 的,他是基于Lucene 3.3.0 的
官网:
http://www.semanticmetadata.net/lire/
现在写下他的使用方法
他有十三个Builder ,他们分别从不同的角度对图片做分析(当然你的Builder也可以只填一种)
可以分别根据他们的Search方法来 查出各自角度的相似图片进行排序让后从相似度由大到小返回回来 ,
首先举个例子,对某个文件夹里的图片建立索引,将他的名字保存到document里 descriptorImageIdentifier (这个在源码里可以看见)域里
indexSource 是图片的路径 ,indexName 是索引的目录
String indexSource = "c:\\priceImage";
String indexPath = "index";
String indexName= "myIndex";
这会在工程的目录下新建一个index文件夹,里面放建好的索引
Builder 初始化的例子:
全局变量:
ChainedDocumentBuilder builder = (ChainedDocumentBuilder) getDocumentBuilder();
private DocumentBuilder getDocumentBuilder() { ChainedDocumentBuilder result = new ChainedDocumentBuilder(); // result.addBuilder(DocumentBuilderFactory // .getAutoColorCorrelogramDocumentBuilder()); // result.addBuilder(DocumentBuilderFactory.getScalableColorBuilder()); // result.addBuilder(DocumentBuilderFactory.getCEDDDocumentBuilder()); // result.addBuilder(DocumentBuilderFactory // .getColorHistogramDocumentBuilder()); // result.addBuilder(DocumentBuilderFactory.getColorLayoutBuilder()); result.addBuilder(DocumentBuilderFactory.getTamuraDocumentBuilder()); result.addBuilder(DocumentBuilderFactory.getEdgeHistogramBuilder()); result.addBuilder(DocumentBuilderFactory.getFCTHDocumentBuilder()); // result.addBuilder(DocumentBuilderFactory.getGaborDocumentBuilder()); // result.addBuilder(DocumentBuilderFactory.getJCDDocumentBuilder()); // result.addBuilder(DocumentBuilderFactory // .getJpegCoefficientHistogramDocumentBuilder()); return result; }
下面是创建索引:
public void testCreateIndex(String indexSource, String indexName) { // 创建索引的目录 try { IndexWriter iw = LuceneUtils.createIndexWriter(indexPath + "/"+indexName , true); // 得到本地图片 ArrayList<String> images = FileUtils.getAllImages(new File( indexSource), true); for (String identifier : images) { String[] testFilesPathTemp = identifier.split("\\\\"); Document doc; try { doc = builder.createDocument( new FileInputStream(identifier), testFilesPathTemp[testFilesPathTemp.length - 1] .split("\\.")[0]); } catch (FileNotFoundException e) { e.printStackTrace(); continue; } catch (IOException e) { e.printStackTrace(); continue; } catch (Exception e) { e.printStackTrace(); continue; } iw.addDocument(doc); } iw.close(); } catch (IOException e1) { e1.printStackTrace(); } }
测试后会在目录下建一个 文件夹 index \\ myIndex , 里面会有你图片的索引
建好后查询索引:下面的代码是根据一张图片 (可以是网络上的图片,也可以是本地的) 找到和你图片相似的图片,我这里返回了建索引的时候的图片名称,
ImageSearcher searcher = ImageSearcherFactory.createEdgeHistogramImageSearcher(10);
这句可以 create 不同的查询器,不过必须和你建立索引时的Builder 相匹配 (10) 表示返回的数量
public static List<String> searchImg(String imgUrl, String kindName) { List<String> imageNames = new ArrayList<String>(); try { IndexReader reader = IndexReader.open(FSDirectory.open(new File( kindName))); ImageSearcher searcher = ImageSearcherFactory .createEdgeHistogramImageSearcher(10); ImageSearchHits hits = null; if (imgUrl.startsWith("http:")) { hits = searcher.search(ImageIO.read(new URL(imgUrl)), reader); } else { hits = searcher.search(ImageIO .read(new FileInputStream(imgUrl)), reader); } for (int i = 0; i < hits.length(); i++) { imageNames.add(hits.doc(i).getFieldable( DocumentBuilder.FIELD_NAME_IDENTIFIER).stringValue()); } reader.close(); } catch (Exception e) { e.printStackTrace(); } for (String string : imageNames) { System.out.println(string); } return imageNames; }