位置敏感哈希或pHash

Locality Sensitive Hash or pHash?

本文关键字:pHash 哈希 位置      更新时间:2023-10-16

我正在尝试实现一个通用的指纹存储器:我们有一个可以通过智能指纹表达的文件(比如图像的pHash或音频的chromacrint),如果我们的无序(昂贵)函数已经在类似的文件上计算过,那么我们会返回相同的结果(避免昂贵的计算)。

对于代价高昂的多维空间中的近似近邻问题,局部敏感哈希(LSH)是一种流行且性能良好的解决方案。

pHash是一个很好的库,可以实现图像的感知哈希。

因此,pHash将多维输入(图像)转换为一维对象(哈希码),这与LSH(同样是LSH中的多维对象)有所不同。

所以我想知道我们如何为pHash哈希值实现一维LSH?或者简单地说:我们如何在垃圾箱中对类似的pHash值进行分组?它能替代传统的LSH方法吗(如果不能,为什么)?

您可以使用n随机投影将pHash空间拆分为2^n桶,然后很可能在同一桶中找到相似的图像。您甚至可以将哈希与所有64个可能的Hamming权重为1的整数进行异或,以方便地检查相邻的桶,并确保找到所有近似匹配。

只有当你对具有几乎相同散列(小汉明距离)的图像感兴趣时,这才是有效的。如果你想容忍更大的hamming距离(比如8),那么要高效准确地找到所有匹配就很难了。通过GPU扫描整个表格,我获得了非常好的性能,即使是我3岁的笔记本电脑的GT 650M也能每秒检查7亿个哈希!

编辑1:您可以将64位哈希视为64维立方体上的单个角,如果将角坐标归一化为-11(这样它的中心在原点),则数学计算会更容易。您可以将m图像表示为大小为m x 64的矩阵M(一行/图像,一位散列/列)。

将其拆分为2^n不同组的最简单方法是生成n 64维向量v_0, v_1, ..., v_n(从正态分布N(0,1)中挑选每个向量元素),这可以表示为大小为64 x n的矩阵V(一列/向量)。可能存在随机投影中提到的正交性强制,但我将跳过这里。

现在通过计算A = (M * V) > 0得到m x n矩阵(一个图像/行,一个投影/列)。接下来,将每一行的二进制表示转换为一个数字,您将获得2^n不同的可能性,并且类似的散列最有可能最终到达同一个bucket。

该算法适用于数据的任何正交表示(如SURF特征),而不仅仅是二进制字符串。我相信有更简单(计算效率更高)的二进制哈希算法,但这是实现随机投影的一种方法。

我建议XOR,因为如果图像没有相同的散列,那么它们就不能保证最终会在同一个桶中。通过检查与原始哈希的所有可能的小偏差,您可以看到哪些其他bin可能用于可能的匹配。

在某种程度上,这类似于计算机游戏引擎将2D地图拆分为大小为x的单元格网格,然后要从一个点找到半径为x的所有单元,只需要检查9个单元格(包含该点的单元格+8个周围单元格)即可获得100%准确的答案。