【问题标题】:Find differences between images查找图像之间的差异
【发布时间】:2013-04-27 11:46:41
【问题描述】:

假设我有两个几乎相同的图像,我想定位并突出它们之间的差异并生成差异图像。该例程有效,但该例程要求提供我不想要的颜色。这是我的代码。

public class ImageTool
{
    public static unsafe Bitmap GetDifferenceImage(Bitmap image1, Bitmap image2, Color matchColor)
    {
        if (image1 == null | image2 == null)
            return null;

        if (image1.Height != image2.Height || image1.Width != image2.Width)
            return null;

        Bitmap diffImage = image2.Clone() as Bitmap;

        int height = image1.Height;
        int width = image1.Width;

        BitmapData data1 = image1.LockBits(new Rectangle(0, 0, width, height), 
                                           ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
        BitmapData data2 = image2.LockBits(new Rectangle(0, 0, width, height), 
                                           ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
        BitmapData diffData = diffImage.LockBits(new Rectangle(0, 0, width, height), 
                                               ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

        byte* data1Ptr = (byte*)data1.Scan0;
        byte* data2Ptr = (byte*)data2.Scan0;
        byte* diffPtr = (byte*)diffData.Scan0;

        byte[] swapColor = new byte[3];
        swapColor[0] = matchColor.B;
        swapColor[1] = matchColor.G;
        swapColor[2] = matchColor.R;

        int rowPadding = data1.Stride - (image1.Width * 3);

        // iterate over height (rows)
        for (int i = 0; i < height; i++)
        {
            // iterate over width (columns)
            for (int j = 0; j < width; j++)
            {
                int same = 0;

                byte[] tmp = new byte[3];

                // compare pixels and copy new values into temporary array
                for (int x = 0; x < 3; x++)
                {
                    tmp[x] = data2Ptr[0];
                    if (data1Ptr[0] == data2Ptr[0])
                    {
                        same++;
                    }
                    data1Ptr++; // advance image1 ptr
                    data2Ptr++; // advance image2 ptr
                }

                // swap color or add new values
                for (int x = 0; x < 3; x++)
                {
                    diffPtr[0] = (same == 3) ? swapColor[x] : tmp[x];
                    diffPtr++; // advance diff image ptr
                }
            }

            // at the end of each column, skip extra padding
            if (rowPadding > 0)
            {
                data1Ptr += rowPadding;
                data2Ptr += rowPadding;
                diffPtr += rowPadding;
            }
        }

        image1.UnlockBits(data1);
        image2.UnlockBits(data2);
        diffImage.UnlockBits(diffData);

        return diffImage;
    }
}

这样调用:

Bitmap diff = ImageTool.GetDifferenceImage(image1, image2, Color.Pink);
diff.MakeTransparent(Color.Pink);
diff.Save("C:\\test-diff.png",ImageFormat.Png);
  1. 有人只是指导我如何更改此例程,因此当我调用 GetDifferenceImage() 方法时我们不必传递颜色。

  2. 这种方式图像比较是最好的技术,如果不是,那么指导我如何开发一个可以更快地获取差异图像的例程。

  3. 获得差异图像后,如何将差异图像与image1 合并。帮助我开发一个更快的合并例程。

【问题讨论】:

  • 问题太多但不是很清楚:) 你打算在函数内部硬编码颜色而不是传递它吗?
  • 我不想传递颜色或硬编码,而是更改不依赖颜色进行图像比较的例程。我说清楚了吗?
  • 据我所见,代码比较了 2 个图像并生成了所有差异都突出显示的结果图像。要突出显示的颜色被发送到该方法。如果您没有传递或硬编码颜色,方法如何知道使用哪种颜色?

标签: c# image-processing


【解决方案1】:

如果两个图像相同,则差异图像是黑色的,并且差异较大的像素的亮度会增加。您可以更改算法,而不是为像素分配交换颜色,而是为其分配两种颜色之间的差异。

    // iterate over height (rows)
    for (int i = 0; i < height; i++)
    {
        // iterate over width (columns)
        for (int j = 0; j < width; j++)
        {
            // for each channel
            for (int x=0; x<3; x++)
            {
                diffPtr[0] = Abs(data1Ptr[0]-data2Ptr[0]);
                data1Ptr++; // advance image1 ptr
                data2Ptr++; // advance image2 ptr
                diffPtr++; // advance diff image ptr
            }
        }

        // at the end of each column, skip extra padding
        if (rowPadding > 0)
        {
            data1Ptr += rowPadding;
            data2Ptr += rowPadding;
            diffPtr += rowPadding;
        }
    }

您如何显示/合并差异取决于您将如何处理它。

【讨论】:

  • 你想让我用你的代码替换它。你能按照你的方式为我的名为 GetDifferenceImage() 的例程编写完整的代码吗?谢谢
  • @Mou 只需将代码中的 for 循环替换为上面的循环并删除 matchColor 参数,不再需要 swapColor 变量。
  • 非常抱歉,您的代码对我没有帮助。最好你运行你的代码。只需拍摄两张非常接近的相同 png 图片并将这两张图片与您的代码进行比较,然后查看生成的图片。
  • @Mou 我知道结果是什么。您需要决定如何展示差异并以这种方式进行。
猜你喜欢
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多