我目前正在扩展用于对图像进行分类的图像库,我想查找重复的图像,转换后的图像以及包含或包含在其他图像中的图像。 我已经测试了OpenCV的SIFT实施,并且效果很好,但是对于多个图像来说速度会很慢。太快了,我想我可以提取功能并将它们保存在数据库中,因为许多其他与图像相关的元数据已经保存在那里。
将新映像的功能与数据库中的功能进行比较的最快方法是什么? 通常,比较是使用kd-tree,FLANN或与我在SO上的另一个线程中找到的“ 金字塔匹配内核”来计算欧几里德距离的,但尚未深入研究。
由于我不知道有效地在数据库中保存和搜索kd树的方法,因此我目前只看到三个选项: 尽管我确定,但让MySQL计算到数据库中每个功能的欧式距离这将花费不合理的时间来获取多个图像。 在开始时将整个数据集加载到内存中并构建kd-tree。这可能很快,但是占用大量内存。另外,所有数据都需要从数据库中传输。 *将生成的树保存到数据库中并全部加载它们,这将是最快的方法,但也会产生大量的流量,因为必须重新构建kd树并将其发送到服务器的新映像。
我正在使用OpenCV的SIFT实现,但是我还没有死定。如果有一个特征提取器更适合此任务(并且大致同样健壮),我很高兴有人提出建议。
因此,我基本上在几年前做了类似的事情。 您想研究的算法是戴维·尼斯特(David Nister)于几年前提出的,论文是:“词汇树的可伸缩识别”。 他们几乎为您的问题提供了精确的解决方案,可以扩展到数百万张图像。
这是摘要的链接,您可以通过谷歌标题找到下载链接。 http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=1641018
基本思想是用分层k均值算法构建一棵树以对特征建模,然后利用该树中稀疏的特征分布来快速找到您最近的邻居…或类似的东西,从那以后已经有好几年了我做了。您可以在以下作者网页上找到PowerPoint演示文稿:http : //www.vis.uky.edu/~dnister/Publications/publications.html
其他一些注意事项:
我不会为金字塔匹配内核感到烦恼,与复制/转换图像检测相比,它实际上更多地用于改进对象识别。
我不会在SQL数据库中存储任何此功能。视您的应用程序而定,动态计算功能 有时会 更有效,因为密集计算时,它们的大小可能会超过原始图像的大小。特征的直方图或词汇树中的节点的指针更为有效。
SQL数据库不适用于进行大量的浮点向量计算。 您可以将事物存储在数据库中,但不要将其用作计算工具。 我曾经用SQLite尝试过一次,结果非常糟糕。
如果您决定实施此方法,请仔细阅读本文并在实施时随手准备一份副本,因为其中有许多次要细节对于使算法有效工作非常重要。