相似图像搜索

虽然已经是神经网络的时代了,但现在主流的基于图像内容(以图搜图)的搜索算法,依然是哈希值比较。具体而言,这种算法要满足两个条件。第一,是将图片映射到一个定长的字节空间(如64位)。第二,这种转换能够用Hamming距离来描述相似度。所谓Hamming距离是指:两个相同长度的比特串S1和S2,S1通过替换比特位变成S2所需要次数。等价于两个比特串异或后1的数量。可见,每张图片都经过一次计算就能形成一个唯一的指纹,这个指纹不依赖于其他图片,且可用于后续与其他图片生成的指纹进行高效率的比较。

在Github上有一个关于图像哈希计算的项目imagehash。这个库实现了多种算法,如average hashing,perception hashing,difference hashing,wavelet hashing等。 这篇文章详细演示了该库的用途。

我比较关注的是wavelet hashing。它调用了PyWavelets库,默认采用基于Haar wavelet(哈尔小波)分析的哈希算法。Haar wavelet是信号分析学中的一种向量变换算法,常用于目标检测或信号压缩。尚记得当年老牌图站Danbooru曾使用的内部相似图像搜索引擎iqdb,也是使用的Haar wavelet变换法。使用下来搜索效果确实不错。现在终于有了封装好的Python库可以直接集成到自己的应用里了。

安装方法:pip install imagehash

使用wavelet hashing来给图像生成哈希到相似度比较非常简单:


from PIL import Image
import imagehash
hash1=imagehash.whash(Image.open('1.jpg'),hash_size=64,remove_max_haar_ll=True) #各参数意义可见函数的__doc__
hash2=imagehash.whash(Image.open('2.jpg'),hash_size=64,remove_max_haar_ll=True)
print (float(hash1-hash2)/len(hash1.hash)**2) #相似度计算。其中减号已被重载。