Image 如何知道一幅图像是否与另一幅图像相似(角度略有不同,但视角相同)

Image 如何知道一幅图像是否与另一幅图像相似(角度略有不同,但视角相同),image,hash,comparison,phash,Image,Hash,Comparison,Phash,我已经检查过像Phasher这样的方法,以获得类似的图像。基本上是将图像调整为8x8灰度,获得平均像素,并创建每个像素的二进制哈希值,比较其是否高于或低于平均像素 这里很好地解释了这种方法: 工作示例: -图1桌子上的计算机 -图2,相同,但有一枚硬币 这是可行的,因为使用非常精简的灰度图像的散列,两者几乎相同,甚至相同。因此,当90%以上的像素相同时(在同一个位置!),您可以得出结论,它们是相似的 我的问题是从同一角度但不同角度拍摄的图像,例如: 在这种情况下,生成的散列“指纹”相互移位

我已经检查过像Phasher这样的方法,以获得类似的图像。基本上是将图像调整为8x8灰度,获得平均像素,并创建每个像素的二进制哈希值,比较其是否高于或低于平均像素

这里很好地解释了这种方法:

工作示例: -图1桌子上的计算机 -图2,相同,但有一枚硬币

这是可行的,因为使用非常精简的灰度图像的散列,两者几乎相同,甚至相同。因此,当90%以上的像素相同时(在同一个位置!),您可以得出结论,它们是相似的

我的问题是从同一角度但不同角度拍摄的图像,例如:

在这种情况下,生成的散列“指纹”相互移位,以至于我们无法逐位比较散列,这将是非常不同的

像素“相似”,但它们不在同一位置,因为在本例中,天空更多,房屋“起点”比第一个低

因此,哈希比较的结果是“它们是不同的图像”

可能的解决办法:

我在考虑为第一个图像创建一个更大的散列,然后为第二个图像获取10个随机“子散列”,并尝试查看这10个子散列是否位于第一个大散列的“某个位置”(如果一个子串包含在另一个更大的图像中)

我认为这里的问题是处理数千个图像时的CPU/时间,因为您必须将1个图像与1000个图像进行比较,并且在每个图像中,将10个子哈希与一个大哈希进行比较


其他解决方案?;-)

如果散列不匹配,可以尝试上限比较8x8网格中匹配的像素数。也许您可以尝试匹配照片马赛克中的颜色:。

一个选项是为每个图像检测一组“有趣”的点,并将其存储在散列中。这与您建议的解决方案有些相似

我们希望这些点不可能在像您这样的视角发生变化的图像之间发生变化。这些很好地概述了如何用相当简单的线性代数找到像这样的点。我使用Mathematica是因为它内置了很多函数。这就是我们想要的

在我们得到我们感兴趣的点之后,我们需要找出哪些点与我们正在比较的图像相匹配。如果您的图像与示例中的图像非常相似,您可能只需为每个感兴趣的点拍摄一张8x8灰度图像,然后将一张图像中的每个图像与另一张图像上附近感兴趣点的图像进行比较。我想你可以使用你现有的算法

如果您想使用更高级的算法,例如,您需要查看ImageKeypoint的属性,如比例和方向

ImageKeypoints文档中有一个示例,您可以使用该示例为每个感兴趣的点获取一小块图像(它使用比例特性而不是固定大小):

找到一定数量的匹配点可能足以说明图像是相似的,但如果不是这样,您可以使用类似的方法来确定对齐哈希图像(您已经能够生成的8x8图像)所需的变换,以使现有算法能够正常工作

我应该指出Mathematica有,它(使用ImageKeypoints)做所有这些事情都要好得多。但我不知道如何让它缓存中间结果,以便根据您尝试的操作进行缩放。不过,您可能需要研究它将匹配点约束到透视变换的能力

下面是示例图像的匹配点图,让您了解哪些部分最终匹配:


因此,您可以为图像数据库预先计算感兴趣的点,以及每个点的灰度散列。您必须为数据库中的每个图像比较多个哈希图像,而不仅仅是两个,但它将在当前算法的恒定因子范围内进行缩放。

Phpdna,这正是Phaser所做的。。。但问题不在于获取“指纹”。另外,比较像素太随机,两张天空太多的照片将具有与上面示例中所述相同的“平均”像素。我的意思是比较8x8像素。从这个例子来看,它看起来非常相似。定义一个上限或阈值并完成。我知道已经3年了,但你有没有找到一个好的解决方案?
MapThread[ImageTrim[img, {#1}, 2.5 #2] &, 
 Transpose@
  ImageKeypoints[img, {"Position", "Scale"}, 
   "KeypointStrength" -> .001]]