Question

I've red a few posts regarding image comparison, and I tried to save image captured from screen then store it in file system .

I used conversion methods to convert captured image into byte[] for later use .

Then when I want to compare it to second screen capture, I load (file saved into byte[]) and compare it against new capture that converted into byte[] in the same way.

Now when having both 1st capture and 2nd capture, in memory, there was few ways to do the comparison, I wanted firstly to share this post with others searching for the same answer and for me to know :

Which is faster, and how do I control the percentage of the similarity?

If the option to have percentage (of equality) is opposing the fastest way to compute... I can disregard it, although I could use it in other projects when performance issue is not there, and according to its needs

These are the codes I know available to do the task

I wanted to check with you for ideas which is faster and if there's a better way at all with and without equality percentage. Thank you.

static bool ByteArrayCompare(byte[] a1, byte[] a2)
{     
  IStructuralEquatable eqa1 = a1;     
  return eqa1.Equals(a2, StructuralComparisons.StructuralEqualityComparer); 
} 

vs

public enum CompareResult
{
  ciCompareOk,
  ciPixelMismatch,
  ciSizeMismatch
};

CompareResult cr = CompareResult.ciCompareOk;

byte[] hash1 = shaM.ComputeHash(btImage1);
byte[] hash2 = shaM.ComputeHash(btImage2);

//Compare the hash values
for (int i = 0; i < hash1.Length && i < hash2.Length 
                  && cr == CompareResult.ciCompareOk; i++)
{
    if (hash1[i] != hash2[i])
        cr = CompareResult.ciPixelMismatch;
}

the later is using System.Security.Cryptography

Was it helpful?

Solution

Comparing images and comparing byte arrays/file content are 2 different tasks as image format may wary. So assuming you are interested in byte comparison (i.e. if the same code used to capture images results should be the same). Otherwise you need to search for "compare images" questions (like one How to compare Image objects with C# .NET? suggested by Jensen Somers).

To compare byte arrays/files you will eventually need to compare byte content byte by byte. You can optimize checks to do nothing for cases when byte arrays/files will definitely not match and do byte compare only when strictly necessary:

  • check if sizes are the same
  • check hashes of arrays/files (cache computed hash values, since computing hash every time will not be any faster than byte-by-byte comparison). SHAxxxx hashes are good, but any reasonable hash function even several randomly taken bytes of arrays would do. With just picking values from array you may avoid caching hashes altogether.
  • compare fixed size chunk of arrays (i.e. somewhere in the middle for images) if you expect files to be different more often than the same.

If above says arrays/files could be the same (same length/hash/partial content) than compare arrays/files byte-by-byte.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top