スポンサードリンク



こんにちは。sinyです。

昨今、ディープラーニングが流行っていますが、今回はAverage Hashという基礎的な理論を使った類似画像検索プログラムをPythonで書いて検証してみました。

プログラム自体は至って簡単ですので、興味のある方はぜひ試してみてください。

 

Average Hashとは?

Average Hashは画像の形状を手軽に計算することができる手法の1つです。
画像から類似度を計算して比較することで、画像が似ているかどうかを判定するというものです。

Average Hashの計算は以下の手順になっています。

Average Hashの処理フロー
  1. 画像サイズを圧縮
  2. グレースケールに変換
  3. 画素の平均値を計算
  4. 各画素の値が平均値より上なら1、下なら0に変換

 

Average Hashで類似画像検出の実装

Average Hashで類似画像検索がどの程度できるのか検証してみました。

事例としては、メルカリの洋服系画像を5000枚ほどスクレイピングで収集し、その画像を素材にしました。

具体的には、「レディースのトップス」というカテゴリの洋服画像(下図)を使いました。

プログラムの解説

 

まず、必要なライブラリを読み込みます。

続いて初期値を設定します。

 

次に、メインとなるAverage Hashの関数と、Average Hashの計算結果の値の差異を比較するためにハミング距離というものを計算します。

ハミング距離は、2つのAverage Hash(ベクトル値)の差分情報だけを合計した値として計算します。

 

では、まず、検索したい画像のAverage Hash値を求めてみます。

実行結果としてAverage Hash値(target_dist)として形状(64,64)のデータが生成されます。

続いて、検索対象となる約5000ファイルの情報を読み込みます。

 

今回は4647個の画像ファイルを用意しました。

では、この4647個のファイルをすべて読み込みAverage Hash値を計算し、検索したい画像のAverage Hash値(target_dist)に対するハミング距離を一気に求めます。

※rateの値はハミング距離に対して類似画像と判定する閾値です。

 

上記プログラムを実行すると、ハミング距離がrate以下である画像の情報がresult変数に格納されます。

※resultの第1要素がハミング距離、第2要素が対象画像のファイルパス

 

これをmatplotlibで描画してみます。

 

 

結果は以下のようになりました。

一番上の大きい画像が検索ターゲットの画像で、下の小さい画像が類似として判定された画像です。

どうも、単純なAverage Hash値の計算ではうまく類似画像を判定できないようです。
※圧縮サイズをもっと増やしてみましたが改善は見られませんでした。

そもそも、Average Hash値の計算が画像データをグレースケール化している時点でRGBの色情報が欠落してしまうので精度が出ないのは当然か・・・
ということで、Average Hash値の計算プログラムをちょっとだけ改良してみました。

変更したのは以下の2か所。

※読み込んだ画像をグレースケール化しないように変更。

※画素データをArray化してReshapeする際にカラー画像を扱うために形状(size,size,3)に変換。

上記設定で、再度類似度を計算して、グラフ描画してみたところ以下のような結果になりました。

※赤枠は完全同一画像

全く違う洋服もありますが、全体的にはピンク系統の似たような形状の画像が抽出されました。
5000枚近くの画像からこれだけ絞り込めればそれなり使えそうな気はします。

 

まとめ

 

  • Average Hash値そのままの計算フロー(グレースケール化)だとうまく検出できない。
  • グレースケール化しないようにすればそれなりの精度はでる。
  • ただし、画像特性によるところが大きく、Mnistの手書き数字のような画像だとうまく画像判定できなかった。
  • おそらく検索対象の画素数がもともと小さいと精度はあがらない。(画素数が大きい画像だと精度がでるかも?)
  • ディープラーニングを使わなくても画像特性と用途によってはお手軽に実装できる類似画像判定機として利用できる可能性あり

 

以上、Average Hash値を使った類似画像判定に関する記事でした。

 

おすすめの記事