11

给定两张图片:

image1.jpg
image2.jpg

什么是检测它们在 Python 中视觉上是否相同的快速方法?例如,它们可能具有不同的 EXIF 数据,即使图像数据相同,也会产生不同的校验和)。

Imagemagick 有一个出色的工具“identify”,它可以生成图像的视觉散列,但它需要大量处理器。

4

2 回答 2

21

使用 PIL/枕头:

from PIL import Image

im1 = Image.open('image1.jpg')
im2 = Image.open('image2.jpg')

if list(im1.getdata()) == list(im2.getdata()):
    print "Identical"
else:
    print "Different"
于 2014-06-01T19:11:56.953 回答
11

仍在提交解决这个问题的方法——即使 OP 说 ImageMagick 的方法过于密集(即使我的方法不涉及 Python)......也许我的回答对其他人有用,到达此页面通过搜索引擎。

请注意,任何应该在高分辨率图像中发现细微差异的图像比较都比在低分辨率图像中发现巨大差异需要更多的处理器密集型,因为它必须比较更多的像素。

差异的可视化

这是一个 ImageMagick 命令,它比较两个(相同大小!)图像,并将所有不同的像素返回为红色,将相同的像素返回为白色。第一个具有参考图像作为红白像素矩阵组成的淡出背景图像。.img可以是任何 IM 支持的格式(.png、.PnG、.png、.PNG、.jpg、.jpeg、.jPeG、.tif、.tiff、.ppm、.gif、.pdf、...) :

 compare reference.img similar.img  delta.img
 compare reference.img similar.img  -compose src delta.img

默认情况下,以 72 PPI 进行比较。如果您需要更高的分辨率(例如,使用基于矢量的图像,例如 PDF 页面),您可以添加-density以增加它。当然,处理时间也会相应增加:

 compare -density 300 reference.img similar.img delta.img

如果添加fuzz factor,您可以告诉 ImageMagick 将所有像素视为相同,它们之间的距离不超过一定的颜色距离:

 compare -fuzz '3%' reference.img similar.img -compose src delta.img

pHash 差值

更新版本的 ImageMagick 支持该phash算法:

 compare -metric phash reference.img similar.img -compose src delta.img

除了创建delta.img可视化之外,这将返回一个数值,指示两个图像之间的“差异”。越接近0,比较的两幅图像越相似。

例子:

创建一些小的 PDF 页面,它们之间有细微的差别。我正在使用 Ghostscript:

gs -o ref1.pdf -sDEVICE=pdfwrite -g1050x1350 \
 -c "/Courier findfont 160 scalefont setfont 10.0 10.0 moveto (0) show showpage"

gs -o ref2.pdf -sDEVICE=pdfwrite -g1050x1350 
 -c "/Courier findfont 160 scalefont setfont 10.1 10.1 moveto (0) show showpage"

gs -o ref3.pdf -sDEVICE=pdfwrite -g1050x1350 \
 -c "/Courier findfont 160 scalefont setfont 10.0 10.0 moveto (O) show showpage"

gs -o ref4.pdf -sDEVICE=pdfwrite -g1050x1350 \
 -c "/Courier findfont 160 scalefont setfont 10.1 10.1 moveto (O) show showpage"

现在ref1.pdfref3.pdf默认分辨率 72 PPI 进行比较:

compare -metric phash ref1.pdf ref3.pdf delta-ref1-ref3.pdf
  7.61662

返回的 pHash 值为7.61662。这表明 ImageMagickcompare至少发现了一些差异。

让我们看一下可视化。我将创建三个 PDF/图像的并排可视化(如下所示):

convert                                    \
   -mattecolor blue                        \
      \( ref1.pdf -frame 2x2 \)            \
    null:                                  \
      \( ref3.pdf -frame 2x2 \)            \
    null:                                  \
      \( delta-ref1-ref3.pdf -frame 2x2 \) \
   +append                                 \
    ref1-ref3-delta.png 

差异的可视化:<code>ref1.pdf</code>(右)、<code>ref3.pdf</code>(中)和<code>ref1-ref3-delta.png</code>(右)

如您所见,0(数字“零”)和O(字母o,大写版本)的不同形状非常突出。

现在下一个:ref1.pdf与 相比ref2.pdf,也是 72 PPI。

compare -metric phash ref1.pdf ref2.pdf delta-ref1-ref2.pdf
  0

现在返回的 pHash 值为0. 这表明 ImageMagick 没有发现任何差异!

创建三个 PDF/图像的并排可视化:

convert                                    \
   -mattecolor blue                        \
      \( ref1.pdf -frame 2x2 \)            \
    null:                                  \
      \( ref2.pdf -frame 2x2 \)            \
    null:                                  \
      \( delta-ref1-ref2.pdf -frame 2x2 \) \
   +append                                 \
    ref1-ref2-delta.png 

差异的可视化:<code>ref1.pdf</code>(右)、<code>ref2.pdf</code>(中)和<code>ref1-ref2-delta.png</code>(右)

如您所见,72 PPI ImageMagick 没有发现两个 PDF 之间的差异(如红色像素所示)。根据 Ghostscript 命令,两者都显示 digit 0,但在 x 和 y 方向相隔 0.1 pt 的位置。所以实际上,在原始 PDF 中,存在差异。但是当以 72 PPI 渲染时,这种差异是不可见的。

让我们尝试看看与density 600then 的区别:

compare        \
 -metric phash \
 -density 600  \
  ref1.pdf     \
  ref2.pdf     \
  ref1-ref2-at-density600-delta.png 

0.00172769

返回的 pHash 值为 600 PPI 现在是0.00172769. 这接近于零,但仍然存在差异。差小于 和 之间的ref1.pdfref3.pdf

现在在视觉比较中清楚地突出了差异,即使只有一条红色像素细线:

于 2014-11-20T16:16:04.360 回答