【发布时间】:2011-10-29 18:48:57
【问题描述】:
ImageMagick 库中是否有任何相等谓词函数?我想比较两张图片,看看它们是否完全相同(像素的所有颜色都相同)或有什么不同。
我看了一圈,好像没有这个功能。我应该自己使用像素迭代器编写函数吗?
【问题讨论】:
标签: comparison imagemagick equals equality
ImageMagick 库中是否有任何相等谓词函数?我想比较两张图片,看看它们是否完全相同(像素的所有颜色都相同)或有什么不同。
我看了一圈,好像没有这个功能。我应该自己使用像素迭代器编写函数吗?
【问题讨论】:
标签: comparison imagemagick equals equality
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
【讨论】:
compare -metric MAE 8.png 48.png。他们在新版本中更改了参数名称。
马克的回答很准确。但是,他忘了提到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。)
【讨论】: