ItFreak
ItFreak

Reputation: 2369

C# check images are equal with tolerance

I have this code where I send images from a thermal camera. getImage() returns the actual image that is provided by the camera. There is no possibility to check directly if the camera can provide a 'new' image, so I did this method to compare two images:

class ImageCompare
    {
        public enum CompareResult
        {
            CompareOK,
            SizeMismatch,
            PixelMismatch
        };

        public static CompareResult CompareImages(Image i1, Image i2)
        {
            CompareResult cr = CompareResult.CompareOK;

            if (i1.Size != i2.Size)
            {
                cr = CompareResult.SizeMismatch;
            }
            else
            {
                ImageConverter ic = new ImageConverter();
                byte[] btImage1 = new byte[1];
                btImage1 = (byte[])ic.ConvertTo(i1, btImage1.GetType());
                byte[] btImage2 = new byte[1];
                btImage2 = (byte[])ic.ConvertTo(i2, btImage2.GetType());

                //compute hashes
                SHA256Managed shaM = new SHA256Managed();
                byte[] hash1 = shaM.ComputeHash(btImage1);
                byte[] hash2 = shaM.ComputeHash(btImage2);

                for (int i = 0; i < hash1.Length && i < hash2.Length
                                  && cr == CompareResult.CompareOK; i++)
                {
                    if (hash1[i] != hash2[i])
                        cr = CompareResult.PixelMismatch;
                }
            }
            return cr;
        }
    }

and here is how I use this class:

private static void HandleImageSending(Socket client, Socket s)
        {
            int sent;
            int imageCount = 0;
            long totalSize = 0;
            try
            {
                while (true)
                {
                    Console.WriteLine("Starting sending...");
                    Image old = getImage();
                    byte[] bmpBytes;
                    using (Image bmp = getImage())
                    using (MemoryStream ms = new MemoryStream())
                    {
                        if (ImageCompare.CompareImages(bmp, old) == ImageCompare.CompareResult.CompareOK)
                        {
                            bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                            bmpBytes = ms.ToArray();
                            sent = SendVarData(client, bmpBytes);
                            imageCount++;
                            totalSize += sent;
                            old = bmp;
                        }
                    }
                }
            }
            catch (Exception e)
            { ... }

So my problem is that comparing by hash results in 'different' images in about 19 of 20 cases. Since the camera provides only 8 fps, there must be something wrong.

Is there a possibility of comparing with a kind of tolerance, so let's say 5 or 10 percent of the compared new image may differ to the old?

Since this is used on a mini PC, I would like to use the smallest CPU load possible. What can I try next?

Upvotes: 2

Views: 748

Answers (1)

Bacon
Bacon

Reputation: 483

indexing the image (and decreasing the size) should give the same result for similar images

using

Bitmap imgtarget = imgsource.Clone(
    new Rectangle(0, 0, imgsource.Width, imgsource.Height),
    PixelFormat.Format8bppIndexed);

from another stackoverflow

Upvotes: 2

Related Questions