比较存储在mysql数据库中的SIFT功能

时间:2010-08-17 18:27:08

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

我正在扩展用于分类图像的图像库,我想找到包含或包含在其他图像中的重复图像,变换图像和图像。
我已经测试了OpenCV的SIFT实现,它运行得很好,但对于多个图像来说速度相当慢。太快了我以为我可以提取功能并将它们保存在数据库中,因为很多其他与图像相关的元数据已经被保存在那里。

将新图像的功能与数据库中的功能进行比较的最快方法是什么?
通常比较是使用kd-trees,FLANN或我在SO上的另一个线程中找到的Pyramid Match Kernel来计算欧氏距离,但还没看好。

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

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

4 个答案:

答案 0 :(得分:14)

所以几年前我基本上做了类似的事情。 几年前David Nister提出了你想要研究的算法,论文是:“用词汇树进行可扩展识别”。它们几乎可以解决您的问题,可以扩展到数百万张图像。

以下是摘要的链接,您可以通过googleing标题找到下载链接。 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一次,结果非常糟糕。

  • 如果您决定实施此功能,请详细阅读本文并在实施时方便地保留副本,因为有许多细微的细节对于使算法有效运行非常重要。

答案 1 :(得分:2)

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

所有这些几何数据结构(例如kd树)的性能随着维数的增加而降低,因此我认为关键是您可能需要以较低的维数表示您的SIFT描述符(例如10) -30而不是256-1024)有真正有效的最近邻搜索(例如使用PCA)。

如果你有这个,我认为如果数据存储在MySQL中,它将成为次要的。

答案 2 :(得分:1)

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

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

此外,还有SIFT以外的本地功能。例如,SURF是与SIFT类似的功能,但它们的提取速度更快,并且已经证明它们对于某些任务表现更好。

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

答案 3 :(得分:1)

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