ZAICOでは、Android・iOS・Rubyエンジニアを絶賛募集中です! 詳しくは、採用ページをご覧ください。
目次
はじめに
こんにちは! ZAICO開発チームです。
先日、ZAICOではFedEx-WEEKが開催されました。
今回は「写真で在庫検索」をやってみましたので、そのレポートを書きたいと思います。
やったこと
実際に開発したものを動画にしましたのでご覧ください。
・類似画像検索
・OCR検索(物品のラベル情報を読み取って検索)
・写真で物品登録 → OCR検索
どうやってるか
初期構想としては、画像の特徴量を抽出してベクトル化、Elasticsearchに流し込んで、コサイン類似度で検索、みたいなことをやる予定でした。
特徴量の抽出はOpenCVを使ったら手軽に出来そう、ぐらいの気持ちでした。
実際、AKAZEというアルゴリズムで特徴点および特徴量の抽出まではすんなりいけました。
ただ、この「特徴点の数」というのが指定する写真ごとに異なっていて、一定の次元数のベクトルデータにうまく変換することが出来ず、時間も限られていたので今回はやむなく断念しました。。
そうなると、流行りの機械学習モデルを使った特徴量抽出の仕組みを使う、という選択になりますが、極力運用・メンテコストはかけたくなかったので、今回は別のアプローチを考えてみました。
考えた方法がこちら。
Google頼りです(笑
しかし、なかなか侮れないところもあって、文字がラベリングされた商品はかなりの精度で商品名を検出できますし、ある程度名の知れた商品であれば大体WEB上に写真付きで情報が掲載されていますので、これをGoogleがうまいこと類似画像検索してくれて、最終的にそれらの類似画像が掲載されたページのタイトルから、いい感じにキーワードを抽出できるはず、という算段です。
画像の類似検索にはCloud Vision APIのWEB DETECTIONを使っていて、入力画像に対して以下のような結果が得られます。
{
“responses”: [
{
“webDetection”: {
“webEntities”: [
{
“entityId”: “/m/02p7_j8”,
“score”: 1.44225,
“description”: “Carnival in Rio de Janeiro”
},
…
],
“pagesWithMatchingImages”: [
{
“url”: “https://www.intrepidtravel.com/us/brazil/rio-carnival-122873”,
“pageTitle”: “\u003cb\u003eRio Carnival\u003c/b\u003e | Intrepid Travel US”,
“partialMatchingImages”: [
{
“url”: “https://www.intrepidtravel.com/sites/intrepid/files/styles/large/public/elements/product/hero/GGSR-Brazil-rio-carnival-ladies.jpg”
},
…
上記のように、類似画像が掲載されたページのタイトルも取れるので、これをElasticsearchのMore like this queryに渡すキーワードとします。
さらに物品自体にラベリングされている文字のOCR結果もキーワードに加えることで、類似画像が見つからないようなケースにもできるだけ対応したつもりです。
また、ここからはどちらかというとElasticsearchの話ですが、実際にやってみると、うまくいかないケースもありました。
こちらは検証機としてまだまだ現役の我が家のiPhone6ですが、類似画像検索の結果「iPhone」というワードは抜き出せていましたが(たまにSAMSUNGになる)、どうしても「iPhone6」という物品名の在庫データにはマッチしてくれませんでした。
おそらくこの在庫データは「iPhone6」という単語として分割されてインデックスされているため、うまく部分一致検索にかかっていないと思われました。
対策として、多少検索が遅くなるようですが、ワイルドカードによる部分一致検索も合わせて行い、More like this queryのスコアに加算するように調整したところ、正しく検索にかかるようになりました。
またこの時、闇雲に部分一致検索してしまうと、全く関係のない在庫データまで引っかかってしまうようになったため、類似画像の掲載されたページタイトルが複数見つかった際、それらのページタイトルを形態素解析し、頻出する名詞・固有名詞のみ抽出して部分一致検索するよう工夫しました。
形態素解析には、GoogleのNatural Language APIを利用しています。
面白い使い方
最後に、何に役立つかはまだ明確ではないのですが、面白い使い方をご紹介します。
このように、複数の商品が存在するようなケースでも、ざっくり検索をかけることが可能です。
改善したいところ
類似画像検索を試していると、類似画像を含むページが見つからないケースも多々ありました。
対策として、類似画像検索時にwebEntityというラベルのようなものを取得出来るので、これも検索時のキーワードに含んでいるのですが、このラベルは大体英語になっていることが多いので、これをユーザーの言語設定に応じて翻訳してからマッチングする、そしてそれはカテゴリにマッチすることが多いだろうから、キーワードの種類によって検索対象項目を変える、といった具合に工夫すれば、もっと精度が上がるかもしれません。
その翻訳の際は、もちろんGoogle Cloud Translationを使うつもりです。
まとめ
今回、類似画像検索はgoogleに委ねる、という大胆な割り切りをしました。
が、googleの偉大さと、Elasticsearchの懐の深さを改めて実感することができました!
OCR × Elasticsearchの組み合わせでもっといろいろできそう!