利用感知圖像雜湊 進行相似圖片檢測。本文採用 差值雜湊 (dHash) 演算法,建立圖片指紋資料庫,實現以圖搜圖功能。適用於濫用圖片攔截、重複圖片去重、反向圖片搜尋等場景。
pip install pillow imagehash
# 自動安裝 numpy/scipy 依賴
# index.py
from PIL import Image
import imagehash, argparse, shelve, glob
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True, help="輸入圖片資料夾")
ap.add_argument("-s", "--shelve", required=True, help="輸出 shelve 資料庫")
args = vars(ap.parse_args())
db = shelve.open(args["shelve"], writeback=True)
for path in glob.glob(args["dataset"] + "/*.jpg"):
img = Image.open(path)
h = str(imagehash.dhash(img))
fname = path[path.rfind("/") + 1:]
db[h] = db.get(h, []) + [fname] # 同雜湊可能多檔
db.close()
python index.py --dataset images --shelve db.shelve
# search.py
from PIL import Image
import imagehash, argparse, shelve
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True)
ap.add_argument("-s", "--shelve", required=True)
ap.add_argument("-q", "--query", required=True, help="查詢圖片路徑")
args = vars(ap.parse_args())
db = shelve.open(args["shelve"])
query_img = Image.open(args["query"])
h = str(imagehash.dhash(query_img))
filenames = db.get(h, [])
print("Found {} images".format(len(filenames)))
for fname in filenames:
Image.open(args["dataset"] + "/" + fname).show()
db.close()
python search.py --dataset images --shelve db.shelve --query images/test.jpg
從 Caltech-101 隨機抽 17 張圖,各產生 N 張縮放變體。查詢任一變體,皆能精準找出同組其他變體,即使解析度不同、長寬比微調。