類似画像検索について、いくつか。
BMBハッシュ((PDF) Block Mean Value Based Image Perceptual Hashing | Bian Yang - Academia.edu)。概要を知覚ハッシュによる類似画像検索(PDF)から引用しておく。
- 対象となる画像をグレースケール化し、あらかじめ決められた大きさに正規化する。
- ハッシュの長さをNと決める。画像を重複しない N 個のブロックに分ける。
- 分けたブロックごとに画素値の平均値を計算する。平均値の集合から中央値を計算する。
- ハッシュの値を以下のように決める。
ブロックサイズを1x1、中央値の代わりに平均値を使えば「Average Hash」と同等のものになる(はず)。
Average HashについてはLooks Like It - The Hacker Factor Blogを参照。
以下、コード。ハッシュ長は144(=12x12)にした。
画像データはCaltech101から。カテゴリーが101個あるが、そのうちBACKGROUND_Googleは外してある。
import numpy as np import cv2 import glob def hdiff(a, b): return (a != b).astype('int').sum() # astype()はなくても可、好みで def mk_hash(img, size=12): size2 = size*size img = cv2.resize(img, (size2, size2)) s = [np.mean(img[i:i+size, j:j+size]) for i in range(0, size2, size) for j in range(0, size2, size)] s = np.array(s) m = np.median(s) return (s >= m) q_img = cv2.imread("101_ObjectCategories/airplanes/image_0001.jpg", 0) q_hash = mk_hash(q_img) for file in sorted(glob.glob("101_ObjectCategories/*/*.jpg")): t_img = cv2.imread(file, 0) t_hash = mk_hash(t_img) d = hdiff(q_hash, t_hash) print(file, d)
クエリーも含めた上位10件を載せておく。
画像 | 距離 |
---|---|
airplanes/image_0001.jpg | 0 |
airplanes/image_0115.jpg | 10 |
Motorbikes/image_0149.jpg | 12 |
airplanes/image_0019.jpg | 12 |
airplanes/image_0086.jpg | 12 |
airplanes/image_0244.jpg | 12 |
airplanes/image_0010.jpg | 14 |
airplanes/image_0046.jpg | 14 |
airplanes/image_0067.jpg | 14 |
airplanes/image_0082.jpg | 14 |