Skip to content
This repository was archived by the owner on Jul 26, 2025. It is now read-only.

Commit 2b771f3

Browse files
authored
similarity (#396)
* feat: alignMinDifference returns the similarity * feat: add getNbNonZeroPixels method in Mask
1 parent ed84ed2 commit 2b771f3

File tree

4 files changed

+39
-8
lines changed

4 files changed

+39
-8
lines changed

src/Mask.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,20 @@ export class Mask {
327327
this.data[index * this.channels] = result;
328328
}
329329

330+
/**
331+
* Get the number of pixels that do not have the value 0.
332+
* @returns
333+
*/
334+
public getNbNonZeroPixels(): number {
335+
let count = 0;
336+
for (const datum of this.data) {
337+
if (datum) {
338+
count++;
339+
}
340+
}
341+
return count;
342+
}
343+
330344
/**
331345
* Get the value of a bit. Function exists for compatibility with Image.
332346
* @param column - Column index.

src/__tests__/Mask.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ describe('get and set bit', () => {
6262
expect(mask.getValueByPoint(point)).toBe(0);
6363
mask.setValueByPoint(point, 1);
6464
expect(mask.getValueByPoint(point)).toBe(1);
65+
expect(mask.getNbNonZeroPixels()).toBe(1);
6566
});
6667
});
6768

@@ -109,6 +110,7 @@ test('fill with a value', () => {
109110
[1, 1],
110111
[1, 1],
111112
]);
113+
expect(mask.getNbNonZeroPixels()).toBe(4);
112114
});
113115

114116
test('createFrom', () => {

src/align/__tests__/alignMinDifference.test.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ test('1 pixel source', () => {
1010
]);
1111

1212
const result = alignMinDifference(source, destination);
13-
expect(result).toStrictEqual({ row: 2, column: 1 });
13+
expect(result).toStrictEqual({ row: 2, column: 1, similarity: 1 });
1414
});
1515

1616
test('4 pixels source', () => {
@@ -25,7 +25,11 @@ test('4 pixels source', () => {
2525
]);
2626

2727
const result = alignMinDifference(source, destination);
28-
expect(result).toStrictEqual({ row: 1, column: 1 });
28+
expect(result).toStrictEqual({
29+
row: 1,
30+
column: 1,
31+
similarity: 0.8235294117647058,
32+
});
2933
});
3034

3135
test('twice same image', () => {
@@ -34,7 +38,7 @@ test('twice same image', () => {
3438
const destination = testUtils.load('opencv/test.png').grey();
3539

3640
const result = alignMinDifference(source, destination);
37-
expect(result).toStrictEqual({ row: 0, column: 0 });
41+
expect(result).toStrictEqual({ row: 0, column: 0, similarity: 1 });
3842
});
3943

4044
test('source too big', () => {
@@ -61,7 +65,7 @@ test('larger image and crop', () => {
6165

6266
const result = alignMinDifference(source, destination);
6367

64-
expect(result).toStrictEqual(origin);
68+
expect(result).toStrictEqual({ ...origin, similarity: 1 });
6569
});
6670

6771
test('larger image and crop 2', () => {
@@ -72,7 +76,7 @@ test('larger image and crop 2', () => {
7276

7377
const result = alignMinDifference(source, destination);
7478

75-
expect(result).toStrictEqual(origin);
79+
expect(result).toStrictEqual({ ...origin, similarity: 1 });
7680
});
7781

7882
test('id crops', () => {

src/align/alignMinDifference.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Image, Mask, Point } from '..';
1+
import { Image, Mask } from '..';
22
import checkProcessable from '../utils/validators/checkProcessable';
33

44
export interface AlignMinDifferenceOptions {
@@ -23,7 +23,7 @@ export function alignMinDifference(
2323
source: Image,
2424
destination: Image,
2525
options: AlignMinDifferenceOptions = {},
26-
): Point {
26+
) {
2727
checkProcessable(source, { components: 1, bitDepth: [8, 16], alpha: false });
2828

2929
const xSpan = destination.width - source.width;
@@ -51,6 +51,13 @@ export function alignMinDifference(
5151
let startY = 0;
5252
let endX = xSpan;
5353
let endY = ySpan;
54+
55+
if (mask && mask.size !== source.size) {
56+
throw new Error('Mask size must be equal to source size');
57+
}
58+
59+
const nbPixelsToCheck = mask ? mask.getNbNonZeroPixels() : source.size;
60+
5461
while (step >= 1) {
5562
step = Math.round(step);
5663

@@ -94,5 +101,9 @@ export function alignMinDifference(
94101
endY = Math.round(Math.min(ySpan, bestShiftY + step));
95102
}
96103

97-
return { row: bestShiftY, column: bestShiftX };
104+
return {
105+
row: bestShiftY,
106+
column: bestShiftX,
107+
similarity: 1 - bestDifference / (nbPixelsToCheck * source.maxValue),
108+
};
98109
}

0 commit comments

Comments
 (0)