オープンソースの類似画像検索エンジンisk-daemonを使ってみたので、その際の手順やはまりどころなどを書いておきます。
現時点では、isk-daemonはあまりメンテされていないようで、面倒な点が多々あり「使ってみよう」という方は覚悟しておいたほうがいいかもしれません。
クライアントについては、XML-RPC/JSON-RPC/SOAPが使えますが、今回はPythonでXML-RPCを使いました。
使用したOSはUbuntu7.10です。Pythonのバージョンは2.5.1です。Windowsでも動かせるのですが、必要なモジュールやファイルパスの設定などで面倒な部分があるので今回は避けました。
- 準備
動作に必要なパッケージをインストールしておきます。
python2.5 libmagick libmagick++
Ubuntuの場合だとaptで、
python2.5 libmagick9 libmagick9-dev libmagick++9c2a libmagick++9-dev
あたりをインストールすればよいです。
isk-daemonの起動時にlibmagickのライブラリがロードできないエラーが出た場合は、soファイルの場所をチェックする。エイリアスを作ったりしてロードできるようにしてやればよい。
- isk-daemonを入手する
isk-daemonのサイトのDownloadからSourceForgeへ行ってダウンロードします。
http://server.imgseek.net/category/download/
今回使用したバージョンは0.6.2です。isk-daemonは0.6.2からオープンソースになったみたいです。
ダウンロードが終わったら、アーカイブを展開しておきます。
- _imgdb.soの入手
isk-daemonの0.6.2のChangeLogに試用に関するコードを削除したとあるのですが、アーカイブに入っている"_imgdb.so"のバイナリは古いバージョンのものでした。最新のものを入手する必要があります。
ソースコードの入手とビルドの方法については次のページにあります(英語)。
http://server.imgseek.net/category/source/
SVNでhttps://imgseek.svn.sourceforge.net/svnroot/imgseek/trunk/net.imgseek.imgdbからソースをチェックアウトしてきます。
ビルドにはpython-devやコンパイラが必要ですので、インストールしておいてください。
今回は、
python2.5-dev g++
をインストールしておきました。
"src/net/imgseek/imgdb/core"ディレクトリにビルド用のスクリプトがあるので、実行します。
$ python build-python.py build
buildディレクトリの下にシステムタイプの名前のディレクトリがあり、その中にimgdb.soが作成されています。
imgdb.soをisk-daemonのimgSeekLibディレクトリにコピーし、ファイル名を"_imgdb.so"に変更します。
また、ソースの確認はしていませんがロードできない関数がimgSeekLib/imgdb.pyにあったので、コメントアウトしておきます。
#mostPopularKeywords = _imgdb.mostPopularKeywords
- settings.pyの編集
isk-daemonのルートにsettings.pyという名前の設定ファイルがあるので、編集します。
databasePathにデータベースファイルのパスを指定します。
登録したデータを自動的に保存したい場合はautomaticSaveをTrueにしておきます。saveIntervalに設定した間隔(秒)で自動的に保存されるようになります。
startAsDaemonをTrueにするとデーモン動作させられるのですが、TwistedのDocumentRootの設定がカレントディレクトリからの相対で書かれているので、isk-daemon.pyを修正する必要があります。
- isk-daemonを起動する
isk-daemon.pyを実行してisk-daemonを起動します。
$ python isk-daemon.py
- isk-daemonの管理画面でデータベースを作成する
http://localhost:31128/にブラウザでアクセスするとAjaxを使った管理画面が表示されます。
画面左の『Databases』メニューを選択し、『Create new』タブからデータベースID(半角数字)を入力して『Add』ボタンをクリックします。これでデータベースが作成されます。
データベースIDはAPIの利用時に指定する必要があるので、メモしておくとよいです。
- APIを利用する
APIリファレンス(英語)は次のページにあります。
http://server.imgseek.net/category/documentation/api/
また、isk-serverのアーカイブのdocディレクトリに、java/php/pythonのクライアントのサンプルコードがあるので、参考になるかと思います。
- APIでデータベースに画像を登録する
まず検索を行うために画像をデータベースに登録する*1必要があります。
Pythonでの場合の例だと次の通り。
from xmlrpclib import ServerProxy dbId = 1 # データベースID id = 1 # データベース上での画像の識別ID(任意) filepath = '/var/www/example.com/htdocs/foo.png' fileurl = 'http://example.com/foo.png' server = ServerProxy('http://localhost:31128/RPC') # サーバ上のローカルファイル指定の場合 server.addImg(dbId, id, filepath) # インターネット上のファイルの場合 server.addImg(dbId, id, fileurl, True)
- APIで画像を検索する
画像の検索では、データベース上の画像の識別IDを指定し、対象の画像と類似する画像のID一覧を取得できます。
from xmlrpclib import ServerProxy dbId = 1 # データベースID id = 1 # 検索する画像の識別ID numres = 10 # 取得する検索結果の数-1 server = ServerProxy('http://localhost:31128/RPC') results_list = server.queryImgDb(dbId, id, numres) for result_id, result_ratio in results_list: print 'ID: %d, Ratio: %f' % (result_id, result_ratio)
実行例.
ID: 11, Ratio: 99.741603 ID: 1, Ratio: 99.741603 ID: 1182, Ratio: 32.820870 ID: 83, Ratio: 32.097147 ID: 136, Ratio: 29.387254 ID: 298, Ratio: 27.346831 ID: 388, Ratio: 26.226296 ID: 54, Ratio: 26.049704 ID: 53, Ratio: 26.049704 ID: 755, Ratio: 24.954222 ID: 123, Ratio: 24.647017
- 画像の実体をどう扱うか
isk-daemonは、画像のメタデータのみをデータベースに保存するため、画像ファイルの管理は完全に切り離されています。
実際にこのエンジンを用いてアプリを作成する場合、RDBMSなどを使ってisk-daemon上のIDとファイルのパスを結びつけるような形にすればよいです。