C++/SIFT/SQL - 如果有办法有效地将图像的 SIFT 描述符与 SQL 数据库中的 SIFT 描述符进行比较?

Posted

技术标签:

【中文标题】C++/SIFT/SQL - 如果有办法有效地将图像的 SIFT 描述符与 SQL 数据库中的 SIFT 描述符进行比较?【英文标题】:C++/SIFT/SQL - If there a way to compare efficiently a SIFT descriptor of an image with a SIFT descriptor in a SQL database? 【发布时间】:2014-08-04 13:58:41 【问题描述】:

我想找到一种方法,可以将图像(查询)的 SIFT 描述符与 SQL 数据库中的描述符进行比较,该数据库包含许多不同图片的描述符。

事实上,我的最终目的是做一个应用程序,它允许将一张图片与数据库(不是我的设备中)但在 SQL 数据库中的大量图片进行比较。

我想到的第一件事是将每个描述符存储在 SQL 数据库中,并使用蛮力方法或 FlanneBased 方法将每个描述符与另一个描述符进行比较。问题是,在 SQL 数据库中,由于匹配背后的“数学”(例如欧几里得距离是 sqrt(a²+b² +...) ),计算匹配需要很长时间,这是不可能的在庞大的数据库中进行这种比较。

例如,如果我没记错的话,一个 SIFT 描述符包含 128 个数字,所以想象一下将每个描述符的每个数字比较在一起的时间。

如果还有其他方法可以做到这一点?我知道在 SQL 数据库中,当您使用“SELECT a FROM b WHERE ...”之类的内容时,请求会很有效

因此我想知道是否有一种方法可以有效地存储 SIFT 描述符?例如,我考虑将描述符“加密”成一种大字符串链,每个链都是唯一的,因此我可以将它们一起比较,但我不知道这是否是一个好的解决方案。

我已经阅读了这篇文章:Comparing SIFT features stored in a mysql database,但这对我没有帮助。 谢谢。

【问题讨论】:

Comparing SIFT features stored in a mysql database的可能重复 尝试本地敏感哈希:ceremade.dauphine.fr/~cohen/mypapers/auclairAMR07.pdf 或其他哈希方法 看看这个:***.com/questions/5751114/… Marol,是的,我看到了这篇文章,但对我没有帮助。关于论文,我会读的。散列允许做我想做的事? 【参考方案1】:

如果我是你,我更愿意在代码中比较描述符,而不是在 SQL 中。 SQL 不是为此而设计的。我会做以下事情:-

1. Pre-load N descriptors from SQL onto memory.
2. Compare distances to query descriptor, descriptor by descriptor.
3. If distance<threshold, push to possiblematches.
4. When you reach N/2 descriptors, push the next N.
5. Compare all matches, choose the best one or the best D descriptors, as per your requirement.

但是,为此,我宁愿使用 OpenCV 的内置 FileStorage 类,它为 XML 和 YAML 文件提供 I/O;它解决了手动解析描述符值的麻烦。

【讨论】:

快吗?因为我在做一个应用程序,我想以更快的方式比较服务器中的图片,而不是“设备”内部的图片。例如,我拍照,计算它的描述符,然后,我从 SQL 预加载描述符?就这样? 速度取决于数据库中描述符的数量。然而,OpenCV 也有不同的近似距离度量,例如 FLANN(它比仅仅计算欧几里得距离更快)。如果您对在服务器上运行它非常特别,您可以编写一个简单的 php 脚本来做同样的事情。因为你只是在计算距离,所以这不是很困难 好吧。如果我按照你的算法,我不理解这部分”但是,为此,我宁愿使用 OpenCV 的内置 FileStorage 类,它为 XML 和 YAML 文件提供 I/O;它解决了手动解析描述符值的麻烦” 。为什么我需要一个 xml 文件?对不起,我有点困惑。 那是在我意识到你想在服务器上运行它之前。如果您想将数据推送到服务器,那么 SQL 可能是最佳选择(因为它几乎可以自动处理速度/安全性等)。 OpenCV 的文件存储模块 (docs.opencv.org/modules/core/doc/xml_yaml_persistence.html) 提供了一种持久保存 OpenCV 结构的简单方法。【参考方案2】:

使用 SQL 数据库来比较 SIFT 并不是最优的。 OpenCV 提出了更高效的some keypoint matchers。您可以在 ./samples/cpp/matcher_simple.cpp 中找到一个带有 SURF 描述符的示例,该示例很容易适应 SIFT。基本上,核心是

BFMatcher matcher(NORM_L2);
vector<DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);

据我所知,一些匹配器(例如 Flann)仅适用于特定类型的描述符(CV_32F)。

【讨论】:

谢谢,但我知道如何进行匹配!实际上我做了一个应用程序,我需要计算与服务器而不是在设备内部的匹配,你知道吗? 可以在服务器内部进行匹配,这是最高效的方法。以lear.inrialpes.fr/pubs/2008/JDS08/jegou_hewgc08.pdf 为例。对于一个非常大的数据库,将 SIFT 聚合到一个 VLAD 中,压缩它们并在压缩域中使用不对称搜索:hal.inria.fr/inria-00633013/PDF/jegou_aggregate.pdf。对于一般大小的数据库,您可以使用包含大量词汇的倒排索引(然后使用您的 SQL 数据库来实现倒排索引):robots.ox.ac.uk/~vgg/publications/2007/Philbin07/philbin07.pdf。 谢谢!哇,对于初学者来说,这似乎很困难,但我会阅读这些论文并尝试理解。但是现在我做了很多研究,我不知道在你的方法(论文)之间哪种方式更有效,并对我的描述符进行哈希处理,然后比较它们。 这些论文确实很有技术含量。对于您的情况,如果“很多图片”是指无论如何少于 100,000,我会说您可以查看(Philbin 等人,2007 年的方法)。在这种情况下,让我们将其视为带有词袋的经典倒排索引,但用 SIFT 替换词(因此使用 flann L2 距离将图像的描述符与码本匹配)。 我已经用 SIFT 描述符实现了 BoW,它对 BoW 的“问题”是,我必须用大量的课程来训练它(在我的情况下是 100 多),这需要很多时间所以我认为这不是一个好的解决方案,这就是为什么我改变了处理方式,也就是说计算描述符并将它们存储在数据库中,方法是散列描述符(效率问题),然后使用查询,做同样的事情以将其与数据库进行比较。是的,我的意思是少于 100 000 我认为。但根据this post 我不能做哈希..

以上是关于C++/SIFT/SQL - 如果有办法有效地将图像的 SIFT 描述符与 SQL 数据库中的 SIFT 描述符进行比较?的主要内容,如果未能解决你的问题,请参考以下文章

如何有效地将数据附加到 C 中的 HDF5 表?

如何有效地将数据插入索引丰富的 oracle db?

在R中有效地将反斜杠转换为正斜杠

如何有效地将具有一定周期性的列表拆分为多个列表?

有效地将聚合列激发到 Set

pandas 有效地将 DataFrames 与不匹配的分类列和 MultiIndex 级别连接起来