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

Commit a6032d4

Browse files
committed
feat(alignMinDiff): extend to any nb of components
Closes: #402
1 parent bdea5fb commit a6032d4

File tree

2 files changed

+37
-17
lines changed

2 files changed

+37
-17
lines changed

src/align/__tests__/alignMinDifference.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,19 @@ test('other id crops', () => {
9898
const overlap = overlapImages(source, destination, { origin: result });
9999
expect(overlap).toMatchImageSnapshot();
100100
});
101+
102+
test('RGB images', () => {
103+
const destination = testUtils.createRgbImage([
104+
[255, 255, 0, 255, 0, 0, 255, 0, 0],
105+
[255, 0, 0, 255, 0, 0, 255, 0, 0],
106+
[255, 0, 0, 255, 0, 0, 255, 0, 0],
107+
]);
108+
109+
const source = testUtils.createRgbImage([[255, 255, 0]]);
110+
111+
const result = alignMinDifference(source, destination, {
112+
startStep: 1,
113+
});
114+
115+
expect(result).toStrictEqual({ row: 0, column: 0, similarity: 1 });
116+
});

src/align/alignMinDifference.ts

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export interface AlignMinDifferenceOptions {
1111
}
1212

1313
/**
14-
* Aligns two grayscale images by finding the translation that minimizes the mean difference
14+
* Aligns two images by finding the translation that minimizes the mean difference of all channels.
1515
* between them. The source image should fit entirely in the destination image.
1616
* @param source - Image to align.
1717
* @param destination - Image to align to.
@@ -24,7 +24,9 @@ export function alignMinDifference(
2424
destination: Image,
2525
options: AlignMinDifferenceOptions = {},
2626
) {
27-
checkProcessable(source, { components: 1, bitDepth: [8, 16], alpha: false });
27+
checkProcessable(source, {
28+
bitDepth: [8, 16],
29+
});
2830

2931
const xSpan = destination.width - source.width;
3032
const ySpan = destination.height - source.height;
@@ -69,21 +71,23 @@ export function alignMinDifference(
6971
if (mask && !mask.getBit(column, row)) {
7072
continue;
7173
}
72-
const sourceValue = source.getValue(column, row, 0);
73-
const destinationValue = destination.getValue(
74-
column + shiftX,
75-
row + shiftY,
76-
0,
77-
);
78-
const difference = sourceValue - destinationValue;
79-
if (difference < 0) {
80-
// Math.abs is super slow, this simple trick is 5x faster
81-
currentDifference -= difference;
82-
} else {
83-
currentDifference += difference;
84-
}
85-
if (currentDifference > bestDifference) {
86-
break next;
74+
for (let channel = 0; channel < source.channels; channel++) {
75+
const sourceValue = source.getValue(column, row, channel);
76+
const destinationValue = destination.getValue(
77+
column + shiftX,
78+
row + shiftY,
79+
channel,
80+
);
81+
const difference = sourceValue - destinationValue;
82+
if (difference < 0) {
83+
// Math.abs is super slow, this simple trick is 5x faster
84+
currentDifference -= difference;
85+
} else {
86+
currentDifference += difference;
87+
}
88+
if (currentDifference > bestDifference) {
89+
break next;
90+
}
8791
}
8892
}
8993
}

0 commit comments

Comments
 (0)