summaryrefslogtreecommitdiff
path: root/js/vendor/image-ssim.js
diff options
context:
space:
mode:
authorJules Laplace <jules@okfoc.us>2016-05-23 01:07:46 -0400
committerJules Laplace <jules@okfoc.us>2016-05-23 01:07:46 -0400
commitcbe5a189dca1c228186fb1e433071578614c4e91 (patch)
tree8e878e1febe2a35dbe97fa71f4ae8e78009fbedc /js/vendor/image-ssim.js
parent7ac0cf096e9b9f0ff0c15968e7f04caeeb220f36 (diff)
genetic algorhehrithm
Diffstat (limited to 'js/vendor/image-ssim.js')
-rw-r--r--js/vendor/image-ssim.js129
1 files changed, 129 insertions, 0 deletions
diff --git a/js/vendor/image-ssim.js b/js/vendor/image-ssim.js
new file mode 100644
index 0000000..e1f07b4
--- /dev/null
+++ b/js/vendor/image-ssim.js
@@ -0,0 +1,129 @@
+var ImageSSIM;
+(function (ImageSSIM) {
+ 'use strict';
+ /**
+ * Grey = 1, GreyAlpha = 2, RGB = 3, RGBAlpha = 4
+ */
+ (function (Channels) {
+ Channels[Channels["Grey"] = 1] = "Grey";
+ Channels[Channels["GreyAlpha"] = 2] = "GreyAlpha";
+ Channels[Channels["RGB"] = 3] = "RGB";
+ Channels[Channels["RGBAlpha"] = 4] = "RGBAlpha";
+ })(ImageSSIM.Channels || (ImageSSIM.Channels = {}));
+ var Channels = ImageSSIM.Channels;
+ /**
+ * Entry point.
+ * @throws new Error('Images have different sizes!')
+ */
+ function compare(image1, image2, windowSize, K1, K2, luminance, bitsPerComponent) {
+ if (windowSize === void 0) { windowSize = 8; }
+ if (K1 === void 0) { K1 = 0.01; }
+ if (K2 === void 0) { K2 = 0.03; }
+ if (luminance === void 0) { luminance = true; }
+ if (bitsPerComponent === void 0) { bitsPerComponent = 8; }
+ if (image1.width !== image2.width || image1.height !== image2.height) {
+ throw new Error('Images have different sizes!');
+ }
+ /* tslint:disable:no-bitwise */
+ var L = (1 << bitsPerComponent) - 1;
+ /* tslint:enable:no-bitwise */
+ var c1 = Math.pow((K1 * L), 2), c2 = Math.pow((K2 * L), 2), numWindows = 0, mssim = 0.0;
+ var mcs = 0.0;
+ function iteration(lumaValues1, lumaValues2, averageLumaValue1, averageLumaValue2) {
+ // calculate variance and covariance
+ var sigxy, sigsqx, sigsqy;
+ sigxy = sigsqx = sigsqy = 0.0;
+ for (var i = 0; i < lumaValues1.length; i++) {
+ sigsqx += Math.pow((lumaValues1[i] - averageLumaValue1), 2);
+ sigsqy += Math.pow((lumaValues2[i] - averageLumaValue2), 2);
+ sigxy += (lumaValues1[i] - averageLumaValue1) * (lumaValues2[i] - averageLumaValue2);
+ }
+ var numPixelsInWin = lumaValues1.length - 1;
+ sigsqx /= numPixelsInWin;
+ sigsqy /= numPixelsInWin;
+ sigxy /= numPixelsInWin;
+ // perform ssim calculation on window
+ var numerator = (2 * averageLumaValue1 * averageLumaValue2 + c1) * (2 * sigxy + c2);
+ var denominator = (Math.pow(averageLumaValue1, 2) + Math.pow(averageLumaValue2, 2) + c1) * (sigsqx + sigsqy + c2);
+ mssim += numerator / denominator;
+ mcs += (2 * sigxy + c2) / (sigsqx + sigsqy + c2);
+ numWindows++;
+ }
+ // calculate SSIM for each window
+ Internals._iterate(image1, image2, windowSize, luminance, iteration);
+ return { ssim: mssim / numWindows, mcs: mcs / numWindows };
+ }
+ ImageSSIM.compare = compare;
+ /**
+ * Internal functions.
+ */
+ var Internals;
+ (function (Internals) {
+ function _iterate(image1, image2, windowSize, luminance, callback) {
+ var width = image1.width, height = image1.height;
+ for (var y = 0; y < height; y += windowSize) {
+ for (var x = 0; x < width; x += windowSize) {
+ // avoid out-of-width/height
+ var windowWidth = Math.min(windowSize, width - x), windowHeight = Math.min(windowSize, height - y);
+ var lumaValues1 = _lumaValuesForWindow(image1, x, y, windowWidth, windowHeight, luminance), lumaValues2 = _lumaValuesForWindow(image2, x, y, windowWidth, windowHeight, luminance), averageLuma1 = _averageLuma(lumaValues1), averageLuma2 = _averageLuma(lumaValues2);
+ callback(lumaValues1, lumaValues2, averageLuma1, averageLuma2);
+ }
+ }
+ }
+ Internals._iterate = _iterate;
+ function _lumaValuesForWindow(image, x, y, width, height, luminance) {
+ var array = image.data, lumaValues = new Float32Array(new ArrayBuffer(width * height * 4)), counter = 0;
+ var maxj = y + height;
+ for (var j = y; j < maxj; j++) {
+ var offset = j * image.width;
+ var i = (offset + x) * image.channels;
+ var maxi = (offset + x + width) * image.channels;
+ switch (image.channels) {
+ case 1 /* Grey */:
+ while (i < maxi) {
+ // (0.212655 + 0.715158 + 0.072187) === 1
+ lumaValues[counter++] = array[i++];
+ }
+ break;
+ case 2 /* GreyAlpha */:
+ while (i < maxi) {
+ lumaValues[counter++] = array[i++] * (array[i++] / 255);
+ }
+ break;
+ case 3 /* RGB */:
+ if (luminance) {
+ while (i < maxi) {
+ lumaValues[counter++] = (array[i++] * 0.212655 + array[i++] * 0.715158 + array[i++] * 0.072187);
+ }
+ }
+ else {
+ while (i < maxi) {
+ lumaValues[counter++] = (array[i++] + array[i++] + array[i++]);
+ }
+ }
+ break;
+ case 4 /* RGBAlpha */:
+ if (luminance) {
+ while (i < maxi) {
+ lumaValues[counter++] = (array[i++] * 0.212655 + array[i++] * 0.715158 + array[i++] * 0.072187) * (array[i++] / 255);
+ }
+ }
+ else {
+ while (i < maxi) {
+ lumaValues[counter++] = (array[i++] + array[i++] + array[i++]) * (array[i++] / 255);
+ }
+ }
+ break;
+ }
+ }
+ return lumaValues;
+ }
+ function _averageLuma(lumaValues) {
+ var sumLuma = 0.0;
+ for (var i = 0; i < lumaValues.length; i++) {
+ sumLuma += lumaValues[i];
+ }
+ return sumLuma / lumaValues.length;
+ }
+ })(Internals || (Internals = {}));
+})(ImageSSIM || (ImageSSIM = {})); \ No newline at end of file