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

Commit 70e18b0

Browse files
feat: add getExtrema and removeClosePoints geometry utils (#412)
chore: fix eslint issues chore: improve watershed tests
1 parent 888503a commit 70e18b0

File tree

16 files changed

+216
-164
lines changed

16 files changed

+216
-164
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878
"autoprefixer": "^10.4.16",
7979
"clsx": "^2.0.0",
8080
"cross-env": "^7.0.3",
81-
"eslint": "^8.53.0",
81+
"eslint": "^8.55.0",
8282
"eslint-config-cheminfo-react": "^10.0.0",
8383
"eslint-config-cheminfo-typescript": "^12.0.4",
8484
"eslint-plugin-import": "^2.29.0",

src/compare/computeRmse.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function computeMse(image: Image, otherImage: Image): number {
2626
for (let i = 0; i < image.size; i++) {
2727
for (let channel = 0; channel < image.channels; channel++) {
2828
const value = difference.getValueByIndex(i, channel);
29-
sum += Math.pow(value, 2);
29+
sum += value ** 2;
3030
}
3131
}
3232
return sum / (image.size * image.channels);

src/compute/__tests__/getExtrema.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import getExtrema from '../getExtrema';
1+
import { getExtrema } from '../getExtrema';
22

33
test('minimum of grey image from legacy code', () => {
44
const image = testUtils.createGreyImage([

src/compute/getExtrema.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Image, Mask, Point } from '..';
22
import { assertUnreachable } from '../utils/validators/assert';
33
import checkProcessable from '../utils/validators/checkProcessable';
44

5-
interface ExtremaOptions {
5+
export interface ExtremaOptions {
66
/**
77
* Chooses what kind of extremum to compute.
88
* @default `'maximum'`
@@ -30,10 +30,7 @@ interface ExtremaOptions {
3030
* @param options - ExtremaOptions
3131
* @returns Array of Points.
3232
*/
33-
export default function getExtrema(
34-
image: Image,
35-
options: ExtremaOptions,
36-
): Point[] {
33+
export function getExtrema(image: Image, options: ExtremaOptions): Point[] {
3734
const { kind = 'maximum', mask, algorithm = 'star', maxEquals = 2 } = options;
3835
checkProcessable(image, {
3936
bitDepth: [8, 16],

src/compute/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './mean';
22
export * from './histogram';
33
export * from './median';
4+
export * from './getExtrema';

src/compute/variance.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ export function variance(image: Image): number[] {
1212
const sum = new Array(image.channels).fill(0);
1313
for (let i = 0; i < image.size; i++) {
1414
for (let channel = 0; channel < image.channels; channel++) {
15-
sum[channel] += Math.pow(
16-
image.getValueByIndex(i, channel) - mean[channel],
17-
2,
18-
);
15+
sum[channel] += (image.getValueByIndex(i, channel) - mean[channel]) ** 2;
1916
}
2017
}
2118

src/featureMatching/keypoints/getHarrisScore.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,6 @@ export function getHarrisScore(
6868

6969
return (
7070
eigenValues[0] * eigenValues[1] -
71-
harrisConstant * Math.pow(eigenValues[0] + eigenValues[1], 2)
71+
harrisConstant * (eigenValues[0] + eigenValues[1]) ** 2
7272
);
7373
}

src/featureMatching/visualize/__tests__/Montage.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ describe('constructor', () => {
1313
});
1414
it('should error when scale is not an integer', () => {
1515
expect(() => {
16-
new Montage(source, source, { scale: 1.5 });
16+
return new Montage(source, source, { scale: 1.5 });
1717
}).toThrow('scale must be an integer');
1818
});
1919
it('invalid disposition type', () => {
2020
expect(() => {
2121
// @ts-expect-error: invalid disposition type
22-
new Montage(source, source, { disposition: 'test' });
22+
return new Montage(source, source, { disposition: 'test' });
2323
}).toThrow('invalid disposition type: test');
2424
});
2525
});

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export * from './draw';
66
export * from './featureMatching';
77
export * from './filters';
88
export * from './geometry';
9+
export * from './utils/geometry';
910
export * from './Image';
1011
export * from './load';
1112
export * from './Mask';

src/roi/__tests__/computeRois.test.ts

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { fromMask } from '..';
1+
import { RoiMapManager, fromMask, waterShed } from '..';
2+
import { createGreyImage, getInt32Array } from '../../../test/testUtils';
23
import { computeRois } from '../computeRois';
34

45
test('3x3 mask', () => {
@@ -15,3 +16,50 @@ test('3x3 mask', () => {
1516
expect(roiMapManager.whiteRois).toMatchSnapshot();
1617
expect(roiMapManager.blackRois).toMatchSnapshot();
1718
});
19+
20+
test('test 2, waterShed for a grey image', () => {
21+
const image = createGreyImage([
22+
[3, 3, 3, 3, 3, 3, 3, 3, 4, 4],
23+
[3, 3, 2, 2, 2, 3, 3, 3, 4, 4],
24+
[4, 3, 2, 1, 2, 2, 3, 3, 4, 4],
25+
[4, 3, 2, 2, 2, 2, 3, 3, 3, 4],
26+
[4, 4, 4, 3, 2, 3, 2, 3, 3, 4],
27+
[4, 4, 4, 3, 3, 3, 3, 1, 3, 3],
28+
[4, 3, 3, 3, 3, 3, 2, 2, 2, 3],
29+
[4, 4, 3, 3, 3, 3, 2, 2, 2, 2],
30+
[4, 4, 4, 4, 3, 2, 2, 2, 2, 3],
31+
[4, 4, 4, 4, 3, 3, 3, 3, 2, 3],
32+
]);
33+
34+
const roiMapManager = waterShed(image, { threshold: 2 / 255 });
35+
36+
const result = new RoiMapManager({
37+
data: getInt32Array(`
38+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39+
0, 0, -1, -1, -1, 0, 0, 0, 0, 0,
40+
0, 0, -1, -1, -1, -1, 0, 0, 0, 0,
41+
0, 0, -1, -1, -1, -1, 0, 0, 0, 0,
42+
0, 0, 0, 0, -1, 0, 0, 0, 0, 0,
43+
0, 0, 0, 0, 0, 0, 0, -2, 0, 0,
44+
0, 0, 0, 0, 0, 0, -2, -2, -2, 0,
45+
0, 0, 0, 0, 0, 0, -2, -2, -2, -2,
46+
0, 0, 0, 0, 0, -2, -2, -2, -2, 0,
47+
0, 0, 0, 0, 0, 0, 0, 0, -2, 0
48+
`),
49+
nbPositive: 0,
50+
nbNegative: 2,
51+
width: 10,
52+
height: 10,
53+
});
54+
expect(roiMapManager).toStrictEqual(result);
55+
computeRois(roiMapManager);
56+
57+
expect(roiMapManager.blackRois[0].origin).toStrictEqual({
58+
column: 2,
59+
row: 1,
60+
});
61+
expect(roiMapManager.blackRois[1].origin).toStrictEqual({
62+
column: 5,
63+
row: 5,
64+
});
65+
});

0 commit comments

Comments
 (0)