我已经检查过像 Phasher 这样的方法来获得类似的图像。基本上将图像大小调整为 8x8,灰度,获取平均像素并创建每个像素的二进制哈希,比较它是高于还是低于平均像素。
这种方法在这里得到了很好的解释:
http://hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html
示例工作:
- table 上电脑的图像 1
- 图 2,相同,但有一枚硬币
这是可行的,因为使用非常简化的灰度图像的散列,它们几乎相同,甚至相同。因此,当 90% 以上的像素相同(在同一个地方!)
我的问题是从相同的角度但不同的角度拍摄的图像,例如这个:
在这种情况下,生成的哈希“指纹”彼此偏移,我们无法逐个比较哈希,它会非常不同。
像素是“相似的”,但它们不在同一个地方,因为在这种情况下有更多的天空,并且房屋比第一个“开始”在下方。
所以哈希比较导致“它们是不同的图像”。
可能的解决方案:
我正在考虑为第一个图像创建一个更大的哈希,然后为第二个图像获取 10 个随机“子哈希”,并尝试查看 10 个子哈希是否在第一个大哈希的“某个地方”(如果一个子字符串包含在另一个更大的字符串中)。
我认为这里的问题是处理数千张图像时的 CPU/时间,因为您必须将 1 个图像与 1000 个进行比较,并且在每个图像中,将 10 个子哈希与一个大的进行比较。
其他解决方案? ;-)
最佳答案
一种选择是为每个图像检测一组“有趣”的点并将其存储在您的散列旁边。它与您建议的解决方案有些相似。
我们希望这些点不太可能在像您这样具有透视变化的图像之间变化。这些 lecture slides很好地概述了如何使用相当简单的线性代数找到这样的点。我使用 Mathematica 是因为它内置了很多这些东西的函数。 ImageKeypoints在这里做我们想做的事。
在我们有了有趣的点之后,我们需要找到哪些点与我们正在比较的图像相匹配。如果您的图像非常相似,就像示例中的图像一样,您可能只需为每个有趣点拍摄 8x8 灰度图像,然后将一张图像中的每张图像与另一张图像上附近有趣点的图像进行比较。我认为您可以使用现有的算法。
如果您想使用更高级的算法,例如 SIFT您需要查看 ImageKeypoint 的属性,例如比例和方向。
ImageKeypoints 文档中有这个示例,您可以使用它为每个有趣的点获取一小部分图像(它使用 scale 属性而不是固定大小):
MapThread[ImageTrim[img, {#1}, 2.5 #2] &,
Transpose@
ImageKeypoints[img, {"Position", "Scale"},
"KeypointStrength" -> .001]]
找到一定数量的匹配点可能足以说明图像相似,但如果不是,您可以使用类似 RANSAC 的内容。找出对齐哈希图像(您已经能够生成的 8x8 图像)所需的转换,以使现有算法能够正常工作。
我应该指出 Mathematica 有 ImageCorrespondingPoints ,它可以更好地完成所有这些工作(使用 ImageKeypoints)。但我不知道您如何让它缓存中间结果,以便根据您尝试执行的操作进行缩放。不过,您可能想要研究它将匹配点限制为透视变换的能力。
这是示例图像的匹配点图,让您了解哪些部分最终匹配:
因此,您可以预先计算图像数据库的有趣点,以及每个点的灰度哈希。您必须为数据库中的每个图像比较多个哈希图像,而不仅仅是两个,但它将扩展到您当前算法的常数因子内。
关于image - 如何知道图像是否与另一个图像相似(角度略有不同但视角相同),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23885422/