Home | History | Annotate | Download | only in video_WebRtcPeerConnectionWithCamera
      1 /*
      2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree.
      7  */
      8 
      9 /* More information about these options at jshint.com/docs/options */
     10 'use strict';
     11 
     12 /* This is an implementation of the algorithm for calculating the Structural
     13  * SIMilarity (SSIM) index between two images. Please refer to the article [1],
     14  * the website [2] and/or the Wikipedia article [3]. This code takes the value
     15  * of the constants C1 and C2 from the Matlab implementation in [4].
     16  *
     17  * [1] Z. Wang, A. C. Bovik, H. R. Sheikh, and E. P. Simoncelli, "Image quality
     18  * assessment: From error measurement to structural similarity",
     19  * IEEE Transactions on Image Processing, vol. 13, no. 1, Jan. 2004.
     20  * [2] http://www.cns.nyu.edu/~lcv/ssim/
     21  * [3] http://en.wikipedia.org/wiki/Structural_similarity
     22  * [4] http://www.cns.nyu.edu/~lcv/ssim/ssim_index.m
     23  */
     24 
     25 function Ssim() {}
     26 
     27 Ssim.prototype = {
     28   // Implementation of Eq.2, a simple average of a vector and Eq.4., except the
     29   // square root. The latter is actually an unbiased estimate of the variance,
     30   // not the exact variance.
     31   statistics: function(a) {
     32     var accu = 0;
     33     var i;
     34     for (i = 0; i < a.length; ++i) {
     35       accu += a[i];
     36     }
     37     var meanA = accu / (a.length - 1);
     38     var diff = 0;
     39     for (i = 1; i < a.length; ++i) {
     40       diff = a[i - 1] - meanA;
     41       accu += a[i] + (diff * diff);
     42     }
     43     return {mean : meanA, variance : accu / a.length};
     44   },
     45 
     46   // Implementation of Eq.11., cov(Y, Z) = E((Y - uY), (Z - uZ)).
     47   covariance: function(a, b, meanA, meanB) {
     48     var accu = 0;
     49     for (var i = 0; i < a.length; i += 1) {
     50       accu += (a[i] - meanA) * (b[i] - meanB);
     51     }
     52     return accu / a.length;
     53   },
     54 
     55   calculate: function(x, y) {
     56     if (x.length !== y.length) {
     57       return 0;
     58     }
     59 
     60     // Values of the constants come from the Matlab code referred before.
     61     var K1 = 0.01;
     62     var K2 = 0.03;
     63     var L = 255;
     64     var C1 = (K1 * L) * (K1 * L);
     65     var C2 = (K2 * L) * (K2 * L);
     66     var C3 = C2 / 2;
     67 
     68     var statsX = this.statistics(x);
     69     var muX = statsX.mean;
     70     var sigmaX2 = statsX.variance;
     71     var sigmaX = Math.sqrt(sigmaX2);
     72     var statsY = this.statistics(y);
     73     var muY = statsY.mean;
     74     var sigmaY2 = statsY.variance;
     75     var sigmaY = Math.sqrt(sigmaY2);
     76     var sigmaXy = this.covariance(x, y, muX, muY);
     77 
     78     // Implementation of Eq.6.
     79     var luminance = (2 * muX * muY + C1) /
     80         ((muX * muX) + (muY * muY) + C1);
     81     // Implementation of Eq.10.
     82     var structure = (sigmaXy + C3) / (sigmaX * sigmaY + C3);
     83     // Implementation of Eq.9.
     84     var contrast = (2 * sigmaX * sigmaY + C2) / (sigmaX2 + sigmaY2 + C2);
     85 
     86     // Implementation of Eq.12.
     87     return luminance * contrast * structure;
     88   }
     89 };
     90