局部敏感哈希或pHash?

时间:2016-05-09 08:23:05

标签: c++ hash locality-sensitive-hash phash

我正在尝试实现一般指纹memoizator:我们有一个可以通过智能指纹表达的文件(如用于图像的pHash或用于音频的chromaprint)以及我们的需求(昂贵) )函数已经在类似的文件上计算,然后我们返回相同的结果(避免昂贵的计算)。

Locality Sensitive Hash(LSH)是昂贵的多维空间中Approximate nearest neighbor问题的流行且高效的解决方案。

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

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

所以我想知道如何为pHash哈希值实现单维LSH?或者用几句话说:我们如何在箱子中分组相似的pHash值?它可以替代经典的LSH方法(如果不是为什么)?

1 个答案:

答案 0 :(得分:1)

您可以使用n random projections将pHash空间分割为2^n个存储桶,然后很可能会从同一个存储桶中找到类似的图像。您甚至可以使用汉明权重1的所有64个可能的整数对哈希进行异或运算,以方便地检查相邻的桶,并确保找到所有近似匹配。

仅当您对具有几乎相同的哈希(小汉明距离)的图像感兴趣时,这才有效。如果你想要容忍更大的汉明距离(例如8),那么有效和准确地找到所有匹配变得棘手。我通过GPU scanning through获得了非常好的表现,即使是我3岁的笔记本电脑的GT 650M也可以检查7亿个哈希/秒!

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

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

现在通过计算64 x n得到A = (M * V) > 0矩阵(一个图像/行,一个投影/列)。接下来将每行的二进制表示转换为数字,得到m x n个不同的可能性,类似的哈希最有可能结束到同一个桶。

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

我建议XORring,因为如果图像没有相同的哈希值,那么它们不能保证在同一个桶中结束。通过检查原始哈希的所有可能的小偏差,您可以看到哪些其他分箱可能匹配。

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