【问题标题】:Can we programmatically compare different images of same resolutions?我们可以以编程方式比较相同分辨率的不同图像吗?
【发布时间】:2015-03-14 12:37:07
【问题描述】:

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

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

【问题讨论】:

  • 这个问题非常广泛,甚至可能“过于广泛”(因为图像有许多可能的差异度量),但这不是我所说的“基于意见” - 请参阅当前答案。
  • 我不认为它“太宽泛”,因为我将它标记为 c# 和 c。最重要的是,以下答案解释了一切都非常好。

标签: c# c++ image image-processing imagemagick


【解决方案1】:

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

(如果您成功使用命令行,则可以继续使用 ImageMagick 的 API 之一:这些 API 可用于 C'MagickWand' )、C++ ('Magick++')、Java ('JMagick')、LISP ('L-Magick' )、.NET ('Magick.NET')、Perl ('PerlMagick')、PHP ('IMagick' )、Python ('PythonMagick') 和 Ruby ('RMagick')。 -- 然后将各自的函数实现到您自己的应用程序中。)

唯一的要求是:图像需要具有相同的宽度和高度尺寸,以像素数衡量。因此,您甚至不需要与您假设的相同的格式

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

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

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


示例

这里有四个可以比较的示例图像。它们的外观相似,大小为 322x429 像素 - 但在颜色和格式方面存在一些细微差别:右上角是 JPEG,其他三个是 PNG:

视觉对比

这是比较前两个图像并产生视觉“增量”的最简单命令:

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 或任何其他颜色定义)

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

简单:在命令行中添加 'fuzz' 因素!

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 上色 CopyBlack CopyBlue CopyCyan CopyGreen Copy CopyMagenta CopyOpacity CopyRed CopyYellow Darken DarkenDardenDist DivideSrc Dst Difference Displace Dissolve Distort DstAtop DstIn DstOut DstOver Exclusion HardLight HardMix Hue In Lighten LightenIntensity LinearBurn LinearDodge LinearLight Luminize Mathematics MinusDst MinusSrc ModulusSubtract Multiply None Out Overlay Over PegtopLight PinLight Plus 替换 Saturate Screen 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

当然,现在显示每一个生成的增量图像会太过分了。最有趣的如下:

  • 左上角是-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(“感知哈希”)。它是唯一一个不需要两个比较图像具有相同尺寸的图像。在命令行和编程方式上,在不真正“查看它们”的情况下缩小看起来相似的图像(或至少可靠地排除这些看起来非常不同的图像对)确实是最好的“指标”。

一个很好的实验是当您将图像与其自身进行比较时。它显示了各个指标如何将“身份”转换为自己的环境:

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

运行同样的命令,将 100x100 像素的纯白色块与纯黑色块进行比较:

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)是不同的。一旦您read up and grokked 各个指标定义的含义,大多数其他结果也很容易理解......

最后,让我们看看在比较上面的前两张图片(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)

现在选择您的指标! :-)

【讨论】:

  • 很好的答案。当我搜索他们的网站时:imagemagick.org 我还发现了 C API,所以这非常适合我的项目。
  • 特别感谢您展示了如何在不保存比较图像的情况下计算比较指标。
猜你喜欢
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
  • 2020-11-01
  • 1970-01-01
  • 2011-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多