画像の類似性を測定するには何百もの方法があるはずです。それは巨大な分野です。それらは、考慮しようとする画像の特徴によって (ほとんど) 異なります。
スコットが言ったように、一連の類似性尺度はヒストグラムに基づいています。これらの手法では、ピクセルが空間的にどのように配置されているかを考慮していないため、2 つの画像が 45 度回転している場合、2 つの画像は同じと見なされる可能性があります。ヒストグラムを見つけるのが速いので、それらも高速です。
単純なヒストグラム マッチャーは次のようになります。2 つの入力画像のヒストグラムを見つけ、正規化 (2 つのヒストの面積が同じになるように...これにより画像サイズの違いが取り除かれます)、減算、二乗、および合計。現在、数値が小さいほど一致が良好であることを意味し、数値が大きいほど一致が悪化することを意味します。
ruby-vips では次のようになります。
require 'vips'
a = Vips::Image.new_from_file ARGV[0], access: :sequential
b = Vips::Image.new_from_file ARGV[1], access: :sequential
# find hists, normalise, difference, square
diff_hist = (a.hist_find.hist_norm - b.hist_find.hist_norm) ** 2
# find sum of squares ... find the average, then multiply by the size of the
# histogram
similarity = diff_hist.avg * diff_hist.width * diff_hist.height
puts "similarity = #{similarity}"
私のデスクトップでは、これは 2k x 3k の JPEG 画像のペアに対して約 0.5 秒で実行されます。
多くのマッチャーは、空間分布に基づいています。簡単な方法は、画像を 8x8 のグリッド (チェス盤のようなもの) に分割し、各正方形の平均ピクセル値を取得してから、正方形の平均が上か下かに応じて、その正方形を 0 または 1 に設定することです。画像全体の平均。これにより、画像のフィンガープリントのようなものが得られ、64 ビット int にきれいに保存できます。ノイズ、スケールの変化、小さな回転などの影響を受けません。
2 つの画像の類似性をテストするには、それらのフィンガープリントを XOR し、結果の設定ビット数を数えます。繰り返しますが、0 は完全に一致し、より大きな数値はあまり良くありません。
ruby-vips では、次のようにコーディングできます。
require 'vips'
a = Vips::Image.new_from_file ARGV[0], access: :sequential
# we need a mono image
a = a.colourspace "b-w"
# reduce to 8x8 with a box filter
a = a.shrink(a.width / 8, a.height / 8)
# set pixels to 0 for less than average, 255 for greater than average
a = a > a.avg
a.write_to_file ARGV[1]
繰り返しますが、これは 2k x 3k JPEG の場合、約 0.5 秒で実行されます。
さらに別のファミリは、相関関係に基づいています。spcorとその友人を参照してください。画像の小さな領域を見つけるのに役立つ場合があります。
多くの洗練された画像類似度メトリックは、さまざまなアルゴリズムを使用してすべてを実行し、一連の重み係数を使用して全体的な類似度を計算します。