使用SOLR计算两个ulongs之间的“相似性”/“bitcount”

时间:2014-02-14 07:22:55

标签: c# solr bit-manipulation solrnet phash

我们有一个图像数据库,我使用Dr. Neal Krawetz's method实现的David Oftedal计算了PHASH。

部分示例代码计算这些长度之间的差异:

ulong hash1 = AverageHash(theImage);
ulong hash2 = AverageHash(theOtherImage);

uint BitCount(ulong theNumber)
{
    uint count = 0;
    for (; theNumber > 0; theNumber >>= 8) {
        count += bitCounts[(theNumber & 0xFF)];
    }
    return count;
}

Console.WriteLine("Similarity: " + ((64 - BitCount(hash1 ^ hash2)) * 100.0) / 64.0 + "%");

挑战在于我只知道其中一个哈希值,并且我想查询SOLR以找到相似顺序的其他哈希值。

一些注意事项:

  1. 在这里使用SOLR(只有我的选择是HBASE)
  2. 想避免在solr中安装任何自定义java(很高兴安装现有的插件)
  3. 很高兴在C#中进行大量预处理
  4. 很高兴使用多个字段将数据存储为位字符串,long等等
  5. 将SOLRNet用作客户端
  6. 编辑,一些额外的信息(道歉我陷入了问题并开始假设它是一个广为人知的领域)。这是直接下载到C#控制台/示例应用程序:http://01101001.net/Imghash.zip

    此控制台应用的示例输出为:

    004143737f7f7f7f phash-test-001.jpg
    0041417f7f7f7f7f phash-test-002.jpg
    相似度:95.3125%

1 个答案:

答案 0 :(得分:3)

你可以使用Solr's Fuzzy Search,你必须在页面上向下滚动一下。

  

Solr的标准查询解析器支持基于Levenshtein距离或编辑距离算法的模糊搜索。模糊搜索发现类似于指定术语的术语,而不一定是完全匹配。要执行模糊搜索,请在单个词的末尾使用波浪号〜符号。

假设您有一个如下所示的架构,此字段phash包含您已计算的相位。

<fields>
    <!-- ... all your other fields ... -->
    <field name="phash" type="string" indexed="true" stored="true" />
</fields>

您可以执行类似

的查询
q=phash:004143737f7f7f7f~0.8&
fl=score,phash

这将返回具有Levenshtein Distance or Edit Distance至少80%的PHASH的所有文档。您不会得到您在问题中给出的95.3125%,但是计算匹配/不匹配字符的87.5%。

如果要查看该值,可以执行以下查询

q=phash:004143737f7f7f7f~0.8&
fl=score,phash,strdist("0041417f7f7f7f7f", phash, edit)

这是function call to fetch the String Distance使用Levenstein或编辑距离,会提供类似于

的结果
+----------------+---------------------------------------+
|hash            |strdist("0041417f7f7f7f7f", hash, edit)|
+----------------+---------------------------------------+
|0041417f7f7f7f7f|1.0                                    |
+----------------+---------------------------------------+
|004143737f7f7f7f|0.875                                  |
+----------------+---------------------------------------+

当你想减少95.3125%87,5%之间的差距时,你应该考虑将PHASH存储为不是十六进制值,而是以八进制存储。