【问题标题】:Comparing SIFT features stored in a mysql database比较存储在 mysql 数据库中的 SIFT 特征
【发布时间】:2011-03-31 03:49:05
【问题描述】:

我目前正在扩展一个用于对图像进行分类的图像库,我想查找重复图像、转换后的图像以及包含或包含在其他图像中的图像。
我已经测试了 OpenCV 的 SIFT 实现,它工作得很好,但对于多个图像来说会相当慢。太快了,我想我可以提取特征并将它们保存在数据库中,因为许多其他与图像相关的元数据已经保存在那里。

将新图像的特征与数据库中的特征进行比较的最快方法是什么?
通常比较是使用 kd-trees、FLANN 或 Pyramid Match Kernel 来计算欧几里得距离,我在 SO 上的另一个线程中找到了,但还没有深入研究。

由于我不知道如何在数据库中有效地保存和搜索 kd-tree,因此我目前只看到三个选项:
* 让 MySQL 计算到数据库中每个特征的欧几里得距离,尽管我确信这将花费不合理的时间来处理多个图像。
* 在开始时将整个数据集加载到内存中并构建 kd-tree(s)。这可能会很快,但非常占用内存。此外,所有数据都需要从数据库中传输。
* 将生成的树保存到数据库中并加载所有树,这将是最快的方法,但也会产生大量流量,因为对于新图像,kd 树必须重新构建并发送到服务器。

我正在使用 OpenCV 的 SIFT 实现,但我并没有死心塌地。如果有更适合这项任务的特征提取器(并且大致同样强大),我很高兴有人能推荐一个。

【问题讨论】:

  • OpenCV 已经包含一个 SURF 实现以及用于匹配的 Kd-Trees(不再需要 SIFT)。并且:这与您的问题没有直接关系,但您可能需要首先考虑匹配直方图(或其他全局特征)。通过这种方式,您可以通过预先消除具有非常不同直方图的所有候选对象来大幅减少与缓慢的高维特征进行比较的图像对数量。

标签: c++ database algorithm computer-vision sift


【解决方案1】:

所以几年前我基本上做了一些与此非常相似的事情。 您要研究的算法是几年前由 David Nister 提出的,论文是:“Scalable Recognition with a Vocabulary Tree”。他们几乎可以为您的问题提供精确的解决方案,可以扩展到数百万张图像。

这是摘要的链接,您可以通过谷歌搜索标题找到下载链接。 http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=1641018

基本思想是使用分层 k-means 算法构建一棵树来对特征进行建模,然后利用该树中特征的稀疏分布来快速找到您最近的邻居......或者类似的东西,这是一个几年后我开始工作了。您可以在此处的作者网页上找到PowerPoint演示文稿:http://www.vis.uky.edu/~dnister/Publications/publications.html

其他几点说明:

  • 我不会为金字塔匹配内核而烦恼,它实际上更多的是用于改进对象识别,而不是重复/转换图像检测。

  • 我不会在 SQL 数据库中存储任何此功能的东西。根据您的应用程序,动态计算特征有时会更有效,因为在密集计算时它们的大小可能会超过原始图像大小。特征直方图或词汇树中节点的指针更有效。

  • SQL 数据库不是为进行大规模浮点向量计算而设计的。 您可以将数据存储在数据库中,但不要将其用作计算工具。我用 SQLite 尝试过一次,结果非常糟糕。

  • 如果您决定实现这一点,请详细阅读论文并在实现时保留一份副本,因为有许多小细节对于使算法有效工作非常重要。

    李>

【讨论】:

  • 这看起来非常符合我的要求。谢谢!我知道 SQL 数据库不是最佳选择,您会选择哪种存储方法?天真的“尽可能多地获取内存允许(从数据库或文件),计算,获取下一个”似乎有点粗略。尽管它看起来会受益于 GPU 计算提供的大规模并行化,而这反过来又需要这种类型的数据管理。我猜我必须要知道。
  • 如果你实现了HK-means树的方法,你应该可以一次把整棵树装进内存(如果不能,买更多的内存)。然后,如果需要,您可以将树的叶子存储在磁盘上。
  • 有人实现了这个解决方案?
  • @William 很多人已经实现了这个解决方案
【解决方案2】:

我认为,关键在于这不是一个 SIFT 问题。这是一个关于近似最近邻搜索的问题。就像图像匹配一样,这也是一个开放的研究问题。您可以尝试使用谷歌搜索“近似最近邻搜索”并查看可用的方法类型。如果您需要精确的结果,请尝试:“精确最近邻搜索”。

所有这些几何数据结构(例如 kd-trees)的性能会随着维数的增加而降低,所以我认为关键是您可能需要以较少的维数(比如 10 -30 而不是 256-1024)进行真正有效的最近邻搜索(例如使用 PCA)。

一旦你有了这个,我认为无论数据是否存储在 MySQL 中,它都会成为次要的。

【讨论】:

  • 我知道如何比较功能。我正在寻找一种方法来利用数据库的力量来比我概述的 3 个幼稚的想法更有效地完成它。我还没有找到任何满足(关系)数据库的特殊要求和优势的搜索算法。
  • 你的问题听起来更像是:因为我已经使用了一个数据库,所以我决定把描述符也放在那里——我怎样才能做到这一点。更简洁地说,我的回答是,我认为您不会找到任何能够满足关系数据库优势的算法。空间数据库在 2 维或 3 维(查找 GIS)中都是实用的。不了解更高维度(比如高于 5)的几何方面。
【解决方案3】:

我认为速度不是这里的主要问题。主要问题是如何使用这些功能来获得您想要的结果。

如果你想对图像进行分类(例如人、车、房子、猫),那么 Pyramid Match 内核绝对值得一看。它实际上是局部特征描述符的直方图,因此无需将各个特征相互比较。还有一类算法被称为“词袋”,它试图将局部特征聚类,形成“视觉词汇表”。同样,在这种情况下,一旦有了“视觉词”,您就不需要计算所有 SIFT 描述符对之间的距离,而是确定每个特征属于哪个集群。另一方面,如果您想获得图像对之间的点对应关系,例如确定一个图像是否包含在另一个图像中,或者计算图像之间的变换,那么您确实需要找到确切的最近邻。

此外,还有 SIFT 以外的本地特征。例如,SURF 是类似于 SIFT 的特征,但提取速度更快,并且已被证明在某些任务中表现更好。

如果您只想查找重复项,则可以通过使用全局图像描述符(例如颜色直方图)来删除明显不同的图像,从而大大加快搜索速度。比较两个颜色直方图比比较两个包含数百个 SIFT 特征的集合快几个数量级。您可以使用颜色直方图创建一个简短的候选列表,然后使用 SIFT 优化您的搜索。

【讨论】:

  • Pyramid Kernel 看起来确实很有趣,因为它聚合了更多的数据,因此需要搜索的内容更少。然而,我的主要目标不是对象识别或分类,而是找到已显着转换的重复项,因此不幸的是,简单的直方图匹配是不够的。
  • 当然,在你的情况下,直方图匹配是不够的。但这将允许您快速拒绝大部分非重复项。将其视为一个两阶段过程:如果颜色直方图匹配,则仅尝试匹配 SIFT 特征。
【解决方案4】:

我有一些 Python 工具,你可以用 here 来玩。基本上它是一个使用 SIFT 变换向量的包,然后计算每个 128d 筛选向量的最近格散列。散列是重要的部分,因为它是局部敏感的,这意味着在 R^n 空间中靠近的向量会导致等效的散列冲突概率。我提供的工作是Andoni 的扩展,它提供了用于修剪 LSH 精确搜索列表的查询自适应启发式,以及散列函数的优化 CUDA 实现。我还有一个小应用程序,它可以在 bsd 下进行图像数据库搜索,并提供很好的视觉反馈(SIFT 例外,它有一些额外的限制)。

【讨论】:

    猜你喜欢
    • 2010-11-26
    • 2011-10-08
    • 2021-11-25
    • 2022-12-25
    • 2016-12-12
    • 2014-05-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    相关资源
    最近更新 更多