检测相似图片

12

可能是重复的问题:
图像比较算法

基本上我需要编写一个程序,检查两个图像是否相同。考虑以下两个图像:

http://i221.photobucket.com/albums/dd298/ramdeen32/starry_night.jpg

http://i221.photobucket.com/albums/dd298/ramdeen32/starry_night2.jpg

这两张图片看起来一样,但我该如何检查它们是否相同呢?我的限制只在于媒体函数。目前我能想到的是通过宽度、高度缩放并比较每个像素的RGB值,但颜色不会有所不同吗?

我完全不知道该怎么做,请帮帮我。

*注意:这必须使用Python并使用(媒体库)。


1
参见图像比较算法 - Matthew Flaschen
3个回答

5
哇,这是一个非常大的问题,有很多可能的解决方案。我不是Python专家,但我认为你的问题很有趣,所以我想提出一个方法,如果我遇到这个问题,我会实现它。
显然,你发布的两张图片实际上非常不同,因此需要考虑“相同有多少不同”,特别是在处理图像并考虑不同的图像格式和压缩等情况时。
无论如何,对于一种解决方案,它允许给定颜色值的差异(但不允许像素放错位置),我会执行以下操作:
1.选择两张图片。 2.将最大的图片重新调整大小为第一张图片的完全相同的高度和宽度(甚至扭曲图像,如果必要)。 3.可能将图像变成灰度,使下一步更简单,而不会失去太多的效果。实际上,在这里运行边缘检测也可能有效。 4.遍历两个图像中的每个像素,并存储RGB通道中的每个像素之间的差异,或者只是灰度强度上的差异。你最终会得到一个大小与图像相同的数组,记录了两个图像像素强度之间的差异。 5.现在,我不知道确切的值,但你可能会发现,如果你遍历数组,你可以看到所有像素中两个图像之间的差异是否相同(或几乎相同)。也许可以先遍历一次数组,找到两个图像像素强度之间的平均差异,然后再遍历一次图像,看看90%的差异是否在某个阈值范围内(5%差异?)。
只是一个想法。当然,可能有一些我不知道的很好的函数可以使这变得容易,但我不抱太大希望!

这很不错!然而,我不明白你所说的“灰度强度”是什么意思。要使图像灰度化,难道不必对每个像素进行归一化处理,例如取R+G+B的平均值,然后将RGB重置为该平均值吗? - 1337holiday
灰度不是RGB的平均值,而是加权平均值,其中R = 0.299,G = 0.587,B = 0.114。(这是因为我们的眼睛对绿色比红色或蓝色更敏感,对蓝色最不敏感。) - kindall
嗯,我还是有点不清楚,请问你能演示一下像素的基本计算吗? - 1337holiday
正如Kindall所说,要将图像灰度化(这将使其余的过程更容易,尽管可能不太准确 - 相同图像的红色版本可能看起来与黄色版本相同),您需要迭代每个像素; grayScalePixel = (0.299R)+(0.587G)+(0.114*B); 虽然,在Python的媒体库中必须有一个函数可以实现这一点!然后在第5步中,您将迭代两个灰度图像中的每个像素,然后测量差异; differences[x][y] = grayImageA[x][y] - grayImageB[x][y]。然后,您可以使用某些算法评估差异(如5中建议的那样)。 - John Wordsworth
我觉得我对0.299、0.587、0.114的来源感到困惑(这些是常数吗?)。我已经设法解决了缩放问题,但这种灰度仍然让我感到困扰。 - 1337holiday
数字0.299、0.587、0.114只是常数,以更符合人眼工作方式的方式将颜色转换为灰度。 - John Wordsworth

1
ImageMagick有Python绑定和比较函数。它应该为您完成大部分工作,但我从未在Python中使用过它。

0

我认为John Wordsworth的第二步可能是最难的 - 在这里,您正在处理图像的拉伸副本,但您是否还允许旋转,裁剪或以其他方式扭曲的图像?如果是这样,您将需要一个特征匹配算法,例如在Hugin或其他全景创建软件中使用的算法。这将找到匹配的特征,进行扭曲以适应,然后您可以执行比较的其他阶段。理想情况下,您希望从照片中识别出梵高的绘画作品,甚至是杯子上的照片!对于人类来说,这很容易做到,但对于计算机来说,需要更复杂的数学。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接