使用ImageMagick和C#比较两张图片

5
我想比较两张图片,生成并保存一张显示所有已发现差异的图片。
例如: enter image description here 我使用ImageMagick:https://magick.codeplex.com/,但是他们没有完整的C#文档。我只找到了:http://www.imagemagick.org/Usage/compare/ 例如,这段代码显示0-1之间的值,表示图像的相似度:
    MagickImage img1 = new MagickImage(@"C:\test\Image1.jpg");
    MagickImage img2 = new MagickImage(@"C:\test\Image2.jpg");
    double diff =  img1.Compare(img2,new ErrorMetric());

但是我该如何使用ImageMagick比较图像并将结果保存,就像上面的示例和他们网站中所示的那样?
更新: 在dlemstra的帮助下,我编写了以下代码,并生成了应该显示与上面示例相同的差异的图像。 MagickImage img1 = new MagickImage(@"C:\test\Image1.jpg"); MagickImage img2 = new MagickImage(@"C:\test\Image2.jpg"); MagickImage img3 = new MagickImage(@"C:\test\Image3.jpg"); MagickImage img4 = new MagickImage(@"C:\test\DiffImage.jpg"); MagickImage img5 = new MagickImage(@"C:\test\DiffImage.jpg");
        var imgDiff = new MagickImage();

        img1.Compare(img2, new ErrorMetric(), imgDiff);
        imgDiff.Write(@"C:\test\Diff4.jpg");

        img1.Compare(img3, new ErrorMetric(), imgDiff);
        imgDiff.Write(@"C:\test\Diff5.jpg");

        img1.Compare(img4, new ErrorMetric(), imgDiff);
        imgDiff.Write(@"C:\test\Diff6.jpg");

        img5.Compare(img4, new ErrorMetric(), imgDiff);
        imgDiff.Write(@"C:\test\Diff7.jpg");

奇怪的结果是:当我比较以下两个图像时,只有标记的差异: enter image description here 这是我得到的结果(而不像上面的“imageMagick”示例) enter image description here

嗨@Yuval,你解决了这个问题吗? - Fractal
2个回答

7
您需要使用Compare方法的其他重载版本来完成此操作。以下示例演示如何实现此操作:
using (var img1 = new MagickImage(@"C:\test\Image1.jpg"))
{
  using (var img2 = new MagickImage(@"C:\test\Image2.jpg"))
  {
    using (var imgDiff = new MagickImage())
    {
      double diff = img1.Compare(img2, new ErrorMetric(), imgDiff);
      imgDiff.Write(@"C:\test\Diff-Image1-Image2.jpg");
    }
  }
}

但是当您使用jpeg格式的图像(它们是有损的)时,您可能还想在第一张图像上设置ColorFuzz:

img1.ColorFuzz = new Percentage(5); // adjust this value for your situation

这将使几乎相同的像素也能匹配。

1
谢谢!那帮了我很多,但现在当我进行两个比较时:一个是完全相同的图像,另一个是有一点差异的图像,我得到了奇怪的结果...请查看更新后的问题。 - Yuval Levy

1

经验教训:

想要添加一些重要的注意事项,以便其他人在第一次测试ImageMagick(或任何比较工具)时,希望避免我遇到的陷阱。

  1. 一般情况下要注意不要在Windows画图中进行编辑。
  2. 不要在Windows画图中编辑带有透明背景的*.png文件,并期望得到良好的比较结果。Windows画图无法处理透明背景,您在Paint中编辑的png现在将具有白色背景。肉眼看图片看起来完全相同,但是图像比较器知道更多。
  3. 如果您有SnagIt,则这是一个更好的工具,用于在您想要测试图像比较工具时对图像进行编辑。

结论

@dlemstra编写的代码确实按预期工作。只需确保在第一次测试时,您修改的第二个图像没有被您使用的图像编辑器无意中修改。这是在第一次测试任何图像比较工具时的一般警告,以查看是否要使用它。

示例

示例1:透明png + Windows Paint

下载了一张透明图片,在Paint中对其进行编辑,但不小心将背景也改为了白色而非透明。只需在Paint中打开第二张图片,然后保存而不进行任何编辑,就会导致差异看起来像这样:

enter image description here

直到我使用Beyond Compare进行比较,才弄清楚发生了什么:

enter image description here

例子2:复杂的*.jpg图片 + Windows绘画

Windows绘画在保存复杂图片时不太能保持图像的完全一致性: 大红色区域是我所做的更改,而玫瑰花的细线轮廓则是Windows绘画对图片所做的更改。

enter image description here

即使我没有做任何更改,只是在Paint中打开、保存和关闭第二张图片(原始图片也是在Paint中保存的),Paint仍然对图片进行了不必要的编辑(图像中有暗红色的点):

enter image description here

我拥有一张原始图像,该图像已在画图中保存并复制,打开第二张图像并在 snagIt 中保存第二张图像,然后关闭图像并比较这两个图像(应该是相同的)。然而,似乎 snagIt 对原始的“画图保存”图像进行了自己的修改:

enter image description here

最后,我复制了“Snagit保存”的图像,也在SnagIt中打开了这第二张图片,对第二张图片进行了编辑,将其保存在SnagIt中,然后关闭了该图片。SnagIt没有对此图片进行任何修改,比较结果与我预期完全一致。

enter image description here

最后: 大多数关于ImageMagick的信息都是关于通过命令行使用它的。您可以通过NuGet包管理器安装Magick.Net NuGet将其添加到Visual Studio中的C#项目中。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接