1

我有一个数据库,其中包含大量图像(数百万)和我需要比较的那些图像(由libpuzzle生成)的内容签名。

我已经运行了许多不同的替代方案来尝试提高效率,包括各种搜索算法(目前运行速度最快的levenshtein 差异)和各种数据点作为预过滤器(将比较减少到只有几千个批次图像),但我尝试过的一切仍然会减慢生产使用的速度。我每天添加数千张图片,与完整收藏中的其他所有图片相比,它们需要有自己的签名。

我使用的两种主要存储方法是 CouchDb 和 MySql,它们都需要 10 多个 gig 的数据存储,并且在几百万条记录之后 MySql 运行速度太慢(即使有结果缓存和索引键大小变化,索引使用类似于这种方法的方法太大但仍然很慢),并且在 Couch 上它似乎无法处理大型索引。我还考虑过像 Amazon SimpleDB 这样可以解决存储问题的服务,但考虑到如此大的索引的内存需求,我预计会非常昂贵,而且可能不会比 Couch 好。

表结构很简单:

ImageId int(11),
Signature VARCHAR(1020) //implemented as text

期望的结果应该是给定 ImageId 的 ImageId(s) 列表。一个简单的自连接(ON 比较函数)太慢了。

我的实现是比较现有图像,并不断将新图像与现有基础进行比较,以实现这两个目标...... 1)识别相同或非常接近相同的图像(包括调整大小、裁剪和微小的颜色变化, 2) 识别相似图像以帮助可能对相似视觉内容的图像感兴趣的图像搜索。libpuzzle 库提供了一个可用于两者的分数(我对前者使用 >95%,对后者使用 >80%)。

基本上我的问题是,有没有人知道
a)不同的数据存储平台
b)使用MySql的技术
c)或其他一些(可能是自定义的)方法
可以用来线性比较大量的二进制数据,在一个非常有效的方法?

4

1 回答 1

1

您链接的“优秀方法”实际上是答案,但它有一个主要问题:它不应该在 MySQL 中完成,这对于那种搜索来说很糟糕,但在 Solr 或 Sphinx 中是专门为那。

因为我知道 Solr,所以你可以这样做:

使用具有恒定长度(最大 ngram 长度 = 最小 ngram 长度)的 ngram 过滤器将索引签名标记为文本 - 这会将签名从链接的答案中拆分为“单词”(令牌)。

<fieldType 
   name="signatureNgrams" 
   stored="false" 
   class="solr.StrField"> 
 <analyzer type="index"> 
   <tokenizer 
       class="solr.analysis.NGramTokenizerFactory" 
       minGramSize="4" 
       maxGramSize="4" 
       /> 
   <filter class="solr.LowerCaseFilterFactory"/> 
 </analyzer> 
</fieldType>

使用http://wiki.apache.org/solr/DisMaxQParserPlugin#mm_.28Minimum_.27Should.27_Match.29定义最小相似度(必须匹配多少个 ngram)。

于 2012-07-29T01:23:47.553 回答