Skip to content
nagadomi edited this page Sep 6, 2014 · 1 revision

Otama Ruby API

Ruby APIの使い方

モジュールのロード

require 'otama'

ドライバのオープンとクローズ

Otama.open : ドライバをオープンします。

require 'otama'

CONFIG = {
  "driver" => {
    "name" => "sim
  },
  "database" => {
    "driver" => "sqlite3",
    "name" => "./sample.db"
  }
}
Otama.open(CONFIG) do |otama|
  puts "OK"
end

Otama.openにブロックを渡す場合は、ブロックを抜けたときにクローズされます。 openの引数にはドライバの設定を渡します。

設定はYAML形式でも渡せます。

---
driver:
  name: sim
  data_dir: ./
  
database:
  driver: sqlite3
  name: ./sample.db
require 'otama'

CONFIG = 'config.yaml'

otama = Otama.open(CONFIG)
otama.close
puts "OK"

ブロックを渡さない場合は、Otamaのインスタンスを返します。 Otama#closeでクローズされます。

otamaの動作設定

ログレベルの設定

Otama.log_level= :ログ出力レベルを変更します。

ログレベルには以下の定数を指定します。

Otama::LOG_LEVEL_QUIET : なにも出力しません。

Otama::LOG_LEVEL_ERROR : エラー情報のみ表示します。

Otama::LOG_LEVEL_NOTICE : エラー以外のメッセージもあれば表示します。

Otama::LOG_LEVEL_DEBUG : デバッグ用のログも表示します。

デバッグ用のログには発行されたSQLや開発者が確認のために入れたメッセージ等が含まれます。

デフォルトではOtama::LOG_LEVEL_NOICEです。

require 'otama'

Otama.log_level = Otama::LOG_LEVEL_QUIET

ログファイルの設定

Otama.set_log_file :ログの出力先を変更します。

デフォルトでは、標準出力(STDOUT)と標準エラー出力(STDERR)に表示されています。

require 'otama'

LOG_FILE="./otama.log"

Otama.set_log_file(LOG_FILE)

Otama.set_log_fileにnilを渡すとデフォルトの動作に戻ります。

データベースの操作

otamaのドライバが使用するリソースの作成と削除

Otama#create_database :ドライバが使用するデータベース上のテーブルや検索用のリソースを作成します。

Otama#drop_database : ドライバが使用するデータベースのテーブルや検索用のリソースを削除します。

Otama#drop_index :データベースを含めない、ローカルの検索リソースのみを削除します。(pullによって復元可能)

require 'otama'

CONFIG = "config.yaml"

Otama.open(CONFIG) do |otama|
  otama.create_database
  otama.drop_index
  otama.drop_database
end

Otama#create_databaseを呼び出したとき、すでにテーブルがある場合は、なにもせず成功を返します。

Otama#drop_databaseは、登録済みデータも含め全て消してしまうので使用には注意してください。

Utility commandsには、これらの機能を呼び出すotama_create_database、otama_drop_index、otama_drop_databaseといったコマンドが用意されています。

追加

Otama#insert : 画像をデータベースに追加します。

otama側のデータベースに保存されるのは、画像を識別するためのIDとシリアライズされた特徴量だけで、画像自体は保存されません。

require 'otama'

CONFIG = "config.yaml"
FILE1 = "./foo.jpg"
FILE2 = "./bar.jpg"

Otama.open(CONFIG) do |otama|
  otama.create_database
  
  p otama.insert(:file => FILE1)
  p otama.insert(:data => File.open(FILE2).read)
  otama.pull
end

ファイル名を指定して挿入する場合は、:fileでファイル名を指定します。 メモリ上の画像データを挿入する場合は、:dataで画像データを指定します。(PNG/JPEG/GIFフォーマット)

Otama#insertは追加した画像のIDを文字列で返します。このIDは、otama内で画像を識別するもので、検索では画像の識別としてこのIDが返ります。

追加したデータはOtama#pullを実行するまで検索結果に反映される保障がありません。

検索

Otama#search :類似検索を実行します。

クエリには、画像ファイル名、メモリ上の画像データ、特徴ベクトル文字列、登録済み画像のIDが指定できます。

require 'otama'
require 'pp'

CONFIG = "config.yaml"
FILE1 = "./foo.jpg"
FILE2 = "./bar.jpg"
RESULT_MAX = 10

Otama.open(YAML.load_file(CONFIG)) do |otama|
  otama.insert(:file => FILE1)
  otama.pull
  
  pp otama.search(RESULT_MAX, :id => Otama.id(FILE1))
  pp otama.search(RESULT_MAX, :file => FILE1)
  pp otama.search(RESULT_MAX, :data => File.open(FILE2).read)
  pp otama.search(RESULT_MAX, :string => otama.feature_string(:file => FILE2))
end

Otama#searchはOtama::Recordの配列を返します。 Otama::Record#idで画像ID、Otama::Record#valueで付加情報を取得します。付加情報は、Otama::Record#value[:similarity]が類似度(スコア)で、他はドライバ依存です。

画像IDの取得

Otama.id : otama内で画像を識別するためのIDを取得します。

require 'otama'

FILE1 = './foo.jpg'
FILE2 = './bar.jpg'

p Otama.id(:file => FILE1)
p Otama.id(:data => File.open(FILE2).read)

otamaの画像IDは、画像データのSHA1ハッシュ値と同一です。バイナリが異なると表示上同じ画像でも異なるIDを返します。

削除

Otama#remove : 画像IDを指定してデータを削除します。

require 'otama'

CONFIG = "config.yaml"
FILE1 = "./foo.jpg"

Otama.open(CONFIG) do |otama|
  otama.remove(Otama.id(:file => FILE1))
  otama.pull
end

削除処理は論理削除です。検索結果に出なくなりますが、データベース上のレコードや検索用に確保したリソースは削除されません。また削除は、検索結果を削除フラグでフィルタリングすることで実現されているため、大量の不要データをOtama#removeで削除してもパフォーマンスは改善しません。

削除したデータはOtama#pullを実行するまで検索結果に反映される保障がありません。

データの同期

Otama#pull : データベース上のデータとローカルの検索インデックスを同期します。

これには、

  • 追加されたされたデータの反映
  • 削除されたデータの反映 が含まれます。

pullを実行することで他のノードで追加/削除されたデータがローカルの検索インデックスに反映されます。

類似度

Otama#similarity : 画像同士の類似度を求めます。

require 'otama'

CONFIG = 'config.yaml'
FILE1 = "./foo.jpg"
FILE2 = "./bar.jpg"

Otama.open(CONFIG) do |otama|
  p otama.similarity({:file => FILE1}, {:data => File.read(FILE2)})
end

ファイルを指定して比較する場合は、:fileでファイル名を指定します。 メモリ上の画像データを比較する場合は、:dataで画像データを指定します。(PNG/JPEG/GIFフォーマット) 登録済みの画像を比較する場合は、:idで画像IDを指定します。 特徴ベクトル文字列で比較す場合は、:stringで特徴ベクトルを指定します。 生の特徴ベクトルで比較する場合は、:rawで特徴ベクトルを指定します。

特徴ベクトルの取得

Otama#feature_stringで画像の特徴ベクトルをシリアライズしたもの(文字列データ)を取得します。 この文字列データは、Otama#searchやOtama#similarityで使用できます。

文字列の形式はドライバ依存です。

require 'otama'

CONFIG = 'config.yaml'
FILE1 = "./foo.jpg"
FILE2 = "./bar.jpg"

Otama.open(CONFIG) do |otama|
  fv1 = otama.feature_string(:file => FILE1)
  fv2 = otama.feature_string(:data => File.open(FILE2).read)
  p fv1
  p fv2
  p otama.search(10, :string => fv1)
  p otama.similarity({:string => fv1}, {:string => fv2})
end

Otama#feature_rawでは生の特徴ベクトルが取得できます。このデータの実体にはRuby側からはアクセスできません。 シリアライズ/デシリアライズのオーバーヘッドが無いため文字列形式よりも高速に使用できます。使い方は、Otama#feature_stringを同じです。

raw = otama.feature_raw(:string => otama.feature_string(:file => FILE1))
string = otama.feature_string(:raw => raw)

のように文字列形式と相互変換できます。

Clone this wiki locally