【问题标题】:Using SOLR to calculate "similarity"/"bitcount" between two ulongs使用 SOLR 计算两个 ulong 之间的“相似度”/“bitcount”
【发布时间】:2014-03-13 10:47:52
【问题描述】:

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

部分示例代码计算这些 long 之间的差异在这里:

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. 希望避免将任何自定义 java 安装到 solr(很高兴安装现有插件)
  3. 很高兴在 C# 中进行大量预处理
  4. 乐于使用多个字段将数据存储为位串、长等
  5. 使用 SOLRNet 作为客户端

编辑,一些额外的信息(抱歉,我陷入了这个问题并开始假设它是一个广为人知的领域)。这是直接下载到 C# 控制台/示例应用程序:http://01101001.net/Imghash.zip

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

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

【问题讨论】:

    标签: c# solr bit-manipulation solrnet phash


    【解决方案1】:

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

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

    假设您有如下架构,其中 phash 字段包含您计算的 phash。

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

    您可以执行类似的查询

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

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

    当您想查看该值时,您可以执行以下查询

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

    这是一个使用 Levenstein 或 Edit 距离的function call to fetch the String Distance,将提供类似于

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

    当您想缩小95.3125%87,5% 之间的差距时,您应该考虑将PHASH 存储为例如八进制而不是十六进制值。

    【讨论】:

    • 感谢@cheffe - 我现在将对此进行测试,以比八位字节进一步改进 strdist 是否有意义使用如下所示的单个位字符串:0000000001000001010000110111001101111111011111110111111101111111,我试图得到尽可能像示例一样的位数。 (虽然我很高兴 SOLR 让我完成了 90% 的工作并在 C# 中完成了剩下的工作)
    • 感谢您的回答 - 仅供参考,上述方法与位计数算法完全匹配。
    猜你喜欢
    • 2017-08-22
    • 2012-03-11
    • 2018-08-09
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多