必須有數百種測量圖像相似性的方式,這是一個巨大的領域。它們(主要)在他們試圖考慮的圖像的特徵中有所不同。正如斯科特所說,一組相似性度量是基於直方圖的。這些技術沒有考慮像素在空間上的排列方式,因此如果旋轉了45度,那麼您的兩幅圖像可能會被視爲相同。它們也很快,因爲找到直方圖很快。
一個簡單的直方圖匹配器可能是:找到兩個輸入圖像的直方圖,歸一化(所以兩個主題有相同的區域...這消除了圖像大小的差異),減去,平方和和。現在少數意味着一個好的搭配,數字越大意味着越差的搭配。
在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}"
在我的桌面上,這個運行在大約0.5秒的一對一個2K x 3K JPEG圖像。
許多匹配器都基於空間分佈。一個簡單的方法是將圖像分成8x8的網格(如棋盤),取每個平方的平均像素值,然後根據平方的平均值是高於還是低於平均值將該平方設置爲0或1整個圖像的平均值。這樣可以爲圖像提供類似指紋的圖像,您可以將它們整齊地存儲在64位整數中。它對噪音,尺度變化或小旋轉等不敏感。
要測試兩張圖像的相似度,請對它們的指紋進行XOR並對結果中設置的位數進行計數。再次,0將是完美的匹配,更大的數字會不太好。
在紅寶石貴賓,你可以爲這個代碼:
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]
這再次運行在大約0.5秒爲一個2K x 3K JPEG。
另一個家庭將基於相關性,請參閱spcor和朋友。它們可能對找到圖像的一個小區域更有用。
許多更漂亮的圖像相似性度量將採用各種算法,將它們全部運行,並使用一組權重因子來計算整體相似性度量。
它看起來像vips支持直方圖,並比較直方圖是比較圖像的一種方法https://stackoverflow.com/questions/6499491/comparing-two-histograms。 OpenCV可以提供更復雜的方式來比較圖像https://stackoverflow.com/questions/11541154/checking-images-for-similarity-with-opencv –