我们使用libpuzzle(http://www.pureftpd.org/project/libpuzzle/doc)来比较400万张图像的相似性。
效果很好。
而是使用libpuzzle函数进行图像与图像比较,还有另一种比较图像的方法。
以下是一些快速背景资料:
Libpuzzle为任何给定图像创建了一个相当小的(544字节)散列。这个哈希可以反过来用于使用libpuzzles函数与其他哈希进行比较。有一些API ... PHP,C等...我们正在使用PHP API。
比较图像的另一种方法是从给定的哈希创建向量,这里是来自文档的粘贴:
用固定长度的单词剪切矢量。例如,让我们考虑一下 以下向量:
[a b c d e f g h i j k l m n o p q r s t u v w x y z]
如果字长(K)为10,您可以获得以下字词:
在位置0找到[a b c d e f g h i j] 在位置1找到[b c d e f g h i j k] [c d e f g h i j k l]在第2位找到 等到位置N-1
然后,使用复合索引(单词+位置)索引矢量。
即使有数百万张图像,K = 10且N = 100也足够了 有很少的条目共享相同的索引。
所以,我们有矢量方法工作。它实际上比图像与图像比较好一点,因为当我们进行图像与图像比较时,我们使用其他数据来减少我们的样本量。它与我们用来减少样本大小的其他数据有点无关和应用特定,但是使用矢量方法......我们不必这样做,我们可以对每个400万个哈希中的每一个进行真正的测试
我们遇到的问题如下:
每个图像有400万个图像,每个图像100个,这就变成了4亿行。我们发现在大约60000张图像(60000 x 100 = 600万行)之后,MySQL往往会窒息。
我们使用的查询如下:
SELECT isw.itemid, COUNT(isw.word) as strength
FROM vectors isw
JOIN vectors isw_search ON isw.word = isw_search.word
WHERE isw_search.itemid = {ITEM ID TO COMPARE AGAINST ALL OTHER ENTRIES}
GROUP BY isw.itemid;
如上所述,即使使用适当的索引,当涉及到4亿行时,上述情况也相当缓慢。
那么,有人可以建议任何其他技术/算法来测试这些相似性吗?
我们愿意提供任何帮助。
值得一提的是:
我们能够提出的最好的是:
我们还没有尝试过上述内容,但这可能会比使用mysql查询产生更好的结果。
有什么想法吗?如上所述,我们愿意安装任何新服务(postgresql?hadoop?)。
最后的注释,问题Libpuzzle Indexing millions of pictures?中可以找到这个向量+比较方法的确切工作原理。我们实际上使用的是Jason提供的确切方法(目前是最后一个答案,获得了200多个积分)。
答案 0 :(得分:0)
不要在数据库中执行此操作,只需使用简单文件即可。下面我展示了一个文件,其中包含两个矢量[abcdefghijklmnopqrst]
(图片1)和[xxcdefghijklxxxxxxxx]
(图片2)
<index> <image>
0abcdefghij 1
1bcdefghijk 1
2cdefghijkl 1
3defghijklm 1
4efghijklmn 1
...
...
0xxcdefghij 2
1xcdefghijk 2
2cdefghijkl 2
3defghijklx 2
4efghijklxx 2
...
现在对文件进行排序:
<index> <image>
0abcdefghij 1
0xxcdefghij 2
1bcdefghijk 1
1xcdefghijk 2
2cdefghijkl 1
2cdefghijkl 2 <= the index is repeated, those we have a match
3defghijklm 1
3defghijklx 2
4efghijklmn 1
4efghijklxx 2
文件排序后,很容易找到具有相同索引的记录。编写一个小程序或可以在排序列表中运行的东西,找到重复项。
答案 1 :(得分:0)
我选择“回答我自己的”问题,因为我们找到了一个效果很好的解决方案。
在最初的问题中,我提到我们正在考虑通过狮身人面像搜索来做到这一点。
好吧,我们继续做了,结果比通过mysql做的更好。
所以,实质上这个过程看起来像这样:
a)从图像生成哈希。
b)将此哈希“矢量化”为100个部分。
c)binhex(二进制到十六进制)这些向量中的每一个,因为它们是二进制格式。d)以如下方式存储在sphinx搜索中:
itemid | 0_vector0 1_vector1 2_vec ... etc
e)使用sphinx搜索进行搜索。
最初......一旦我们拥有这个充满400万条记录的sphinxbase,每次搜索仍需要大约1秒。
然后我们在8个内核上为此sphinxbase启用了分布式索引,现在即将查询每秒大约10次以上的搜索。这对我们来说已经足够了。
最后一步是在我们拥有的多个服务器上进一步分发这个sphinxbase,进一步利用我们现有的未使用的cpu周期。
但暂时还不错。我们每天添加大约1000-2000个“项目”,因此在我们进行初始扫描之后,搜索“只是新项目”将很快发生。