【问题标题】:Comparing Image Files比较图像文件
【发布时间】:2012-01-23 20:47:20
【问题描述】:

我想创建一个比较两个图像的程序。它必须包含 2 个文件夹,每个文件夹中都包含图片,并且一个文件夹中的每张图片在另一个文件夹中都有一对(具有相同的文件名)例如:文件夹 1 有 3 张图片:[a.png,b.png,c.png] ,而folder2有3张图片:[a.png, b.png, c.png]。我想将文件夹 1/a 与文件夹 2/a 进行比较。我不知道从哪里开始。

【问题讨论】:

  • 您要比较文件名还是图片内容?
  • 如果您只想找到相同的图像,您可以比较文件的 CRC32。如果你想要一个完全成熟的图像比较器,我想你需要更多的东西(将图像解码为原始像素并逐像素比较)
  • 比较文件或图像?
  • 如果对你使用的工具没有限制,也就是说,它不是家庭作业,你可以在两个目录上运行diff
  • 看看 TortoiseSvn 中的图像比较工具是如何工作的(从用户的角度来看)。这将使您了解一个好的图像差异程序可能具有的操作理论。从那里,你必须实现它:)

标签: c# python c image


【解决方案1】:

您提到了images 而不是file,所以我假设您不想比较原始数据而是图像像素,并且您可能还希望对图像之间的差异设置阈值

最简单的方法是使用 PIL 比较两个图像。 PIL 有一个 histogram 函数,您可以使用它来获取两个图像的直方图,然后获取 RMS(均方根),例如

import ImageChops
import math, operator

def rmsdiff(im1, im2):
    "Calculate the root-mean-square difference between two images"

    h = ImageChops.difference(im1, im2).histogram()

    # calculate rms
    return math.sqrt(reduce(operator.add,
        map(lambda h, i: h*(i**2), h, range(256))
    ) / (float(im1.size[0]) * im1.size[1]))

复制自http://effbot.org/zone/pil-comparing-images.htm

一旦你有一个返回 rmsdiff 的函数,你就可以在另一个函数中使用它来遍历所有文件,例如

def diff_folder(folder1, folder2):
    for path1 in glob.glob(folder1+"/*.png"):
        filename = os.path.basename(path1)
        path2 = os.path.join(folder2, filename)
        if not os.path.exists(path2):
            continue
        im1 = Image.open(path1)
        im2 = Image.open(path2)
        diff = rmsdiff(im1, im2)
        if diff > threshold:
           print "different"

【讨论】:

    【解决方案2】:

    【讨论】:

      【解决方案3】:

      这是一个 C# 解决方案,它使用二进制文件比较来比较文件。但是,即使图片看起来相同,图像也可能包含不同的元信息。因此,最好先将图像作为图像而不是文件打开来进行比较。

      public void CompareImages()
      {
          var dir1 = new DirectoryInfo(@"C:\path1");
          FileInfo[] files1 = dir1.GetFiles("*.png");
      
          var dir2 = new DirectoryInfo(@"C:\path2");
          FileInfo[] files2 = dir2.GetFiles("*.png");
          Dictionary<string, FileInfo> files2Dict = files2.ToDictionary(f => f.Name);
      
          foreach (FileInfo f1 in files1) {
              FileInfo f2;
              bool equal = true;
              if (files2Dict.TryGetValue(f1.Name, out f2) && f1.Length == f2.Length) {
                  byte[] image1 = GetFileBytes(f1);
                  byte[] image2 = GetFileBytes(f2);
                  for (int i = 0; i < image1.Length; i++) {
                      if (image1[i] != image2[i]) {
                          equal = false;
                          break;
                      }
                  }
              } else {
                  equal = false;
              }
              Console.WriteLine(f1.Name + ": " + (equal ? "Images are equal" : "Images are NOT equal"));
          }
      }
      
      private static byte[] GetFileBytes(FileInfo f)
      {
          using (FileStream stream = f.OpenRead()) {
              byte[] buffer = new byte[f.Length];
              stream.Read(buffer, 0, (int)f.Length);
              return buffer;
          }
      }
      

      【讨论】:

      • 除了二进制文件比较,我什么也没看到
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-15
      • 1970-01-01
      • 1970-01-01
      • 2011-01-09
      • 1970-01-01
      相关资源
      最近更新 更多