Skip to content
This repository has been archived by the owner on Dec 7, 2023. It is now read-only.

Commit

Permalink
feat(weber): add Weber SSIM (follow-up) (#271)
Browse files Browse the repository at this point in the history
- This comment is a cleanup / formatting commit
- Flagged as "feat" to ensure we trigger a minor version from the
  previous one, which did add the Weber approach but somehow didn't
  trigger a release
  • Loading branch information
obartra authored Aug 20, 2020
1 parent ab46e09 commit ca72429
Show file tree
Hide file tree
Showing 54 changed files with 1,439 additions and 1,351 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"browser": "dist/ssim.web",
"version": "0.0.0-semantically-released",
"scripts": {
"format-all": "git ls-files {src,spec}*.{js,json} | xargs yarn format",
"format-all": "git ls-files {src,spec}*.{ts,js,json} | xargs yarn format",
"format": "prettier --write --single-quote --no-semi --trailing-comma es5",
"commit": "git-cz",
"test": "jest --testTimeout=500000",
Expand Down Expand Up @@ -77,4 +77,4 @@
"path": "node_modules/cz-conventional-changelog"
}
}
}
}
38 changes: 14 additions & 24 deletions spec/e2e/ivc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ describe("IVC", () => {
const expected = await getJSONScores(scores, path, "bmp");
const results = Object.entries(expected)
.map(([key, { file, reference }]): [string, number] => {
const { mssim } = ssim(reference, file, {ssim: "fast"});
const { mssim } = ssim(reference, file, { ssim: "fast" });

return [key, roundTo(mssim, 3)];
})
.reduce(
(acc, [key, result]) => ({
...acc,
[key]: result
[key]: result,
}),
{} as MSSIMValues
);
Expand All @@ -41,14 +41,12 @@ describe("IVC", () => {
.reduce(
(acc, [key, result]) => ({
...acc,
[key]: result
[key]: result,
}),
{} as MSSIMValues
);
//

const end = new Date().getTime();
// console.log(`Weber Total Time: ${end-start}`);
// console.log(`Weber Mean time: ${(end-start)/Object.keys(scores).length}`);
const referenceScores = scores as MSSIMValues;
const newV: any = {};
let newMean = 0;
Expand All @@ -60,19 +58,18 @@ describe("IVC", () => {
newV[score] = {
mssim: weberNewVal,
distance: distWeberNew,
ref: refVal
ref: refVal,
};
const newMeanR = newMean + (distWeberNew - newMean) / Object.keys(newV).length;
const newMeanR =
newMean + (distWeberNew - newMean) / Object.keys(newV).length;
newS = newS + (distWeberNew - newMean) * (distWeberNew - newMeanR);
newMean = newMeanR;
}


const newVar = newS / (Object.keys(newV).length - 1);
// console.log(`mean: ${newMean} variance: ${newVar}`);
// These came from the the calculated variances from the above commented console log
expect(roundTo(newMean,4 )).toEqual(0.0202);
expect(roundTo(newVar, 6)).toEqual(0.000211);

expect(roundTo(newMean, 4)).toMatchInlineSnapshot(`0.0202`);
expect(roundTo(newVar, 6)).toMatchInlineSnapshot(`0.000211`);
expect(results).toEqual(weberScores as MSSIMValues);
}, 70000);

Expand All @@ -87,14 +84,11 @@ describe("IVC", () => {
.reduce(
(acc, [key, result]) => ({
...acc,
[key]: result
[key]: result,
}),
{} as MSSIMValues
);
//
const end = new Date().getTime();
// console.log(`Bezkrovny Total Time: ${end-start}`);
// console.log(`Bezkrovny Mean time: ${(end-start)/Object.keys(scores).length}`);

const referenceScores = scores as MSSIMValues;
const newV: any = {};
Expand All @@ -107,19 +101,15 @@ describe("IVC", () => {
newV[score] = {
mssim: newVal,
distance: distNew,
ref: refVal
ref: refVal,
};
const meanR = newMean + (distNew - newMean) / Object.keys(newV).length;
newS = newS + (distNew - newMean) * (distNew - meanR);
newMean = meanR;
}
const newVar = newS / (Object.keys(newV).length - 1);
// console.log(`mean: ${newMean} variance: ${newVar}`);
// These came from the the calculated variances from the above commented console log
expect(roundTo(newMean, 4 )).toEqual(0.0155);
expect(roundTo(newVar, 6)).toEqual(0.000153);
expect(roundTo(newMean, 4)).toMatchInlineSnapshot(`0.0155`);
expect(roundTo(newVar, 6)).toMatchInlineSnapshot(`0.000153`);
expect(results).toEqual(bezkrovnyScores as MSSIMValues);
}, 70000);


});
42 changes: 21 additions & 21 deletions spec/helpers/getJSONScores.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { resolve, sep } from "path";
import { readdirSync } from "fs";
import { readpixels } from "./readpixels";
import { resolve, sep } from 'path'
import { readdirSync } from 'fs'
import { readpixels } from './readpixels'

export type LoadedData = {
file: ImageData;
mssim: number;
reference: ImageData;
};
file: ImageData
mssim: number
reference: ImageData
}

function filterFiles(file = "", extension: string) {
return file.toLowerCase().endsWith(extension);
function filterFiles(file = '', extension: string) {
return file.toLowerCase().endsWith(extension)
}

async function fileToObjectPath(
Expand All @@ -18,26 +18,26 @@ async function fileToObjectPath(
fileName: string,
extension: string
): Promise<{ [key: string]: LoadedData }> {
let referenceFile = (fileName.split(sep).pop() || "").split("_")[0] || "";
let referenceFile = (fileName.split(sep).pop() || '').split('_')[0] || ''

if (!referenceFile.endsWith(`.${extension}`)) {
referenceFile += `.${extension}`;
referenceFile += `.${extension}`
}

if (scores[fileName] === 0) {
return {};
return {}
}

const reference = resolve(path, referenceFile);
const file = resolve(path, fileName);
const reference = resolve(path, referenceFile)
const file = resolve(path, fileName)

return {
[fileName]: {
reference: await readpixels(reference),
file: await readpixels(file),
mssim: scores[fileName] || 0
}
};
mssim: scores[fileName] || 0,
},
}
}

export async function getJSONScores(
Expand All @@ -47,12 +47,12 @@ export async function getJSONScores(
) {
const objects = await Promise.all(
readdirSync(path)
.filter(file => filterFiles(file, extension))
.map(fileName => fileToObjectPath(scores, path, fileName, extension))
);
.filter((file) => filterFiles(file, extension))
.map((fileName) => fileToObjectPath(scores, path, fileName, extension))
)

return objects.reduce(
(acc, curr) => ({ ...acc, ...curr }),
{} as { [key: string]: LoadedData }
);
)
}
32 changes: 16 additions & 16 deletions spec/helpers/matrices.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import imageSamples from "./imageSamples.json";
import { loadCsv } from "./sampleloader";
import { flatMxToData } from "./util";
import imageSamples from './imageSamples.json'
import { loadCsv } from './sampleloader'
import { flatMxToData } from './util'

const sampleCsv = loadCsv({
lena: "./samples/lena/q1.csv",
lena02876: "./samples/lena/q02876.csv"
});
const samples = JSON.parse(JSON.stringify(imageSamples));
lena: './samples/lena/q1.csv',
lena02876: './samples/lena/q02876.csv',
})
const samples = JSON.parse(JSON.stringify(imageSamples))

Object.keys(samples).forEach(key => {
Object.keys(samples[key]).forEach(skey => {
samples[key][skey] = flatMxToData(samples[key][skey]);
});
});
Object.keys(sampleCsv).forEach(key => {
sampleCsv[key] = flatMxToData(sampleCsv[key]);
});
Object.keys(samples).forEach((key) => {
Object.keys(samples[key]).forEach((skey) => {
samples[key][skey] = flatMxToData(samples[key][skey])
})
})
Object.keys(sampleCsv).forEach((key) => {
sampleCsv[key] = flatMxToData(sampleCsv[key])
})

export { samples, sampleCsv };
export { samples, sampleCsv }
56 changes: 28 additions & 28 deletions spec/helpers/measure.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable no-console */
import Benchmark from "benchmark";
import Benchmark from 'benchmark'

export function measure(
expect: jest.Expect,
Expand All @@ -8,67 +8,67 @@ export function measure(
fast,
slow
) {
const results = {};
const results = {}
const suite = new Benchmark.Suite(testName, {
defer,
onError,
async: defer,
onComplete,
onCycle
});
onCycle,
})

suite.add(fast.name, {
defer,
fn: fast.fn
});
fn: fast.fn,
})

suite.add(slow.name, {
defer,
fn: slow.fn
});
fn: slow.fn,
})

suite.run({
defer,
async: defer
});
async: defer,
})

function onComplete() {
const fastest = this.filter("fastest").map("name");
const slowest = this.filter("slowest").map("name");
const fastest = this.filter('fastest').map('name')
const slowest = this.filter('slowest').map('name')

Object.keys(results).forEach(name => {
const { rme, hz } = results[name];
let icon = "";
Object.keys(results).forEach((name) => {
const { rme, hz } = results[name]
let icon = ''

if (fastest.includes(name)) {
icon = "🏍";
icon = '🏍'
} else if (slowest.includes(name)) {
icon = "🐌";
icon = '🐌'
}
console.log(` - ${name}: ${hz} ops/sec ±${rme}% ${icon}`);
});
console.log(` - ${name}: ${hz} ops/sec ±${rme}% ${icon}`)
})

let success;
let success
if (fastest.includes(fast.name) && slowest.includes(slow.name)) {
success = true;
success = true
} else if (fastest.includes(fast.name) && fastest.includes(slow.name)) {
success = true;
success = true
} else {
success = false;
success = false
}
expect(success).toBe(true);
expect(success).toBe(true)
}

function onCycle({ target }) {
results[target.name] = {
rme: Math.round(target.stats.rme),
count: target.count,
hz: target.hz.toFixed(2)
};
hz: target.hz.toFixed(2),
}
}

function onError() {
const success = false;
expect(success).toBe(true);
const success = false
expect(success).toBe(true)
}
}
Loading

0 comments on commit ca72429

Please sign in to comment.