はじめに
類似画像の検出方法はいくつかありますが、今回はハミング距離による検出方法について記載します。
備忘録を兼ねて記事を書きますが、コメント等は随時いただけると助かります
ハミング距離について
ハミング距離というのは、簡単に言うと、ビットの違いを数えたものです。
同じ長さのビット列を比較し、値が違う箇所を数えると、それがハミング距離になります。
例えば、以下の2つのデータにおけるハミング距離は「3」です。
データ1 : 1000100111
データ2 : 0100100110
ハミング距離の求め方
類似画像を検出する際、一般的には、各画像のハッシュ値を取得して、そのハミング距離を求めます。
例えば、画像1、画像2のハッシュ値が以下だった場合
画像1 : 58FA9F3AA8AD958AEA6
画像2 : 70FA9D3AA8AD952AAA4
以下の2つを使うと、楽に求められます。
・排他的論理和(XOR)
・ビットのカウント
「排他的論理和(XOR)」というのは、2つのデータを比較して、ビットが同じ箇所に0、違う箇所に1を立てる演算方法です。
排他的論理和(XOR)の例 | |
---|---|
データ1 | 0100100110101101 |
データ2 | 1101100100101101 |
XOR | 1001000010000000 |
このXORのビット列について1が立っている箇所を数えたらいいのですが、プログラム上で計算するより、SQLを使った方が楽です。
先ほどの画像1、画像2のハッシュ値について、ハミング距離をSQLを用いて求めると
select bit_count(0x58FA9F3AA8AD958AEA6 ^ 0x70FA9D3AA8AD952AAA4)
これだけで済みます。
このSQLの実行結果は「5」なので、画像1と画像2のハミング距離は「5」となります。
どこまでを類似画像と定義するかは要件によって異なるので、検証を重ね、適切な閾値を導いてください。
注意点
上記のように、画像をハッシュ化すれば、類似画像の検出を行えます。
しかし、ここで気をつけないといけないのは、ハッシュ化の方法。
やり方によっては、異なる画像で同じハッシュ値になることもあります。
私が見かけたのは、画像をリサイズして大きさを揃え、モノクロ化してハッシュ値を求める方法。
ほとんどの画像では異なる値になりますが、一部の画像においては、見た目が全く違うのに同じハッシュ値になってしまいます。中には、イラストとテキスト画像が同じハッシュ値なんてことも。(たまたま見つけて調査に至りましたが、実際にありました)
どのくらいの精度を求められるかによって、ハッシュ値の求め方もどれを採用するべきか異なります。
(詳しくないので)ここでは言及しませんが、ハッシュ化の方法についても、検証を重ねて採用してください。
最後に
あまり使うケースが無い知識かと思いますが、なんらかのタイミングで、この知識が役立つ時が来れば幸いです。
色々と挑戦して、スキルアップを楽しみましょう!