title: JS - How to check if 2 images (their hash) are similar
body: <p><strong>GOAL</strong><br>
  Finding a good way to check if 2 image are similar compairing their <strong>hash</strong> profiles. The hash is a simple <strong>array</strong> containing <strong>0 and 1 values</strong>.</p>
  
  <p><strong>INTRO</strong><br>
  I have 2 images. They are the same image but with some <strong>little</strong> differences: one has a different brightness, rotation and shot.<br>
  What I want to do is create a Javascript method to compare the 2 images and calculate a <strong>percentage value</strong> that tells <strong>how much they are similar</strong>.</p>
  
  <p><strong>WHAT I'VE DONE</strong><br>
  After uploading the 2 images into a html5 canvas to get their <em>image data</em>, I've used the <strong>pHash</strong> algorithm (www.phash.org) to obtain their <strong>hash</strong> rapresentation.<br>
  The hash is an array containing 0 and 1 values that recreates the image in a "simplified" form.<br>
  I've also created a JS script that generates a html table with black cells where the array contains 1.<br>The result is the following screenshot (the image is a Van Gogh picture):</p>
  
  <p><a href="https://i.stack.imgur.com/1IjDQ.jpg" rel="nofollow noreferrer">Screenshot</a></p>
  
  <p>Now, what I should do is to compare the 2 arrays for obtaining a percentage value to know "how much" they are similar.<br>
  The most part of the hash Javascript algorithms I've found googling already have a compare algorithm: the <strong>hamming distance</strong> algorithm. It's very simple and fast, but not very precise. In fact, the hamming distance algorithm says that the 2 images in my screenshot have a <strong>67% of similarity</strong>. </p>
  
  <p><strong>THE QUESTION</strong><br>
  Starting with 2 simple arrays, with the same length, filled with 0 and 1 values: <em>what could be a good algorithm to determine similarity more precisely?</em></p>
  
  <p><strong>NOTES</strong><br>
  - Pure Javascript development, no third party plugins or framework.<br>
  - No need of a complex algorithm to find the right similarity when the 2 images are the same but they are very different (strong rotation, totaly different colors, etc.).<br><br>
  Thanx</p>
  
  <p><strong>PHASH CODE</strong><br></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>  // Size is the image size (for example 128px)
    var pixels = [];
  
    for (var i=0;i&lt;imgData.data.length;i+=4){
     
        var j = (i==0) ? 0 : i/4;
     var y = Math.floor(j/size);
     var x = j-(y*size);   
     
     var pixelPos = x + (y*size);
     var r = imgData.data[i];
     var g = imgData.data[i+1];
     var b = imgData.data[i+2];
  
     var gs = Math.floor((r*0.299)+(g*0.587)+(b*0.114));
     pixels[pixelPos] = gs;
        
    }
  
    var avg = Math.floor( array_sum(pixels) / pixels.length );
    var hash = [];
    array.forEach(pixels, function(px,i){
      if(px &gt; avg){
        hash[i] = 1;
      } else{
        hash[i] = 0;
      }
    });
  
    return hash;</code></pre>
  </div>
  </div>
  </p>
  
  <p><strong>HAMMING DISTANCE CODE</strong><br></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>  // hash1 and hash2 are the arrays of the "coded" images.
    
    var similarity = hash1.length;
    
    array.forEach(hash1, function(val,key){
      if(hash1[key] != hash2[key]){
        similarity--;
      }
    });
  
    var percentage = (similarity/hash1.length*100).toFixed(2);</code></pre>
  </div>
  </div>
  </p>
  
  <p>NOTE: array.forEach is not pure javascript. Consider it as a replace of: for (var i = 0; i &lt; array.length; i++).</p>