简体   繁体   中英

How can i change the method that compare two images to be faster?

This is the method im using today:

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;
        }

But GetPixel is slow i searched google and found some methods using LockBits for example this method:

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;
        }

But this one just tell me if one image is the same like the second one. I want to use my method above but with LockBits or some way faster.

How can i change my method the first one above to be faster ?

GetPixel is terrible slow, don't use it if you have more than one pixel and you don't want to spend your childhood by watching your code crawling through a picture.

You have to use unsafe code (unmanaged) for fast accessing of picture. See this post for help: C# Bitmap using unsafe code

Performance comparison: C# Image Processing Performance - Unsafe vs. Safe code, Part II

I can recommend one naive optimization. Instead of manualy comparing each byte in resulting array you can use hash funciton. It means that next code:

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

can be replaced with

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

Build in hash functions are well optimized.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM