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

Commit 4b0464d

Browse files
opatinytargos
andauthored
fix: handle 0 to 1 threshold (#290)
* fix: handle 0 to 1 threshold Closes: #288 * feat: allow threshold only from 0 to 1 * chore: fix prettier * Update src/operations/threshold.ts Co-authored-by: Michaël Zasso <[email protected]> * test: fix error messages --------- Co-authored-by: Michaël Zasso <[email protected]>
1 parent fedba43 commit 4b0464d

File tree

8 files changed

+16
-46
lines changed

8 files changed

+16
-46
lines changed

demo/components/testFunctions/testGetConvexHull.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { fromMask, Image } from '../../../src';
88
*/
99
export function testGetConvexHull(image: Image): Image {
1010
const grey = image.convertColor('GREY');
11-
const mask = grey.threshold({ threshold: 35 });
11+
const mask = grey.threshold({ threshold: 35 / 255 });
1212
const roiMapManager = fromMask(mask);
1313

1414
const rois = roiMapManager.getRois({ kind: 'black' });

demo/components/testFunctions/testGetFeret.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { fromMask, Image } from '../../../src';
88
*/
99
export function testGetFeret(image: Image): Image {
1010
const grey = image.convertColor('GREY');
11-
const mask = grey.threshold({ threshold: 35 });
11+
const mask = grey.threshold({ threshold: 35 / 255 });
1212
const roiMapManager = fromMask(mask);
1313

1414
const rois = roiMapManager.getRois({ kind: 'black' });

demo/components/testFunctions/testGetMbr.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { fromMask, Image } from '../../../src';
88
*/
99
export function testGetMbr(image: Image): Image {
1010
const grey = image.convertColor('GREY');
11-
const mask = grey.threshold({ threshold: 35 });
11+
const mask = grey.threshold({ threshold: 35 / 255 });
1212
const roiMapManager = fromMask(mask);
1313

1414
const rois = roiMapManager.getRois({ kind: 'black' });

demo/components/testFunctions/testPaintMask.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { fromMask, Image } from '../../../src';
66
*/
77
export function testPaintMask(image: Image): Image {
88
const grey = image.convertColor('GREY');
9-
const mask = grey.threshold({ threshold: 100 });
9+
const mask = grey.threshold({ threshold: 100 / 255 });
1010

1111
const roiMapManager = fromMask(mask);
1212

src/maskAnalysis/__tests__/getMbr.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ test('empty mask', () => {
208208
test('draw mbr on large image', () => {
209209
const image = testUtils.load('various/grayscale_by_zimmyrose.png');
210210
const rgbaImage = image.convertColor('RGBA');
211-
const mask = image.threshold({ threshold: 200 });
211+
const mask = image.threshold({ threshold: 200 / 255 });
212212
const roiMapManager = fromMask(mask);
213213

214214
const rois = roiMapManager.getRois({ kind: 'white' });

src/operations/__tests__/threshold.test.ts

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { computeThreshold, threshold } from '../threshold';
33
test('threshold with a fixed value of 100', () => {
44
const testImage = testUtils.load('opencv/test.png');
55
const grey = testImage.convertColor('GREY');
6-
const th = threshold(grey, { threshold: 100 });
6+
const th = threshold(grey, { threshold: 100 / 255 });
77

88
const expected = testUtils.createMask([
99
[1, 1, 1, 1, 1, 1, 1, 1],
@@ -70,7 +70,7 @@ test('threshold in percents', () => {
7070
[50, 60, 70],
7171
]);
7272

73-
const th = threshold(grey, { threshold: '10%' });
73+
const th = threshold(grey, { threshold: 0.1 });
7474

7575
const expected = testUtils.createMask([
7676
[0, 0, 0],
@@ -87,27 +87,10 @@ test('error too many channels', () => {
8787
/threshold can only be computed on images with one channel/,
8888
);
8989
});
90-
test('error threshold in percents out of range', () => {
91-
const testImage = testUtils.load('opencv/test.png');
92-
93-
expect(() => threshold(testImage, { threshold: '150%' })).toThrow(
94-
/threshold: threshold in percents is out of range 0 to 100/,
95-
);
96-
});
9790
test('error threshold out of range', () => {
9891
const testImage = testUtils.load('opencv/test.png');
9992

10093
expect(() => threshold(testImage, { threshold: 450 })).toThrow(
101-
/invalid value: 450. It must be a positive value smaller than 256/,
102-
);
103-
});
104-
test('error threshold string format wrong', () => {
105-
const testImage = testUtils.load('opencv/test.png');
106-
107-
expect(() => threshold(testImage, { threshold: '150' })).toThrow(
108-
/threshold: unrecognised threshold format/,
109-
);
110-
expect(() => threshold(testImage, { threshold: 'abc%' })).toThrow(
111-
/threshold: unrecognised threshold format/,
94+
/threshold must be a value between 0 and 1/,
11295
);
11396
});

src/operations/threshold.ts

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Mask } from '..';
22
import { Image } from '../Image';
33
import { imageToOutputMask } from '../utils/getOutputImage';
4-
import { validateValue } from '../utils/validators';
54

65
import huang from './thresholds/huang';
76
import intermodes from './thresholds/intermodes';
@@ -49,9 +48,10 @@ interface ThresholdOptionsBase {
4948

5049
export interface ThresholdOptionsThreshold extends ThresholdOptionsBase {
5150
/**
52-
* Threshold value that should be used. Should be an integer between 0 and Image.maxValue or a value in percents as a string, like "40%".
51+
* Threshold value that should be used. Threshold is a value in range [0,1],
52+
* which will be interpreted as a percentage of image.maxValue.
5353
*/
54-
threshold: number | string;
54+
threshold: number;
5555
}
5656

5757
export interface ThresholdOptionsAlgorithm extends ThresholdOptionsBase {
@@ -131,29 +131,16 @@ export function computeThreshold(
131131
*/
132132
export function threshold(image: Image, options: ThresholdOptions = {}): Mask {
133133
let thresholdValue: number;
134+
134135
if ('threshold' in options) {
135136
const threshold = options.threshold;
136-
if (typeof threshold === 'number') {
137-
thresholdValue = threshold;
138-
} else if (
139-
typeof threshold === 'string' &&
140-
threshold.endsWith('%') &&
141-
!Number.isNaN(Number(threshold.slice(0, -1)))
142-
) {
143-
const percents = Number(threshold.slice(0, -1));
144-
if (percents < 0 || percents > 100) {
145-
throw new RangeError(
146-
'threshold: threshold in percents is out of range 0 to 100',
147-
);
148-
}
149-
thresholdValue = (percents / 100) * image.maxValue;
150-
} else {
151-
throw new Error('threshold: unrecognised threshold format');
137+
if (threshold < 0 || threshold > 1) {
138+
throw new RangeError('threshold must be a value between 0 and 1');
152139
}
140+
thresholdValue = threshold * image.maxValue;
153141
} else {
154142
thresholdValue = computeThreshold(image, options.algorithm);
155143
}
156-
validateValue(thresholdValue, image);
157144
const result = imageToOutputMask(image, options);
158145
for (let i = 0; i < image.size; i++) {
159146
result.setBitByIndex(

src/roi/__tests__/RoiMapManager.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ test('should work with crop', () => {
99
[0, 0, 0, 0, 0],
1010
]);
1111

12-
const mask = image.threshold({ threshold: 100 });
12+
const mask = image.threshold({ threshold: 100 / 255 });
1313

1414
expect(mask).toMatchMaskData([
1515
[0, 0, 0, 0, 0],

0 commit comments

Comments
 (0)