Skip to content

Commit cfd9a63

Browse files
authored
Test that two images are identical for the Seam Carving algorithm. (trekhleb#694)
* Test that two images are identical for the Seam Carving algorithm. * Tune the Seam Carving tests. * Tune the Seam Carving tests. * Tune the Seam Carving tests. * Tune the Seam Carving tests.
1 parent f0b246a commit cfd9a63

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/bin/sh
22
. "$(dirname "$0")/_/husky.sh"
33

4+
# @TODO: Implement the pre-commit checks.
45
# npm run lint
56
# npm run test

src/algorithms/image-processing/seam-carving/__tests__/resizeImageWidth.test.js

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,40 @@ import resizeImageWidth from '../resizeImageWidth';
44
const testImageBeforePath = './src/algorithms/image-processing/seam-carving/__tests__/test-image-before.jpg';
55
const testImageAfterPath = './src/algorithms/image-processing/seam-carving/__tests__/test-image-after.jpg';
66

7+
/**
8+
* Compares two images and finds the number of different pixels.
9+
*
10+
* @param {ImageData} imgA - ImageData for the first image.
11+
* @param {ImageData} imgB - ImageData for the second image.
12+
* @param {number} threshold - Color difference threshold [0..255]. Smaller - stricter.
13+
* @returns {number} - Number of different pixels.
14+
*/
15+
function pixelsDiff(imgA, imgB, threshold = 0) {
16+
if (imgA.width !== imgB.width || imgA.height !== imgB.height) {
17+
throw new Error('Images must have the same size');
18+
}
19+
20+
let differentPixels = 0;
21+
const numColorParams = 4; // RGBA
22+
23+
for (let pixelIndex = 0; pixelIndex < imgA.data.length; pixelIndex += numColorParams) {
24+
// Get pixel's color for each image.
25+
const [aR, aG, aB] = imgA.data.subarray(pixelIndex, pixelIndex + numColorParams);
26+
const [bR, bG, bB] = imgB.data.subarray(pixelIndex, pixelIndex + numColorParams);
27+
28+
// Get average pixel's color for each image (make them greyscale).
29+
const aAvgColor = Math.floor((aR + aG + aB) / 3);
30+
const bAvgColor = Math.floor((bR + bG + bB) / 3);
31+
32+
// Compare pixel colors.
33+
if (Math.abs(aAvgColor - bAvgColor) > threshold) {
34+
differentPixels += 1;
35+
}
36+
}
37+
38+
return differentPixels;
39+
}
40+
741
describe('resizeImageWidth', () => {
842
it('should perform content-aware image width reduction', () => {
943
// @see: https://jestjs.io/docs/asynchronous
@@ -21,6 +55,7 @@ describe('resizeImageWidth', () => {
2155
const canvasAfter = createCanvas(imgAfter.width, imgAfter.height);
2256
const ctxAfter = canvasAfter.getContext('2d');
2357
ctxAfter.drawImage(imgAfter, 0, 0, imgAfter.width, imgAfter.height);
58+
const imgDataAfter = ctxAfter.getImageData(0, 0, imgAfter.width, imgAfter.height);
2459

2560
const toWidth = Math.floor(imgBefore.width / 2);
2661

@@ -44,8 +79,13 @@ describe('resizeImageWidth', () => {
4479
expect(imgDataTest.width).toBe(imgAfter.width);
4580
expect(imgDataTest.height).toBe(imgAfter.height);
4681

47-
// @TODO: Check that images are identical.
48-
// expect(canvasTest.toDataURL()).toEqual(canvasAfter.toDataURL());
82+
const colorThreshold = 50;
83+
const differentPixels = pixelsDiff(imgDataTest, imgDataAfter, colorThreshold);
84+
85+
// Allow 10% of pixels to be different
86+
const pixelsThreshold = Math.floor((imgAfter.width * imgAfter.height) / 10);
87+
88+
expect(differentPixels).toBeLessThanOrEqual(pixelsThreshold);
4989
});
5090
});
5191
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy