LIRE教程之源碼分析 |LIRE Tutorial of Analysis of the Source Code
最近在做地理圖像識別和檢索的研究,發現了一個很好用的框架LIRE,遂研究了一通。網上的教程不算很多,而且LIRE更新比較快,一些方法已經更新或廢棄,故想寫幾篇文章重新總結一下框架內的多種方法,方便他人使用。
LIRE(Lucene Image Retrieval)是一個開源的輕量級圖像識別Java框架,提供了多種簡單易用的圖片檢索方法。事實上,LIRE是基於Lucene這個全文檢索引擎修改的,也沿用了該檢索引擎的思路。
LIRE相關資料:
官網首頁:http://www.lire-project.net/
下載地址:http://www.itec.uni-klu.ac.at/~mlux/lire-release/
Github:https://github.com/dermotte/LIRE
官方文檔:https://github.com/dermotte/LIRE/blob/master/src/main/docs/developer-docs/docs/index.md
官方教程:http://www.semanticmetadata.net/wiki/
在進入正文之前,再推薦一下DaveBobo的博客,作者已經總結了不少方法,可以參考:https://blog.csdn.net/davebobo/article/category/6466512
在下載LIRE之后,同時也要確保Lucene相關的jar包沒有缺失。
接下來進入正題。本文的內容是結合官方給出的Sample Application,完成圖片的提取特征、索引生成、圖片檢索。下載地址:[LIRE Sample Application]
筆者使用的是Intellij Idea。首先導入工程。從左邊的文件夾中,可以發現LIRE的class都在net.semanticmetadata.lire這個文件夾中,而官方給出的案例則在net.semanticmetada.sampleapplication中。
圖片特征提取和索引生成
打開案例中的Index.java文件(Github),點擊右上角的三角,修改Idea的配置文件,輸入圖片文件夾的路徑。
運行,等待程序結束后發現右邊文件夾多出了一個index文件。
事實上,這個程序是最基本的索引文件。其步驟是:
(1) 讀取輸入文件夾下所有的照片文件。
(2) 設置提取圖片要素的方法和descriptors。
(3) 對圖片進行特征提取並寫入索引。
其中,重點在於圖片特征的提取方法。根據源碼,可以發現首先建立了一個GlobalFeatureBuilder。這相當於圖片提取的容器,再設置了圖片提取要素的方法,在這段源碼中包括CEDD,FCTH,AutoColorCorrelogram這三種方法。事實上,除了這些方法之外,還可以參考lib/net.semanticmetadata.lire/imageanalysis/features/global這個文件夾下的其他類,這個文件夾下包括了LIRE中包含的全局要素提取方法。
GlobalDocumentBuilder globalDocumentBuilder = new GlobalDocumentBuilder(false, false);
globalDocumentBuilder.addExtractor(CEDD.class);
globalDocumentBuilder.addExtractor(FCTH.class);
globalDocumentBuilder.addExtractor(AutoColorCorrelogram.class);
接下來,只要使用GlobalDocumentBuilder.createDocument()方法就可以完成圖片的特征提取。提取之后還需要建立索引,從而方便之后的圖片檢索。LIRE是建立在Lucene的基礎上的,通過Lucene可以非常快速建立文檔及其索引。新建一個IndexWriter,並將圖片的特征寫入其中。具體代碼是下面這一段:
BufferedImage img = ImageIO.read(new FileInputStream(imageFilePath));
Document document = globalDocumentBuilder.createDocument(img, imageFilePath);
iw.addDocument(document);
即從本地上讀取圖片,再進行圖片的特征提取,最后生成索引文件。
圖片檢索
在完成圖片的特征提取之后,下一步是進行圖片的檢索,即給定一張圖片,找出與這張圖片最相似的圖片。
打開案例中的Searcher.java文件(Github)。修改Idea配置文件,傳入給定圖片的路徑。
運行之后可以發現輸出了一串從小到大的分數及其具體的圖片路徑。分數越小說明該圖片與給定圖片越相似。如果分數為0說明兩者一樣。
這個程序是最基本的檢索文件。其步驟是:
(1) 讀取給定的圖片。
(2) 讀取之前生成的圖片索引,尋找與給定圖片最相似的圖片。
(3) 輸出相似度分數及具體的圖片。
根據源碼,可以發現使用了IndexReader讀取了索引文件,之前是使用IndexWriter將這些索引文件寫入了硬盤。
IndexReader ir = DirectoryReader.open(FSDirectory.open(Paths.get("index")));
接下來使用了ImageSearcher.search()方法尋找最相似的圖片。其方法是使用CEDD方法對給定的圖片進行特征提取,之后在索引中進行搜索。在這段代碼中,返回與給定圖片最相似的30張圖片。ImageSearchHits即為最相似的圖片,可以從中獲取相似度分數和圖片路徑等。
ImageSearcher searcher = new GenericFastImageSearcher(30, CEDD.class);
ImageSearchHits hits = searcher.search(img, ir);
以上構成了一個完整的圖片特征提取-生成索引-圖片檢索步驟,使用這兩份代碼已經滿足基礎的使用了。