我真的认为没有理由为此使用任何外部库,我已经多次做过这种事情,并且以下算法效果很好。我假设如果您要比较两张具有相同尺寸的图像,但如果它们不同,您可以调整其中一张的大小。
badness := 0.0
For x, y over the entire image:
r, g, b := color at x,y in image 1
R, G, B := color at x,y in image 2
badness += (r-R)*(r-R) + (g-G)*(g-G) + (b-B)*(b-B)
badness /= (image width) * (image height)
现在您已经获得了两个图像之间的标准化不良值,不良值越低,图像匹配的可能性就越大。这是简单而有效的,在某些情况下有很多东西可以让它更好或更快地工作,但你可能不需要这样的东西。您甚至不需要对不良进行规范化,但是如果您想手动查看几个可能的匹配项,您只需为其设置一个阈值即可。
由于这个问题得到了更多关注,因此我决定添加一种方法来加快处理多次图像的速度。当我需要比较数以万计的图像时,我使用了这种方法,并且我确信一对典型的图像会大不相同。我也知道我所有的图像都是完全相同的尺寸。在您比较对话框的情况下,您的典型图像可能大多是灰色的,并且您的某些图像可能需要调整大小(尽管这可能只是表示不匹配),在这种情况下,这种方法可能不会让您受益很多。
这个想法是形成一个四叉树,其中每个节点代表该节点代表的区域的平均 RGB 值。因此,4x4 图像的根节点的 RGB 值等于图像的平均 RGB 值,其子节点的 RGB 值表示其各自 2x2 区域的平均 RGB 值,而它们的子节点将代表单个像素。(实际上,最好不要超过大约 16x16 的区域,此时您应该开始比较单个像素。)
在开始比较图像之前,您还需要确定坏度阈值。您不会以任何可靠的准确度计算高于此阈值的不良率,因此这基本上是您愿意将图像标记为“不匹配”的阈值。
现在,当您比较图像 A 和图像 B 时,首先比较它们的四叉树表示的根节点。就像计算单个像素图像一样计算 badness,如果 badness 超过您的阈值,则立即返回并报告此级别的 badness。因为您使用的是标准化的坏度,并且由于坏度是使用平方差计算的,所以任何特定级别的坏度都将等于或小于较低级别的坏度,所以如果它在任何点超过阈值,你知道它也会超过单个像素级别的阈值。
如果阈值测试在 nxn 图像上通过,只需下降到下一个级别并像它是 2nx2n 图像一样进行比较。一旦你变得足够低,只需比较各个像素。根据您的图像语料库,这可能允许您跳过大量比较。