如何更改比较两个图像的方法以使其更快

本文关键字:方法 图像 两个 比较 何更改 | 更新日期: 2024-10-31 22:54:02

这是我今天使用的方法:

public static Bitmap CloudsOnly(Bitmap bitmapwithclouds, Bitmap bitmapwithoutclouds)
        {
            Color color;
            Color backgroundColor = Color.Black;
            CreateErrorsArray(bitmapwithclouds, bitmapwithoutclouds);
            int tolerance = tolerancenum * tolerancenumeric + tolerancenumeric * tolerancenumeric + tolerancenumeric * tolerancenumeric;
            Bitmap newbitmap = new Bitmap(512, 512);
            for (int x = 0; x < bitmapwithclouds.Width; x++)
            {
                for (int y = 0; y < bitmapwithclouds.Height; y++)
                {
                    int error = errorsArray[x, y];
                    if (error < tolerance)
                    {
                        color = backgroundColor;
                    }
                    else
                    {
                        color = bitmapwithclouds.GetPixel(x, y);
                    }
                    newbitmap.SetPixel(x, y, color);
                }
            }
            newbitmap.Save(@"d:'test'newbitmap.jpg");
            return newbitmap;
        }

但是GetPixel很慢,我搜索了谷歌,找到了一些使用LockBits的方法,例如这种方法:

private bool CompareBitmaps(Image left, Image right)
        {
            if (object.Equals(left, right))
                return true;
            if (left == null || right == null)
                return false;
            if (!left.Size.Equals(right.Size) || !left.PixelFormat.Equals(right.PixelFormat))
                return false;
            Bitmap leftBitmap = left as Bitmap;
            Bitmap rightBitmap = right as Bitmap;
            if (leftBitmap == null || rightBitmap == null)
                return true;
            #region Optimized code for performance
            int bytes = left.Width * left.Height * (Image.GetPixelFormatSize(left.PixelFormat) / 8);
            bool result = true;
            byte[] b1bytes = new byte[bytes];
            byte[] b2bytes = new byte[bytes];
            BitmapData bmd1 = leftBitmap.LockBits(new Rectangle(0, 0, leftBitmap.Width - 1, leftBitmap.Height - 1), ImageLockMode.ReadOnly, leftBitmap.PixelFormat);
            BitmapData bmd2 = rightBitmap.LockBits(new Rectangle(0, 0, rightBitmap.Width - 1, rightBitmap.Height - 1), ImageLockMode.ReadOnly, rightBitmap.PixelFormat);
            Marshal.Copy(bmd1.Scan0, b1bytes, 0, bytes);
            Marshal.Copy(bmd2.Scan0, b2bytes, 0, bytes);
            for (int n = 0; n <= bytes - 1; n++)
            {
                if (b1bytes[n] != b2bytes[n])
                {
                    result = false;
                    break;
                }
            }
            leftBitmap.UnlockBits(bmd1);
            rightBitmap.UnlockBits(bmd2);
            #endregion
            return result;
        }

但是这个只是告诉我一个图像是否与第二个图像相同。我想使用上面的方法,但使用LockBits或更快。

我怎样才能将上面的第一个方法更改为更快?

如何更改比较两个图像的方法以使其更快

GetPixel 非常慢,如果你有多个像素,并且你不想通过观看代码在图片中爬行来度过童年,请不要使用它。

您必须使用不安全的代码(非托管)才能快速访问图片。请参阅此帖子以获取帮助:使用不安全代码的 C# 位图

性能比较:C# 图像处理性能 - 不安全与安全代码,第二部分

我可以推荐一个幼稚的优化。您可以使用哈希函数,而不是手动比较结果数组中的每个字节。这意味着下一个代码:

 for (int n = 0; n <= bytes - 1; n++)
            {
                if (b1bytes[n] != b2bytes[n])
                {
                    result = false;
                    break;
                }
            }

可以替换为

var sha1 = new SHA1CryptoServiceProvider();
return sha1.ComputeHash(b1bytes) == sha1.ComputeHash(b2bytes);

内置哈希函数得到了很好的优化。