【问题标题】:How to compare Image objects with C# .NET? [closed]如何将 Image 对象与 C# .NET 进行比较? [关闭]
【发布时间】:2011-03-24 00:49:00
【问题描述】:

我们可以用 C# 比较两个 Image 对象吗?例如,检查它们是否相等,或者更好地检查它们的像素有多相似?

如果可能,怎么做?

【问题讨论】:

    标签: c# .net testing image bitmap


    【解决方案1】:

    最简单的起点是维度。如果维度不相等,您可以将它们声明为 false。

    如果您需要逐个像素地遍历它们,则需要两个 for 循环。大致如下:

    Bitmap ImageA...
    Bitmap ImageB...
    
    for ( Int64 x = 0; x < ImageA.Width; x++ )
    {
         for ( Int64 y = 0; y < ImageA.Height; y++ )
         {
             if ( ImageA.GetPixel(x, y) != ImageB.GetPixel(x, y) )
             {
                return false;
             }
         }
    }
    

    它是伪代码(这些函数存在于 C# 中,虽然我现在不记得它们了)并且非常简单,但它是您想要执行基本的像素到像素检查的方式。

    但是请注意,要使该循环正常工作,图像必须具有相同的尺寸。如果不是,如果您尝试对较小区域之外的像素进行采样,您可能会遇到异常。比较像素也不会很快,因此您可能需要先找到另一种丢弃可能重复的方法。

    编辑:我不确定如何在 Image 上执行此操作,但对于 Bitmaps 来说非常简单。没有从类中获取图像像素数据的可见方法。不过,位图似乎继承自图像,所以这可能仍然有效。鉴于图像是位图和元文件的抽象类,它们可能没有简单的内部像素列表。

    【讨论】:

    • 所以,我只提一下,如果两个图像都比较大,这会像狗一样慢。我会使用 Lockbits 并按行而不是按列循环,因为这就是它在内存中的排列方式。
    【解决方案2】:

    您可以使用一组名为TestApi 的工具,这是一个帮助单元测试的开源库。其中一个 API 称为 Visual Verification API,它完全可以满足您的需求 - 它可以比较两个图像并告诉您它们是否相等:

    // 1. Capture the actual pixels from a given window
    Snapshot actual = Snapshot.FromRectangle(new Rectangle(0, 0, 100, 100));
    
    // 2. Load the reference/master data from a previously saved file
    Snapshot expected = Snapshot.FromFile("Expected.png"));
    
    // 3. Compare the actual image with the master image
    //    This operation creates a difference image. Any regions which are identical in 
    //    the actual and master images appear as black. Areas with significant 
    //    differences are shown in other colors.
    Snapshot difference = actual.CompareTo(expected);
    
    // 4. Configure the snapshot verifier - It expects a black image with zero tolerances
    SnapshotVerifier v = new SnapshotColorVerifier(Color.Black, new ColorDifference());
    
    // 5. Evaluate the difference image
    if (v.Verify(difference) == VerificationResult.Fail)
    {
        // Log failure, and save the diff file for investigation
        actual.ToFile("Actual.png", ImageFormat.Png);
        difference.ToFile("Difference.png", ImageFormat.Png);
    }
    

    【讨论】:

      【解决方案3】:

      我今天也有同样的问题,我的解决方法是将 image1 和 image2 转换为 256x256 或 128x128 都被翻译,然后生成一个具有它们之间差异的 image3,然后扫描 image3 检查差异并返回差异量,我发现图像的 LOWER 差异量更相等,并且它们更可能相等。这样,即使图像大小不同,您也可以识别图像是否相等。这是代码。

      double CompareImages(Bitmap InputImage1, Bitmap InputImage2, int Tollerance)
          {
              Bitmap Image1 = new Bitmap(InputImage1, new Size(128, 128));
              Bitmap Image2 = new Bitmap(InputImage2, new Size(128, 128));
              int Image1Size = Image1.Width * Image1.Height;
              int Image2Size = Image2.Width * Image2.Height;
              Bitmap Image3;
              if (Image1Size > Image2Size)
              {
                  Image1 = new Bitmap(Image1, Image2.Size);
                  Image3 = new Bitmap(Image2.Width, Image2.Height);
              }
              else
              {
                  Image1 = new Bitmap(Image1, Image2.Size);
                  Image3 = new Bitmap(Image2.Width, Image2.Height);
              }
              for (int x = 0; x < Image1.Width; x++)
              {
                  for (int y = 0; y < Image1.Height; y++)
                  {
                      Color Color1 = Image1.GetPixel(x, y);
                      Color Color2 = Image2.GetPixel(x, y);
                      int r = Color1.R > Color2.R ? Color1.R - Color2.R : Color2.R - Color1.R;
                      int g = Color1.G > Color2.G ? Color1.G - Color2.G : Color2.G - Color1.G;
                      int b = Color1.B > Color2.B ? Color1.B - Color2.B : Color2.B - Color1.B;
                      Image3.SetPixel(x, y, Color.FromArgb(r,g,b));
                  }
              }
              int Difference = 0;
              for (int x = 0; x < Image1.Width; x++)
              {
                  for (int y = 0; y < Image1.Height; y++)
                  {
                      Color Color1 = Image3.GetPixel(x, y);
                      int Media = (Color1.R + Color1.G + Color1.B) / 3;
                      if (Media > Tollerance)
                          Difference++;
                  }
              }
              double UsedSize = Image1Size > Image2Size ? Image2Size : Image1Size;
              double result = Difference*100/UsedSize;
              return Difference*100/UsedSize;
          }
      

      在这里测试了 900 多张图片,它就像一个魅力 x)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-21
        • 2022-09-30
        • 1970-01-01
        相关资源
        最近更新 更多