【问题标题】:OpenCV / SURF How to generate a image hash / fingerprint / signature out of the descriptors?OpenCV / SURF 如何从描述符中生成图像哈希/指纹/签名?
【发布时间】:2011-01-09 22:22:52
【问题描述】:

这里有一些主题对如何找到相似的图片很有帮助。

我想做的是获取照片的指纹并在数码相机拍摄的不同照片上找到相同的照片。 SURF 算法似乎是独立于缩放、角度和其他失真的最佳方式。

我正在使用带有 SURF 算法的 OpenCV 来提取样本图像上的特征。现在我想知道如何将所有这些特征数据(位置、拉普拉斯、大小、方向、粗麻布)转换为指纹或散列。

此指纹将存储在数据库中,搜索查询必须能够将该指纹与具有几乎相同特征的照片的指纹进行比较。

更新:

似乎没有办法将所有描述符向量转换为简单的哈希。那么将图像描述符存储到数据库中以便快速查询的最佳方法是什么?

词汇树是一种选择吗?

如果能提供任何帮助,我将不胜感激。

【问题讨论】:

  • 代码执行所谓的“最近邻”匹配 - 获取描述符(大小为 N 的向量)并将其与一组其他大小为 N 的向量进行比较(这可以通过计算欧几里得距离它们之间或任何其他距离度量)并选择最接近的那个。名称中的朴素意味着该向量与所有其他向量进行比较。还有其他算法使用近似最近邻,虽然不太准确但效率更高
  • 为了简短起见 - 你不能用图像制作散列函数(这太不合时宜了,太冒昧了)。您可以参考文献了解最近邻分类或图像相似性度量。
  • 好的,存储任何查询图像描述符的最佳方式是什么?
  • 你所寻求的一切都包含在我的答案中,真的没有更多。
  • 非常感谢 Liza 的所有帮助!通过您的提示,我对这一切都变得更加清楚。

标签: opencv image-processing data-structures surf


【解决方案1】:

您提到的特征数据(位置、拉普拉斯、大小、方向、粗麻布)不足以满足您的目的(如果您想进行匹配,这些实际上是描述符中不太相关的部分)。您要查看的数据是“描述符”(第 4 个参数):

void cvExtractSURF(const CvArr* image, const CvArr* mask, CvSeq** keypoints, CvSeq** descriptors, CvMemStorage* storage, CvSURFParams params)

这些是 128 或 64 个(取决于参数)向量,其中包含特定特征的“指纹”(每个图像将包含可变数量的此类向量)。 如果您获得最新版本的 Opencv,他们有一个名为 find_obj.cpp 的示例,它向您展示了它是如何用于匹配的

更新

您可能会发现this 讨论很有帮助

【讨论】:

  • 嗨丽莎,感谢您的回复。我查看了该示例,但没有找到任何方法将存储在 CvSeq 中的描述符向量转换为哈希值,从而可以将其存储在数据库中并与其他哈希值进行比较。你对此有什么暗示吗?
  • CvSeq 只存储浮点数组(查看 cvExtractSURF 的源代码以了解它们是如何存储的)。这些数组(长度为 128 或 64)是你感兴趣的
  • 顺便说一句,如果你想要一些神奇的散列,例如将所有狗图像映射到相同的散列码,恐怕它比仅仅提取 SURF 特征更复杂。看看我在更新上放的链接
  • 不,我试图在照片中找到同一张照片。 OpenCV 示例适用于我所有的测试镜头。但是我仍然不知道如何将描述符转换为线性哈希值以使用汉明距离来计算相似度。
  • 丽莎,非常感谢您的帮助。你是对的,我正在寻找一个哈希指纹作为可以存储在关系数据库中的每个图像的数字字符串。比我想计算两个图像之间的汉明距离来检查图像是否几乎相同。我的问题是我不知道如何将描述符向量数据转换为这样的字符串 - 就像 pHash 库一样。
【解决方案2】:

计算哈希的简单方法如下。从图像中获取所有描述符(例如,其中 N 个)。每个描述符都是一个由 128 个数字组成的向量(您可以将它们转换为 0 到 255 之间的整数)。所以你有一组 N*128 整数。只需将它们一个接一个地写入一个字符串并将其用作哈希值。如果您希望哈希值很小,我相信有一些方法可以计算字符串的哈希函数,因此将描述符转换为字符串,然后使用该字符串的哈希值。

如果您想找到精确的重复项,这可能会起作用。但似乎(因为您谈论缩放、旋转等)您只想找到“相似”的图像。在这种情况下,使用哈希可能不是一个好方法。您可能会使用一些兴趣点检测器来查找计算 SURF 描述符的点。想象一下,它将返回相同的点集,但顺序不同。突然之间,即使图像和描述符相同,您的哈希值也会非常不同。

所以,如果我必须可靠地找到相似的图像,我会使用不同的方法。例如,我可以对 SURF 描述符进行矢量量化,构建矢量量化值的直方图,并使用直方图交集进行匹配。您真的必须使用哈希函数(也许是为了提高效率),还是只想使用任何方法来查找相似图像?

【讨论】:

  • 嗨,谢尔顿,感谢您的回复。在查看 SURF 之前,我正在使用 pHash 库。该库为媒体数据(图像、视频和音频)生成一个哈希值。你可以使用汉明距离很容易地查询类似图像哈希的数据库。我认为必须有一种方法可以以某种方式对 SURF 描述符做同样的事情。现在我正在考虑将所有序列化的图像描述符数组对象存储在数据库中。当我想在数据库中找到相似的图像时,我必须逐行选择并手动查找相似的描述符。 (...)
  • (续)对于大型图像数据库来说,最大的缺点是性能非常差。我想知道 TinEye.com 怎么能这么快找到类似的图像。必须有一些技巧可以非常快速地查询他们的数据库。
  • 我认为如果你告诉你到底想要达到什么目标会有所帮助。给定一张图片,你想找到什么?相同的图像、相似的图像、直到旋转/平移缩放的相似图像?给定图像 X,您是否只想找到与 X 相似的图像,或者您还想要包含 X 作为子部分的图像?例如,查询是人脸图像。您想查找其他人脸图像,还是包含人脸但还包含很多其他内容的全身照片?你为什么停止使用 pHash 而决定使用 SURF 描述符?
  • 我想要实现的是建立一个包含样本图像签名的数据库。然后我想打印出这些示例图像并用我的手机与它们合影。然后我试图将照片与数据库中的原始图像进行匹配。由于照片将具有不同的照明并且可能会略微失真,因此 pHash 将无法工作,因为该库对闪电和其他错误源的容忍度不够。 SURF 算法效果很好。我唯一的问题是以一种有效的方式将描述符存储在数据库中以便快速查询。
  • 丹,我也有同样的问题。您是否找到了实现这一目标的方法?谢谢
【解决方案3】:

似乎 GIST 可能更适合使用。

http://people.csail.mit.edu/torralba/code/spatialenvelope/ 有 MATLAB 代码。

【讨论】:

    【解决方案4】:

    Min-Hashmin-Hashing 是一种可能对您有所帮助的技术。它将整个图像编码为可调整大小的表示,然后存储在哈希表中。 Geometric min-HashingPartition min-HashBundle min-Hashing 等几种变体确实存在。由此产生的内存占用不是最小的之一,但这些技术适用于各种场景,例如近似重复检索甚至小对象检索——其他短签名通常表现不佳的场景。

    关于这个主题有几篇论文。入门文献将是: 近重复图像检测:min-Hash 和 tf-idf 加权 Ondrej Chum、James Philbin、Andrew Zisserman,BMVC 2008 PDF

    【讨论】:

      猜你喜欢
      • 2011-06-22
      • 1970-01-01
      • 2012-04-16
      • 1970-01-01
      • 2014-05-07
      • 1970-01-01
      • 1970-01-01
      • 2014-07-15
      • 2012-06-14
      相关资源
      最近更新 更多