title: Which SSIM is correct : skimage.metrics.structural_similarity()?
body: <p>Stackoverflow comunity,</p>
  <p>I'm trying to compute SSIM (Structural SIMilarity) between two <code>bmp</code> images on Python. I've found <a href="https://scikit-image.org/docs/dev/api/skimage.metrics.html#skimage.metrics.structural_similarity" rel="noreferrer">structural_similarity()</a> function implemented in the <code>skimage</code> python library  and the equivalent code from the original <code>MatLab</code> implementation which is <a href="https://ece.uwaterloo.ca/%7Ez70wang/research/ssim/ssim_index.m" rel="noreferrer">hosted here</a>. The implimentation is right bellow:</p>
  <pre><code>def structuralSimilarityIndex(ref_image, impaired_image, cs_map=False):
  
      window = Metric.fSpecialGauss(constant.SSIM_FILTER_SIZE,
                                    constant.SSIM_FILTER_SIGMA)
      C1 = (constant.SSIM_Constant_1 * constant.PIXEL_MAX) ** 2
      C2 = (constant.SSIM_Constant_2 * constant.PIXEL_MAX) ** 2
  
      mu1 = signal.fftconvolve(window, ref_image, mode='valid')
      mu2 = signal.fftconvolve(window, impaired_image, mode='valid')
  
      mu1_sq = mu1 * mu1
      mu2_sq = mu2 * mu2
      mu1_mu2 = mu1 * mu2
  
      sigma1_sq = signal.fftconvolve(
          window, ref_image*ref_image, mode='valid') - mu1_sq
      sigma2_sq = signal.fftconvolve(
          window, impaired_image*impaired_image, mode='valid') - mu2_sq
      sigma12 = signal.fftconvolve(
          window, ref_image*impaired_image, mode='valid') - mu1_mu2
  
      if cs_map:
          return (((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) * (sigma1_sq + sigma2_sq + C2)), (2.0 * sigma12 + C2) / (sigma1_sq + sigma2_sq + C2))
      else:
          return np.mean(((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) * (sigma1_sq + sigma2_sq + C2)))
  </code></pre>
  <p>I'm reading  the images using this piece of code :</p>
  <pre><code>ref_image = np.asfarray(Image.open('ref_image.bmp').convert('L'))
  impaired_image = np.asfarray(Image.open('impaired_image.bmp').covert('L)
  </code></pre>
  <p>The input images shape and <code>dtype</code> of both <code>ref_image</code> and <code>impaired_image</code>  are respectively:</p>
  <blockquote>
  <p>(512, 512) float64</p>
  <p>(512, 512) float64</p>
  </blockquote>
  <p>I've tested both using the same condition and same input images as follow:</p>
  <pre><code># Using the above code
  structuralSimilarityIndex(ref_image, impaired_image, cs_map=False)
  
  # Using the function imported from skimage.metrics
  structural_similarity(ref_image, impaired_image, gaussian_weights=False, use_sample_covariance=False)
  </code></pre>
  <p>the result was so much different, here the results:</p>
  <p>The SSIM from the <code>Skimage</code> python library:</p>
  <blockquote>
  <p>SSIM :  0.38135154028457885</p>
  </blockquote>
  <p>The SSIM from the code above:</p>
  <blockquote>
  <p>SSIM : 0.8208087737160036</p>
  </blockquote>
  <p><strong>EDIT:</strong></p>
  <p>I've added the reading and calling code</p>
  <p>The above Python code was from the <a href="http://mubeta06.github.io/python/sp/_modules/sp/ssim.html" rel="noreferrer">signal processing library</a>, which is according to the author, the function attempts to mimic precisely the functionality of ssim.m a MATLAB provided by the author's of SSIM</p>
  <p><strong>Update</strong> :</p>
  <p>I've tested the original code which is writing in MatLab on the same images and the result is as follow :</p>
  <blockquote>
  <p>SSIM : 0.8424</p>
  </blockquote>
  <p>Which is not far from the result of the Python implementation given above.</p>