我们能以编程方式比较相同分辨率的不同图像吗?

是否有一种良好可靠的方法来比较相同格式和相同分辨率的图像并获得它们之间的差异?

在最好的情况下,我正在寻找可以进行比较的图像的一些数字表示,因为我必须比较许多图像。

您可以使用ImageMagick的compare命令执行此操作。

(如果您使用命令行成功,那么您可以继续使用ImageMagick的API之一:其中包括可用于C‘MagickWand’ ), C++‘Magick ++’ ), Java‘JMagick’ ) , LISP‘L-Magick’.NET‘Magick.NET’ ), Perl‘PerlMagick’ ), PHP‘IMagick’ ), Python‘PythonMagick’ )和Ruby‘RMagick’ )。然后将各自的function实现到您自己的应用程序中。)

唯一的要求是:图像需要在宽度和高度上具有相同的尺寸,以像素数量来衡量。 所以你甚至不需要你想象的相同格式

可以通过不同方式返回差异:

  • 生成差异的直观表示,其中具有增量的像素以某种方式在增量图像中突出显示。

  • 生成差异的文本和/或统计表示,其中输出是一个或多个数字,或者只是不同的像素数或其他度量。


以下是可以比较的四个示例图像。 它们各自具有类似的外观,尺寸为322×429像素 – 但在颜色和格式方面存在一些细微差别:右上角是JPEG,另外三种是PNG:

视觉比较

这是最简单的命令来比较前两个图像并产生一个视觉’delta’:

 compare \ http://i.stack.imgur.com/GBax7.png \ http://i.stack.imgur.com/D9IAV.jpg \ delta1.pdf 

这将PNG与JPEG进行比较,并生成PDF作为输出。 有关此输出的视觉印象,请参见左下方的图像(由于此处无法显示PDF,因此我确实生成了一个PNG并将其用于显示)。

所有ImageMagick中最简单的compare命令究竟做了什么?

  1. 它使用第一张图像作为苍白背景。
  2. 它在每个位置上覆盖红色的完全不透明的像素,其中第二图像中的相应像素的颜色偏离第一图像。

(如果我不想要默认的红色突出显示,我可以添加-highlight-color blue-lowlight-color yellow或任何其他颜色定义)

如果我不想要像素颜色的这种过度精确比较怎么办? 如果我只想在各个像素之间有更大的色彩距离时才想要红色像素怎么办?

简单:在命令行中添加“模糊”因子!

 compare \ http://i.stack.imgur.com/GBax7.png \ http://i.stack.imgur.com/D9IAV.jpg \ -fuzz 2.5% \ delta2.png 

在没有附加参数的情况下运行第一个(最简单的)比较命令时,ImageMagick默默地添加了其默认比较方法的规范,该方法称为-compose src-over

当然,我们可以覆盖它并使用不同的合成模式。 如何了解可用的合成模式? 命令convert -list compose将为我们枚举它们! 这是完整的列表 – 它在我的系统中包含67个不同的列表:

Atop Blend Blur Bumpmap ChangeMask Clear ColorBurn ColorDodge Colorize CopyBlack CopyBlue CopyCyan CopyGreen Copy CopyYellow Darken DarkenIntensity DivideDst DivideSrc Dst Difference Displace Dissolve Distort DstAtop DstIn DstOut DstOver Exclusion HardLight HardMix Hue In Lighten LightenIntensity LinearBurn LinearDodge LinearLight Luminize Mathematics MinusDst MinusSrc Modulate ModulusAdd ModulusSubtract Multiply None覆盖超过PegtopLight PinLight Plus替换饱和屏幕SoftLight Src SrcAtop SrcIn SrcOut SrcOver VividLight Xor

让我们尝试每一个:

 for i in $(convert -list compose|tr "\n" " "); do \ compare \ http://i.stack.imgur.com/GBax7.png \ http://i.stack.imgur.com/D9IAV.jpg \ -compose ${i} \ delta-${i}.png ; \ done 

当然,现在显示每个结果的delta图像太多了。 最有趣的是:

  • 左上角是-compose Difference
  • 右上角是-compose DivideSrc
  • 中心左边是-compose CopyBlue
  • 中右边是 – -compose MinusDst
  • 左下角是-compose Hue
  • 右下角是-compose LightenIntensity

注意:如果你交换两个比较图像的顺序,两个结果的增量可能会有两个显着不同!

现在,您可以通过视觉比较两个相似的图像开始自己的实验。

测量结果

要生成有关两个图像差异的指标,您可以运行如下命令:

 compare \ -metric rmse \ http://i.stack.imgur.com/GBax7.png \ http://i.stack.imgur.com/D9IAV.jpg \ null: 

rmse均方根误差的首字母缩写。 以上示例图像的结果给出:

  1339.53 (0.02044) 

支持多少种不同的度量方法?

对于当前版本的ImageMagick,以下命令枚举给定系统上的所有可用比较度量方法:

 compare -list metric 

在我的笔记本上,这些是:

AE Fuzz MAE MEPP MSE NCC PAE PHASH PSNR RMSE

这些缩写的含义是:

 AE absolute error count, number of different pixels (`-fuzz` effected) FUZZ mean color distance MAE mean absolute error (normalized), average channel error distance MEPP mean error per pixel (normalized mean error, normalized peak error) MSE mean error squared, average of the channel error squared NCC normalized cross correlation PAE peak absolute (normalized peak absolute) PHASH perceptual hash PSNR peak signal to noise ratio RMSE root mean squared (normalized root mean squared) 

一个有趣的(和相对较新的)度量标准是phash (’perceptual hash’)。 它是唯一一个不需要相同尺寸的两个比较图像。 在命令行和编程方式上,在没有真正“查看它们”的情况下缩小类似图像(或者至少可靠地排除看起来非常不同的图像对)确实是最好的“度量”。

一个很好的实验就是将图像与自身进行比较。 它显示了相应的度量标准如何将“身份”转换为其自己的环境:

 for i in $(compare -list metric); do \ compare \ -metric $i \ http://i.stack.imgur.com/GBax7.png \ http://i.stack.imgur.com/GBax7.png \ null: \ done 

这是结果:

 AE : 0 Fuzz : 0 (0) MAE : 0 (0) MEPP : 0 (0, 0) MSE : 0 (0) NCC : 1.00001 PAE : 0 (0) PHASH : 0 PSNR : inf RMSE : 0 (0) 

如您所见,每个度量方法返回0 ,除了两个:PSNR返回infinity ,NCC返回1.00001

运行相同的命令,将100×100像素的纯白色补丁与纯黑色补丁进行比较:

 for i in $(compare -list metric); do \ compare \ -metric $i \ -size 100x100 \ xc:white \ xc:black \ null: \ done 

这将返回以下结果:

 AE : 10000 Fuzz : 65535 (1) MAE : 65535 (1) MEPP : 1.96605e+09 (1.00003, 1) MSE : 65535 (1) NCC : 0 PAE : 65535 (1) PHASH : 417.941 PSNR : 0 RMSE : 65535 (1) 

AE指标与预期一致:10000像素(来自-size 100x100 )不同。 一旦您阅读并了解各自的度量标准定义意味着什么,大多数其他结果也很容易理解….

最后,让我们看一下比较上面两个图像(PNG和JPEG)时每个可用指标的输出:

 for i in $(compare -list metric); do \ compare -metric $i \ http://i.stack.imgur.com/GBax7.png \ http://i.stack.imgur.com/D9IAV.jpg \ null: \ done AE : 74200 Fuzz : 1339.53 (0.02044) MAE : 499.997 (0.00762946) MEPP : 2.07206e+08 (0.000417654, 0.435294) MSE : 27.3801 (0.000417793) NCC : 0.99709 PAE : 28527 (0.435294) PHASH : 0.745389 PSNR : 33.7904 RMSE : 1339.53 (0.02044) 

现在选择你的指标! 🙂