【问题标题】:Equality test of images using ImageMagick使用 ImageMagick 对图像进行平等测试
【发布时间】:2011-10-29 18:48:57
【问题描述】:

ImageMagick 库中是否有任何相等谓词函数?我想比较两张图片,看看它们是否完全相同(像素的所有颜色都相同)或有什么不同。

我看了一圈,好像没有这个功能。我应该自己使用像素迭代器编写函数吗?

【问题讨论】:

    标签: comparison imagemagick equals equality


    【解决方案1】:

    ImageMagick 提供compare 函数来正确比较图像。

    检查两个图像的md5 校验和不是正确的方法,因为某些图像格式(例如带有 EXIF 的 PNG 和 JPEG)包含创建文件的日期和时间(参见示例 1),并且一些文件可以在外观上相同,但在内部表示完全不同(参见示例 2),或者具有不同的位深度(参见示例 3)。

    示例 1

    # Create two identical images (100x100 pixels, bright red) but with different file contents
    convert -size 100x100 xc:red r1.png
    convert -size 100x100 xc:red r2.png
    
    # MD5 checksum them
    md5 r?.png
    MD5 (r1.png) = 9f6d612615efd88c3fd8521d717e9811
    MD5 (r2.png) = 996911bec0e0da75af46a1e78c052998      # Mmmm different
    
    # Ask IM to tell us absolute error between the two (number of differing pixels)
    compare -metric AE r1.png r2.png null:
    0                                                    # No difference - that's better
    

    为什么这两个在 MD5 中不同?因为日期在里面……

    identify -verbose r[12].png | grep -i date
    date:create: 2015-03-03T14:57:26+00:00
    date:modify: 2015-03-03T14:57:26+00:00
    date:create: 2015-03-03T14:57:43+00:00
    date:modify: 2015-03-03T14:57:43+00:00
    

    示例 2

    # Create PNG and identical GIF
    convert -size 100x100 xc:red r.png
    convert -size 100x100 xc:red r.gif
    
    # Compare with MD5 sums
    md5 r.png r.gif
    MD5 (r.png) = 692ef06b62a15b799d5dc549b0dd3737
    MD5 (r.gif) = 549feea78dc438924fbb3e0ef97dc0b3         # Ooops
    
    # Compare properly
    compare -metric AE r.gif r.png null:
    0                                                      # Identical
    

    示例 3

    # Create 8-bit PNG and 16-bit PNG
    convert -size 100x100 xc:red PNG8:8.png
    convert -size 100x100 xc:red PNG48:48.png
    
    # MD5 sum them
    md5 8.png 48.png
    MD5 (8.png) = eb3fc9a06e1632c3b41ebb986b81a816
    MD5 (48.png) = 32fdf1c30793a4fed941c91d27084e0a   # Ooops
    
    # Let ImageMagick compare them
    compare -metric AE 8.png 48.png  null:
    0
    

    图像的模糊比较

    正如 Kurt 所暗示的,这也导致了对图像进行模糊比较的可能性。我们可以这样探索:

    # Create a grey image, 100x100 and put some noise in it
    convert -size 100x100 xc:gray +noise gaussian noise.png
    

    现在将所有像素乘以 1.01,使它们的亮度提高 1%,让人难以察觉:

    # Make pixels 1% brighter
    convert noise.png -evaluate multiply 1.01 brighternoise.png
    
    # ... and compare the statistics of the two images
    identify -verbose *noise* | grep -E "^Image|mean"
    
    Image: brighternoise.png
      mean: 127.235 (0.498959)       <--- The brighter image is, well, brighter
    Image: noise.png
      mean: 126.175 (0.494805)
    

    现在用几种不同的方式比较它们:

    # Pixels may differ by up to 2% before being considered different
    compare -fuzz 2% -metric AE noise.png brighternoise.png null:
    0        # All pixel values within 2% between the 2 images
    
    # Pixels may only differ by 0.5% before being considered different
    compare -fuzz 0.5% -metric AE noise.png brighternoise.png null:
    594      # 594 of the 10,000 pixels differ by more than 0.5%
    
    # Calculate Root Mean Square Error (RMSE) to see how much pixels tend to differ
    compare -metric RMSE noise.png brighternoise.png null:
    278.96 (0.00425666)    # On average, the pixels differ by 0.4% - i.e. hardly at all
    

    【讨论】:

    • 对于 6 年后尝试此操作的任何人:compare -metric MAE 8.png 48.png。他们在新版本中更改了参数名称。
    【解决方案2】:

    马克的回答很准确。但是,他忘了提到compare 也可以返回一个“增量图像”,它将任何有差异的像素绘制为红色,而相同的像素将绘制为白色。

    # Create a PNG and a JPEG from the builtin 'wizard:' image:
    convert wizard: wizard.png
    convert wizard: wizard.jpg
    

    现在比较两者:

    compare wizard.png wizard.jpg delta.png
    

    这是“delta.png”:

    PNG 和 JPEG 之间有很多不同之处!好的,这是因为 JPEG 是一种 有损 图像格式...

    如您所见,“delta.png”的背景是苍白的。如果您不想要这个背景,而只想要红色/白色像素,请修改compare 命令:

    compare wizard.png wizard.jpg -compose src delta.png
    

    此外,您可能希望忽略低于某个阈值的此类差异。这里-fuzz N%参数就派上用场了。

    您想要蓝色像素而不是红色像素?黄色的而不是白色的?给你:

    compare                  \
      -highlight-color blue  \
      -lowlight-color yellow \
      -fuzz 3%               \
       wizard.png            \
       wizard.jpg            \
       delta2.png
    

    您想要对坐标不同的所有像素进行文字描述吗?这里特殊的输出格式*.txt 可能不错。

    试试这个:

    compare                  \
      -fuzz 6%               \
       wizard.png            \
       wizard.jpg            \
      -compose src           \
       delta3.txt
    

    “delta3.txt”文件将非常大,因为它包含这种格式的每个像素一行:

    # ImageMagick pixel enumeration: 480,640,255,srgba
    0,0: (255,255,255,0.8)  #FFFFFFCC  srgba(255,255,255,0.8)
    1,0: (255,255,255,0.8)  #FFFFFFCC  srgba(255,255,255,0.8)
    2,0: (255,255,255,0.8)  #FFFFFFCC  srgba(255,255,255,0.8)
    [....]
    77,80: (241,0,30,0.8)  #F1001ECC  srgba(241,0,30,0.8)
    [....]
    

    第一列给出了相应像素的(row,column) 对(计数从零开始,最上面、最左边的像素的地址为(0,0)

    接下来的三列以 3 种不同的常用符号格式返回各自的像素颜色。

    顺便说一句,ImageMagick 可以毫无问题地将delta3.txt 文件转换回真实图像:

    convert delta3.txt delta3.png
    

    因此,要将所有不同(红色)的像素放入文本文件中,您可以这样做:

    compare                  \
      -fuzz 6%               \
       wizard.png            \
       wizard.jpg            \
      -compose src           \
       txt:-                 \
    | grep -v '#FFFFFFCC' 
    

    要计算不同像素的数量:

    compare                  \
      -fuzz 6%               \
       wizard.png            \
       wizard.jpg            \
      -compose src           \
       txt:-                 \
    | grep -v '#FFFFFFCC'    \
    | wc -l
    

    -fuzz 6% 我有2269 不同的像素。使用-fuzz 0% 我得到122474 不同的像素。 (这些图像中的像素总数为307200。)

    【讨论】:

      猜你喜欢
      • 2016-05-21
      • 1970-01-01
      • 2012-12-16
      • 2016-11-14
      • 2015-10-28
      • 1970-01-01
      • 2017-10-07
      • 2019-06-04
      • 1970-01-01
      相关资源
      最近更新 更多