| /* |
| * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. |
| */ |
| |
| /* More information about these options at jshint.com/docs/options */ |
| 'use strict'; |
| |
| /* This is an implementation of the algorithm for calculating the Structural |
| * SIMilarity (SSIM) index between two images. Please refer to the article [1], |
| * the website [2] and/or the Wikipedia article [3]. This code takes the value |
| * of the constants C1 and C2 from the Matlab implementation in [4]. |
| * |
| * [1] Z. Wang, A. C. Bovik, H. R. Sheikh, and E. P. Simoncelli, "Image quality |
| * assessment: From error measurement to structural similarity", |
| * IEEE Transactions on Image Processing, vol. 13, no. 1, Jan. 2004. |
| * [2] http://www.cns.nyu.edu/~lcv/ssim/ |
| * [3] http://en.wikipedia.org/wiki/Structural_similarity |
| * [4] http://www.cns.nyu.edu/~lcv/ssim/ssim_index.m |
| */ |
| |
| function Ssim() {} |
| |
| Ssim.prototype = { |
| // Implementation of Eq.2, a simple average of a vector and Eq.4., except the |
| // square root. The latter is actually an unbiased estimate of the variance, |
| // not the exact variance. |
| statistics: function(a) { |
| var accu = 0; |
| var i; |
| for (i = 0; i < a.length; ++i) { |
| accu += a[i]; |
| } |
| var meanA = accu / (a.length - 1); |
| var diff = 0; |
| for (i = 1; i < a.length; ++i) { |
| diff = a[i - 1] - meanA; |
| accu += a[i] + (diff * diff); |
| } |
| return {mean : meanA, variance : accu / a.length}; |
| }, |
| |
| // Implementation of Eq.11., cov(Y, Z) = E((Y - uY), (Z - uZ)). |
| covariance: function(a, b, meanA, meanB) { |
| var accu = 0; |
| for (var i = 0; i < a.length; i += 1) { |
| accu += (a[i] - meanA) * (b[i] - meanB); |
| } |
| return accu / a.length; |
| }, |
| |
| calculate: function(x, y) { |
| if (x.length !== y.length) { |
| return 0; |
| } |
| |
| // Values of the constants come from the Matlab code referred before. |
| var K1 = 0.01; |
| var K2 = 0.03; |
| var L = 255; |
| var C1 = (K1 * L) * (K1 * L); |
| var C2 = (K2 * L) * (K2 * L); |
| var C3 = C2 / 2; |
| |
| var statsX = this.statistics(x); |
| var muX = statsX.mean; |
| var sigmaX2 = statsX.variance; |
| var sigmaX = Math.sqrt(sigmaX2); |
| var statsY = this.statistics(y); |
| var muY = statsY.mean; |
| var sigmaY2 = statsY.variance; |
| var sigmaY = Math.sqrt(sigmaY2); |
| var sigmaXy = this.covariance(x, y, muX, muY); |
| |
| // Implementation of Eq.6. |
| var luminance = (2 * muX * muY + C1) / |
| ((muX * muX) + (muY * muY) + C1); |
| // Implementation of Eq.10. |
| var structure = (sigmaXy + C3) / (sigmaX * sigmaY + C3); |
| // Implementation of Eq.9. |
| var contrast = (2 * sigmaX * sigmaY + C2) / (sigmaX2 + sigmaY2 + C2); |
| |
| // Implementation of Eq.12. |
| return luminance * contrast * structure; |
| } |
| }; |