image-js 0.35.1 → 0.35.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +99 -35
- package/lib/browser/environment.js +0 -6
- package/lib/browser/worker/extend.js +0 -3
- package/lib/browser/worker/process/background.js +0 -12
- package/lib/browser/worker/worker.js +0 -17
- package/lib/image/Image.js +18 -51
- package/lib/image/compute/colorHistogram.js +0 -8
- package/lib/image/compute/countAlphaPixels.js +0 -3
- package/lib/image/compute/extendedPoints.js +2 -7
- package/lib/image/compute/histogram.js +6 -25
- package/lib/image/compute/localMaxima.js +2 -10
- package/lib/image/compute/max.js +0 -5
- package/lib/image/compute/mean.js +0 -4
- package/lib/image/compute/median.js +0 -4
- package/lib/image/compute/min.js +0 -5
- package/lib/image/compute/minimalBoundingRectangle.js +5 -18
- package/lib/image/compute/moment.js +0 -3
- package/lib/image/compute/monotoneChainConvexHull.js +0 -3
- package/lib/image/compute/points.js +0 -3
- package/lib/image/compute/relativePosition.js +2 -8
- package/lib/image/compute/sum.js +0 -5
- package/lib/image/core/bitMethods.js +0 -11
- package/lib/image/core/checkProcessable.js +0 -13
- package/lib/image/core/environment.js +0 -8
- package/lib/image/core/export.js +0 -38
- package/lib/image/core/extend.js +0 -13
- package/lib/image/core/getRGBAData.js +0 -15
- package/lib/image/core/kind.js +4 -28
- package/lib/image/core/kindNames.js +1 -0
- package/lib/image/core/load.js +1 -53
- package/lib/image/core/mediaTypes.js +0 -2
- package/lib/image/core/valueMethods.js +0 -13
- package/lib/image/extend.js +7 -83
- package/lib/image/filter/abs.js +0 -3
- package/lib/image/filter/add.js +2 -8
- package/lib/image/filter/background.js +0 -9
- package/lib/image/filter/blurFilter.js +0 -6
- package/lib/image/filter/divide.js +0 -8
- package/lib/image/filter/flipX.js +0 -5
- package/lib/image/filter/flipY.js +0 -4
- package/lib/image/filter/gaussianFilter.js +0 -5
- package/lib/image/filter/gradientFilter.js +0 -10
- package/lib/image/filter/hypotenuse.js +0 -13
- package/lib/image/filter/invert.js +0 -9
- package/lib/image/filter/level.js +1 -19
- package/lib/image/filter/medianFilter.js +0 -15
- package/lib/image/filter/multiply.js +0 -10
- package/lib/image/filter/scharrFilter.js +0 -4
- package/lib/image/filter/sobelFilter.js +0 -4
- package/lib/image/filter/subtract.js +0 -8
- package/lib/image/filter/subtractImage.js +0 -10
- package/lib/image/internal/checks.js +1 -9
- package/lib/image/internal/clamp.js +0 -1
- package/lib/image/internal/copy.js +0 -2
- package/lib/image/internal/copyAlphaChannel.js +0 -1
- package/lib/image/internal/getImageParameters.js +0 -1
- package/lib/image/internal/getOutputImage.js +1 -13
- package/lib/image/model/model.js +1 -1
- package/lib/image/morphology/blackHat.js +0 -5
- package/lib/image/morphology/close.js +0 -5
- package/lib/image/morphology/dilate.js +0 -40
- package/lib/image/morphology/erode.js +0 -40
- package/lib/image/morphology/morphologicalGradient.js +0 -5
- package/lib/image/morphology/open.js +0 -5
- package/lib/image/morphology/topHat.js +0 -5
- package/lib/image/operator/cannyEdge.js +0 -3
- package/lib/image/operator/convolution.js +9 -34
- package/lib/image/operator/convolutionSeparable.js +0 -10
- package/lib/image/operator/extract.js +4 -13
- package/lib/image/operator/floodFill.js +2 -15
- package/lib/image/operator/getSeparatedKernel.js +0 -2
- package/lib/image/operator/paintLabels.js +8 -19
- package/lib/image/operator/paintMasks.js +2 -12
- package/lib/image/operator/paintPoints.js +0 -9
- package/lib/image/operator/paintPolygon.js +1 -15
- package/lib/image/operator/paintPolygons.js +2 -6
- package/lib/image/operator/paintPolyline.js +0 -7
- package/lib/image/operator/paintPolylines.js +1 -5
- package/lib/image/roi/Roi.js +27 -207
- package/lib/image/roi/RoiLayer.js +1 -22
- package/lib/image/roi/RoiMap.js +5 -38
- package/lib/image/roi/creator/fromMask.js +4 -22
- package/lib/image/roi/creator/fromMaskConnectedComponentLabelingAlgorithm.js +2 -20
- package/lib/image/roi/creator/fromMaxima.js +10 -43
- package/lib/image/roi/creator/fromPoints.js +2 -10
- package/lib/image/roi/creator/fromWaterShed.js +6 -17
- package/lib/image/roi/feretDiameters.js +9 -21
- package/lib/image/roi/manager.js +30 -119
- package/lib/image/roi/util/commonBorderLength.js +5 -16
- package/lib/image/roi/util/mergeRoi.js +2 -21
- package/lib/image/transform/cmyk.js +0 -9
- package/lib/image/transform/colorDepth.js +0 -12
- package/lib/image/transform/crop.js +0 -20
- package/lib/image/transform/cropAlpha.js +0 -11
- package/lib/image/transform/grey.js +0 -16
- package/lib/image/transform/greyAlgorithms.js +1 -24
- package/lib/image/transform/hsl.js +0 -16
- package/lib/image/transform/hsv.js +0 -15
- package/lib/image/transform/insert.js +0 -6
- package/lib/image/transform/mask/huang.js +3 -18
- package/lib/image/transform/mask/intermodes.js +3 -14
- package/lib/image/transform/mask/isodata.js +0 -14
- package/lib/image/transform/mask/li.js +12 -42
- package/lib/image/transform/mask/mask.js +1 -13
- package/lib/image/transform/mask/maxEntropy.js +8 -25
- package/lib/image/transform/mask/mean.js +1 -3
- package/lib/image/transform/mask/minError.js +10 -21
- package/lib/image/transform/mask/minimum.js +0 -20
- package/lib/image/transform/mask/moments.js +4 -17
- package/lib/image/transform/mask/otsu.js +1 -7
- package/lib/image/transform/mask/percentile.js +0 -8
- package/lib/image/transform/mask/renyiEntropy.js +8 -34
- package/lib/image/transform/mask/shanbhag.js +8 -25
- package/lib/image/transform/mask/thresholdAlgorithms.js +1 -17
- package/lib/image/transform/mask/triangle.js +13 -29
- package/lib/image/transform/mask/yen.js +2 -14
- package/lib/image/transform/pad.js +0 -20
- package/lib/image/transform/resize/nearestNeighbor.js +0 -6
- package/lib/image/transform/resize/resize.js +0 -16
- package/lib/image/transform/rgba.js +0 -9
- package/lib/image/transform/rgba8.js +0 -3
- package/lib/image/transform/rotate.js +0 -29
- package/lib/image/transform/rotateFree.js +0 -31
- package/lib/image/transform/warping.js +2 -35
- package/lib/image/utility/combineChannels.js +0 -11
- package/lib/image/utility/getBestMatch.js +2 -13
- package/lib/image/utility/getChannel.js +0 -10
- package/lib/image/utility/getClosestCommonParent.js +6 -23
- package/lib/image/utility/getColumn.js +0 -4
- package/lib/image/utility/getIntersection.js +2 -18
- package/lib/image/utility/getMatrix.js +0 -7
- package/lib/image/utility/getPixelsArray.js +0 -5
- package/lib/image/utility/getPixelsGrid.js +0 -11
- package/lib/image/utility/getRow.js +0 -4
- package/lib/image/utility/getSimilarity.js +3 -17
- package/lib/image/utility/getThreshold.js +0 -4
- package/lib/image/utility/setBorder.js +0 -16
- package/lib/image/utility/setChannel.js +0 -6
- package/lib/image/utility/setMatrix.js +0 -6
- package/lib/image/utility/split.js +2 -15
- package/lib/index.js +0 -12
- package/lib/kernel/kernel.js +0 -3
- package/lib/kernel/laplacianOfGaussian.js +1 -7
- package/lib/node_modules/test/binary.js +0 -3
- package/lib/node_modules/test/oneRoi.js +0 -2
- package/lib/stack/Stack.js +2 -35
- package/lib/stack/compute/histogram.js +0 -4
- package/lib/stack/compute/histograms.js +0 -4
- package/lib/stack/compute/max.js +0 -3
- package/lib/stack/compute/median.js +0 -4
- package/lib/stack/compute/min.js +0 -3
- package/lib/stack/extend.js +1 -11
- package/lib/stack/transform/matchAndCrop.js +6 -19
- package/lib/stack/utility/averageImage.js +0 -9
- package/lib/stack/utility/maxImage.js +0 -7
- package/lib/stack/utility/minImage.js +0 -7
- package/lib/util/Shape.js +3 -40
- package/lib/util/base64.js +3 -14
- package/lib/util/channel.js +1 -35
- package/lib/util/color.js +1 -25
- package/lib/util/converter.js +1 -13
- package/lib/util/deepValue.js +0 -3
- package/lib/util/histogram.js +1 -12
- package/lib/util/kernel.js +2 -12
- package/lib/util/matrix.js +0 -13
- package/lib/util/points.js +12 -35
- package/lib/util/value.js +0 -7
- package/lib/util/zerosMatrix.js +0 -3
- package/package.json +2 -2
- package/src/image/operator/paintLabels.js +6 -6
- package/src/image/operator/paintPolygon.js +1 -1
- package/src/image/operator/paintPolygons.js +2 -2
- package/src/image/operator/paintPolylines.js +1 -1
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = flipX;
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* Flip an image horizontally.
|
|
10
9
|
* @memberof Image
|
|
@@ -15,14 +14,11 @@ function flipX() {
|
|
|
15
14
|
this.checkProcessable('flipX', {
|
|
16
15
|
bitDepth: [8, 16]
|
|
17
16
|
});
|
|
18
|
-
|
|
19
17
|
for (let i = 0; i < this.height; i++) {
|
|
20
18
|
let offsetY = i * this.width * this.channels;
|
|
21
|
-
|
|
22
19
|
for (let j = 0; j < Math.floor(this.width / 2); j++) {
|
|
23
20
|
let posCurrent = j * this.channels + offsetY;
|
|
24
21
|
let posOpposite = (this.width - j - 1) * this.channels + offsetY;
|
|
25
|
-
|
|
26
22
|
for (let k = 0; k < this.channels; k++) {
|
|
27
23
|
let tmp = this.data[posCurrent + k];
|
|
28
24
|
this.data[posCurrent + k] = this.data[posOpposite + k];
|
|
@@ -30,6 +26,5 @@ function flipX() {
|
|
|
30
26
|
}
|
|
31
27
|
}
|
|
32
28
|
}
|
|
33
|
-
|
|
34
29
|
return this;
|
|
35
30
|
}
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = flipY;
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* Flip an image vertically. The image
|
|
10
9
|
* @memberof Image
|
|
@@ -15,12 +14,10 @@ function flipY() {
|
|
|
15
14
|
this.checkProcessable('flipY', {
|
|
16
15
|
bitDepth: [8, 16]
|
|
17
16
|
});
|
|
18
|
-
|
|
19
17
|
for (let i = 0; i < Math.floor(this.height / 2); i++) {
|
|
20
18
|
for (let j = 0; j < this.width; j++) {
|
|
21
19
|
let posCurrent = j * this.channels + i * this.width * this.channels;
|
|
22
20
|
let posOpposite = j * this.channels + (this.height - 1 - i) * this.channels * this.width;
|
|
23
|
-
|
|
24
21
|
for (let k = 0; k < this.channels; k++) {
|
|
25
22
|
let tmp = this.data[posCurrent + k];
|
|
26
23
|
this.data[posCurrent + k] = this.data[posOpposite + k];
|
|
@@ -28,6 +25,5 @@ function flipY() {
|
|
|
28
25
|
}
|
|
29
26
|
}
|
|
30
27
|
}
|
|
31
|
-
|
|
32
28
|
return this;
|
|
33
29
|
}
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = gaussianFilter;
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* Apply a gaussian filter to the image.
|
|
10
9
|
* @memberof Image
|
|
@@ -33,24 +32,20 @@ function gaussianFilter(options = {}) {
|
|
|
33
32
|
algorithm: 'separable'
|
|
34
33
|
});
|
|
35
34
|
}
|
|
36
|
-
|
|
37
35
|
function getKernel(radius, sigma) {
|
|
38
36
|
const n = radius * 2 + 1;
|
|
39
37
|
const kernel = new Array(n);
|
|
40
38
|
const sigmaX = sigma ? sigma : ((n - 1) * 0.5 - 1) * 0.3 + 0.8;
|
|
41
39
|
const scale2X = -0.5 / (sigmaX * sigmaX);
|
|
42
40
|
let sum = 0;
|
|
43
|
-
|
|
44
41
|
for (let i = 0; i < n; i++) {
|
|
45
42
|
const x = i - radius;
|
|
46
43
|
const t = Math.exp(scale2X * x * x);
|
|
47
44
|
kernel[i] = t;
|
|
48
45
|
sum += t;
|
|
49
46
|
}
|
|
50
|
-
|
|
51
47
|
for (let i = 0; i < n; i++) {
|
|
52
48
|
kernel[i] /= sum;
|
|
53
49
|
}
|
|
54
|
-
|
|
55
50
|
return kernel;
|
|
56
51
|
}
|
|
@@ -4,11 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = gradientFilter;
|
|
7
|
-
|
|
8
7
|
var _convolution = _interopRequireDefault(require("../operator/convolution"));
|
|
9
|
-
|
|
10
8
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
-
|
|
12
9
|
/**
|
|
13
10
|
* Direction of a gradient filter
|
|
14
11
|
* @typedef {('x'|'y'|'xy')} GradientDirection
|
|
@@ -38,7 +35,6 @@ function gradientFilter(options = {}) {
|
|
|
38
35
|
this.checkProcessable('gradientFilter', {
|
|
39
36
|
bitDepth: [8, 16]
|
|
40
37
|
});
|
|
41
|
-
|
|
42
38
|
switch (direction) {
|
|
43
39
|
case 'x':
|
|
44
40
|
if (!kernelX) throw new Error('kernelX option is missing');
|
|
@@ -47,7 +43,6 @@ function gradientFilter(options = {}) {
|
|
|
47
43
|
border: border,
|
|
48
44
|
bitDepth
|
|
49
45
|
});
|
|
50
|
-
|
|
51
46
|
case 'y':
|
|
52
47
|
if (!kernelY) throw new Error('kernelY option is missing');
|
|
53
48
|
return _convolution.default.call(this, kernelY, {
|
|
@@ -55,30 +50,25 @@ function gradientFilter(options = {}) {
|
|
|
55
50
|
border: border,
|
|
56
51
|
bitDepth
|
|
57
52
|
});
|
|
58
|
-
|
|
59
53
|
case 'xy':
|
|
60
54
|
{
|
|
61
55
|
if (!kernelX) throw new Error('kernelX option is missing');
|
|
62
56
|
if (!kernelY) throw new Error('kernelY option is missing');
|
|
63
|
-
|
|
64
57
|
const gX = _convolution.default.call(this, kernelX, {
|
|
65
58
|
channels: channels,
|
|
66
59
|
border: border,
|
|
67
60
|
bitDepth: 32
|
|
68
61
|
});
|
|
69
|
-
|
|
70
62
|
const gY = _convolution.default.call(this, kernelY, {
|
|
71
63
|
channels: channels,
|
|
72
64
|
border: border,
|
|
73
65
|
bitDepth: 32
|
|
74
66
|
});
|
|
75
|
-
|
|
76
67
|
return gX.hypotenuse(gY, {
|
|
77
68
|
bitDepth,
|
|
78
69
|
channels: channels
|
|
79
70
|
});
|
|
80
71
|
}
|
|
81
|
-
|
|
82
72
|
default:
|
|
83
73
|
throw new Error(`Unknown parameter direction: ${direction}`);
|
|
84
74
|
}
|
|
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = hypotenuse;
|
|
7
|
-
|
|
8
7
|
var _channel = require("../../util/channel");
|
|
9
|
-
|
|
10
8
|
var _Image = _interopRequireDefault(require("../Image"));
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
10
|
/**
|
|
15
11
|
* Calculate a new image that is the hypotenuse between the current image and the otherImage.
|
|
16
12
|
* @memberof Image
|
|
@@ -29,34 +25,26 @@ function hypotenuse(otherImage, options = {}) {
|
|
|
29
25
|
this.checkProcessable('hypotenuse', {
|
|
30
26
|
bitDepth: [8, 16, 32]
|
|
31
27
|
});
|
|
32
|
-
|
|
33
28
|
if (this.width !== otherImage.width || this.height !== otherImage.height) {
|
|
34
29
|
throw new Error('hypotenuse: both images must have the same size');
|
|
35
30
|
}
|
|
36
|
-
|
|
37
31
|
if (this.alpha !== otherImage.alpha || this.bitDepth !== otherImage.bitDepth) {
|
|
38
32
|
throw new Error('hypotenuse: both images must have the same alpha and bitDepth');
|
|
39
33
|
}
|
|
40
|
-
|
|
41
34
|
if (this.channels !== otherImage.channels) {
|
|
42
35
|
throw new Error('hypotenuse: both images must have the same number of channels');
|
|
43
36
|
}
|
|
44
|
-
|
|
45
37
|
let newImage = _Image.default.createFrom(this, {
|
|
46
38
|
bitDepth: bitDepth
|
|
47
39
|
});
|
|
48
|
-
|
|
49
40
|
channels = (0, _channel.validateArrayOfChannels)(this, {
|
|
50
41
|
channels: channels
|
|
51
42
|
});
|
|
52
43
|
let clamped = newImage.isClamped;
|
|
53
|
-
|
|
54
44
|
for (let j = 0; j < channels.length; j++) {
|
|
55
45
|
let c = channels[j];
|
|
56
|
-
|
|
57
46
|
for (let i = c; i < this.data.length; i += this.channels) {
|
|
58
47
|
let value = Math.hypot(this.data[i], otherImage.data[i]);
|
|
59
|
-
|
|
60
48
|
if (clamped) {
|
|
61
49
|
// we calculate the clamped result
|
|
62
50
|
newImage.data[i] = Math.min(Math.max(Math.round(value), 0), newImage.maxValue);
|
|
@@ -65,6 +53,5 @@ function hypotenuse(otherImage, options = {}) {
|
|
|
65
53
|
}
|
|
66
54
|
}
|
|
67
55
|
}
|
|
68
|
-
|
|
69
56
|
return newImage;
|
|
70
57
|
}
|
|
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = invert;
|
|
7
|
-
|
|
8
7
|
var _copyAlphaChannel = _interopRequireDefault(require("../internal/copyAlphaChannel"));
|
|
9
|
-
|
|
10
8
|
var _getOutputImage = require("../internal/getOutputImage");
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
10
|
/**
|
|
15
11
|
* Invert the colors of an image
|
|
16
12
|
* @memberof Image
|
|
@@ -25,26 +21,21 @@ function invert(options = {}) {
|
|
|
25
21
|
bitDepth: [1, 8, 16]
|
|
26
22
|
});
|
|
27
23
|
const out = (0, _getOutputImage.getOutputImageOrInPlace)(this, options);
|
|
28
|
-
|
|
29
24
|
if (this.bitDepth === 1) {
|
|
30
25
|
invertBinary(this, out);
|
|
31
26
|
} else {
|
|
32
27
|
invertColor(this, out);
|
|
33
|
-
|
|
34
28
|
if (this !== out) {
|
|
35
29
|
(0, _copyAlphaChannel.default)(this, out);
|
|
36
30
|
}
|
|
37
31
|
}
|
|
38
|
-
|
|
39
32
|
return out;
|
|
40
33
|
}
|
|
41
|
-
|
|
42
34
|
function invertBinary(image, out) {
|
|
43
35
|
for (let i = 0; i < image.data.length; i++) {
|
|
44
36
|
out.data[i] = ~image.data[i];
|
|
45
37
|
}
|
|
46
38
|
}
|
|
47
|
-
|
|
48
39
|
function invertColor(image, out) {
|
|
49
40
|
for (let pixel = 0; pixel < image.data.length; pixel += image.channels) {
|
|
50
41
|
for (let c = 0; c < image.components; c++) {
|
|
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = level;
|
|
7
|
-
|
|
8
7
|
var _newArray = _interopRequireDefault(require("new-array"));
|
|
9
|
-
|
|
10
8
|
var _channel = require("../../util/channel");
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
10
|
/**
|
|
15
11
|
* Level the image for by default have the minimal and maximal values.
|
|
16
12
|
* @memberof Image
|
|
@@ -35,52 +31,40 @@ function level(options = {}) {
|
|
|
35
31
|
channels = (0, _channel.validateArrayOfChannels)(this, {
|
|
36
32
|
channels: channels
|
|
37
33
|
});
|
|
38
|
-
|
|
39
34
|
if (channels.length !== this.channel) {
|
|
40
35
|
// if we process only part of the channels and the min or max length corresponds to the number of channels
|
|
41
36
|
// we need to take the corresponding values
|
|
42
37
|
if (Array.isArray(min) && min.length === this.channels) {
|
|
43
38
|
min = min.filter((a, index) => channels.includes(index));
|
|
44
39
|
}
|
|
45
|
-
|
|
46
40
|
if (Array.isArray(max) && max.length === this.channels) {
|
|
47
41
|
max = max.filter((a, index) => channels.includes(index));
|
|
48
42
|
}
|
|
49
43
|
}
|
|
50
|
-
|
|
51
44
|
switch (algorithm) {
|
|
52
45
|
case 'range':
|
|
53
46
|
if (min < 0) {
|
|
54
47
|
min = 0;
|
|
55
48
|
}
|
|
56
|
-
|
|
57
49
|
if (max > this.maxValue) {
|
|
58
50
|
max = this.maxValue;
|
|
59
51
|
}
|
|
60
|
-
|
|
61
52
|
if (!Array.isArray(min)) {
|
|
62
53
|
min = (0, _newArray.default)(channels.length, min);
|
|
63
54
|
}
|
|
64
|
-
|
|
65
55
|
if (!Array.isArray(max)) {
|
|
66
56
|
max = (0, _newArray.default)(channels.length, max);
|
|
67
57
|
}
|
|
68
|
-
|
|
69
58
|
processImage(this, min, max, channels);
|
|
70
59
|
break;
|
|
71
|
-
|
|
72
60
|
default:
|
|
73
61
|
throw new Error(`level: algorithm not implement: ${algorithm}`);
|
|
74
62
|
}
|
|
75
|
-
|
|
76
63
|
return this;
|
|
77
64
|
}
|
|
78
|
-
|
|
79
65
|
function processImage(image, min, max, channels) {
|
|
80
66
|
let delta = 1e-5; // sorry no better value that this "best guess"
|
|
81
|
-
|
|
82
67
|
let factor = new Array(channels.length);
|
|
83
|
-
|
|
84
68
|
for (let i = 0; i < channels.length; i++) {
|
|
85
69
|
if (min[i] === 0 && max[i] === image.maxValue) {
|
|
86
70
|
factor[i] = 0;
|
|
@@ -89,9 +73,9 @@ function processImage(image, min, max, channels) {
|
|
|
89
73
|
} else {
|
|
90
74
|
factor[i] = (image.maxValue + 1 - delta) / (max[i] - min[i]);
|
|
91
75
|
}
|
|
92
|
-
|
|
93
76
|
min[i] += (0.5 - delta / 2) / factor[i];
|
|
94
77
|
}
|
|
78
|
+
|
|
95
79
|
/*
|
|
96
80
|
Note on border effect
|
|
97
81
|
For 8 bits images we should calculate for the space between -0.5 and 255.5
|
|
@@ -99,10 +83,8 @@ function processImage(image, min, max, channels) {
|
|
|
99
83
|
But doing this we need to deal with Math.round that gives 256 if the value is 255.5
|
|
100
84
|
*/
|
|
101
85
|
|
|
102
|
-
|
|
103
86
|
for (let j = 0; j < channels.length; j++) {
|
|
104
87
|
let c = channels[j];
|
|
105
|
-
|
|
106
88
|
if (factor[j] !== 0) {
|
|
107
89
|
for (let i = 0; i < image.data.length; i += image.channels) {
|
|
108
90
|
image.data[i + c] = Math.min(Math.max(0, (image.data[i + c] - min[j]) * factor[j] + 0.5 | 0), image.maxValue);
|
|
@@ -4,15 +4,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = medianFilter;
|
|
7
|
-
|
|
8
7
|
var _medianQuickselect = _interopRequireDefault(require("median-quickselect"));
|
|
9
|
-
|
|
10
8
|
var _channel = require("../../util/channel");
|
|
11
|
-
|
|
12
9
|
var _Image = _interopRequireDefault(require("../Image"));
|
|
13
|
-
|
|
14
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
-
|
|
16
11
|
/**
|
|
17
12
|
* Each pixel of the image becomes the median of the neighbor pixels.
|
|
18
13
|
* @memberof Image
|
|
@@ -32,46 +27,36 @@ function medianFilter(options = {}) {
|
|
|
32
27
|
this.checkProcessable('medianFilter', {
|
|
33
28
|
bitDepth: [8, 16]
|
|
34
29
|
});
|
|
35
|
-
|
|
36
30
|
if (radius < 1) {
|
|
37
31
|
throw new Error('radius must be greater than 0');
|
|
38
32
|
}
|
|
39
|
-
|
|
40
33
|
channels = (0, _channel.validateArrayOfChannels)(this, channels, true);
|
|
41
34
|
let kWidth = radius;
|
|
42
35
|
let kHeight = radius;
|
|
43
|
-
|
|
44
36
|
let newImage = _Image.default.createFrom(this);
|
|
45
|
-
|
|
46
37
|
let size = (kWidth * 2 + 1) * (kHeight * 2 + 1);
|
|
47
38
|
let kernel = new Array(size);
|
|
48
|
-
|
|
49
39
|
for (let channel = 0; channel < channels.length; channel++) {
|
|
50
40
|
let c = channels[channel];
|
|
51
|
-
|
|
52
41
|
for (let y = kHeight; y < this.height - kHeight; y++) {
|
|
53
42
|
for (let x = kWidth; x < this.width - kWidth; x++) {
|
|
54
43
|
let n = 0;
|
|
55
|
-
|
|
56
44
|
for (let j = -kHeight; j <= kHeight; j++) {
|
|
57
45
|
for (let i = -kWidth; i <= kWidth; i++) {
|
|
58
46
|
let index = ((y + j) * this.width + x + i) * this.channels + c;
|
|
59
47
|
kernel[n++] = this.data[index];
|
|
60
48
|
}
|
|
61
49
|
}
|
|
62
|
-
|
|
63
50
|
let index = (y * this.width + x) * this.channels + c;
|
|
64
51
|
newImage.data[index] = (0, _medianQuickselect.default)(kernel);
|
|
65
52
|
}
|
|
66
53
|
}
|
|
67
54
|
}
|
|
68
|
-
|
|
69
55
|
if (this.alpha && !channels.includes(this.channels)) {
|
|
70
56
|
for (let i = this.components; i < this.data.length; i = i + this.channels) {
|
|
71
57
|
newImage.data[i] = this.data[i];
|
|
72
58
|
}
|
|
73
59
|
}
|
|
74
|
-
|
|
75
60
|
newImage.setBorder({
|
|
76
61
|
size: [kWidth, kHeight],
|
|
77
62
|
algorithm: border
|
|
@@ -4,11 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = multiply;
|
|
7
|
-
|
|
8
7
|
var _channel = require("../../util/channel");
|
|
9
|
-
|
|
10
8
|
var _value = require("../../util/value");
|
|
11
|
-
|
|
12
9
|
/**
|
|
13
10
|
* @memberof Image
|
|
14
11
|
* @instance
|
|
@@ -23,20 +20,16 @@ function multiply(value, options = {}) {
|
|
|
23
20
|
this.checkProcessable('multiply', {
|
|
24
21
|
bitDepth: [8, 16]
|
|
25
22
|
});
|
|
26
|
-
|
|
27
23
|
if (value <= 0) {
|
|
28
24
|
throw new Error('multiply: the value must be greater than 0');
|
|
29
25
|
}
|
|
30
|
-
|
|
31
26
|
channels = (0, _channel.validateArrayOfChannels)(this, {
|
|
32
27
|
channels: channels
|
|
33
28
|
});
|
|
34
29
|
value = (0, _value.checkNumberArray)(value);
|
|
35
|
-
|
|
36
30
|
if (!isNaN(value)) {
|
|
37
31
|
for (let j = 0; j < channels.length; j++) {
|
|
38
32
|
let c = channels[j];
|
|
39
|
-
|
|
40
33
|
for (let i = 0; i < this.data.length; i += this.channels) {
|
|
41
34
|
this.data[i + c] = Math.min(this.maxValue, this.data[i + c] * value >> 0);
|
|
42
35
|
}
|
|
@@ -45,15 +38,12 @@ function multiply(value, options = {}) {
|
|
|
45
38
|
if (this.data.length !== value.length) {
|
|
46
39
|
throw new Error('multiply: the data size is different');
|
|
47
40
|
}
|
|
48
|
-
|
|
49
41
|
for (let j = 0; j < channels.length; j++) {
|
|
50
42
|
let c = channels[j];
|
|
51
|
-
|
|
52
43
|
for (let i = 0; i < this.data.length; i += this.channels) {
|
|
53
44
|
this.data[i + c] = Math.max(0, Math.min(this.maxValue, this.data[i + c] * value[i + c] >> 0));
|
|
54
45
|
}
|
|
55
46
|
}
|
|
56
47
|
}
|
|
57
|
-
|
|
58
48
|
return this;
|
|
59
49
|
}
|
|
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = scharrFilter;
|
|
7
|
-
|
|
8
7
|
var _kernels = require("../../util/kernels");
|
|
9
|
-
|
|
10
8
|
var _gradientFilter = _interopRequireDefault(require("./gradientFilter"));
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
10
|
/**
|
|
15
11
|
* Applies the Scharr operator.
|
|
16
12
|
* @memberof Image
|
|
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = sobelFilter;
|
|
7
|
-
|
|
8
7
|
var _kernels = require("../../util/kernels");
|
|
9
|
-
|
|
10
8
|
var _gradientFilter = _interopRequireDefault(require("./gradientFilter"));
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
10
|
/**
|
|
15
11
|
* Applies the Sobel operator.
|
|
16
12
|
* @memberof Image
|
|
@@ -4,11 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = subtract;
|
|
7
|
-
|
|
8
7
|
var _channel = require("../../util/channel");
|
|
9
|
-
|
|
10
8
|
var _value = require("../../util/value");
|
|
11
|
-
|
|
12
9
|
/**
|
|
13
10
|
* @memberof Image
|
|
14
11
|
* @instance
|
|
@@ -27,11 +24,9 @@ function subtract(value, options = {}) {
|
|
|
27
24
|
channels: channels
|
|
28
25
|
});
|
|
29
26
|
value = (0, _value.checkNumberArray)(value);
|
|
30
|
-
|
|
31
27
|
if (!isNaN(value)) {
|
|
32
28
|
for (let j = 0; j < channels.length; j++) {
|
|
33
29
|
let c = channels[j];
|
|
34
|
-
|
|
35
30
|
for (let i = 0; i < this.data.length; i += this.channels) {
|
|
36
31
|
this.data[i + c] = Math.max(0, this.data[i + c] - value >> 0);
|
|
37
32
|
}
|
|
@@ -40,15 +35,12 @@ function subtract(value, options = {}) {
|
|
|
40
35
|
if (this.data.length !== value.length) {
|
|
41
36
|
throw new Error('subtract: the data size is different');
|
|
42
37
|
}
|
|
43
|
-
|
|
44
38
|
for (let j = 0; j < channels.length; j++) {
|
|
45
39
|
let c = channels[j];
|
|
46
|
-
|
|
47
40
|
for (let i = 0; i < this.data.length; i += this.channels) {
|
|
48
41
|
this.data[i + c] = Math.max(0, Math.min(this.maxValue, this.data[i + c] - value[i + c] >> 0));
|
|
49
42
|
}
|
|
50
43
|
}
|
|
51
44
|
}
|
|
52
|
-
|
|
53
45
|
return this;
|
|
54
46
|
}
|
|
@@ -4,9 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = subtractImage;
|
|
7
|
-
|
|
8
7
|
var _channel = require("../../util/channel");
|
|
9
|
-
|
|
10
8
|
/**
|
|
11
9
|
* Calculate a new image that is the subtraction between the current image and the otherImage.
|
|
12
10
|
* @memberof Image
|
|
@@ -25,30 +23,23 @@ function subtractImage(otherImage, options = {}) {
|
|
|
25
23
|
this.checkProcessable('subtractImage', {
|
|
26
24
|
bitDepth: [8, 16]
|
|
27
25
|
});
|
|
28
|
-
|
|
29
26
|
if (this.width !== otherImage.width || this.height !== otherImage.height) {
|
|
30
27
|
throw new Error('subtractImage: both images must have the same size');
|
|
31
28
|
}
|
|
32
|
-
|
|
33
29
|
if (this.alpha !== otherImage.alpha || this.bitDepth !== otherImage.bitDepth) {
|
|
34
30
|
throw new Error('subtractImage: both images must have the same alpha and bitDepth');
|
|
35
31
|
}
|
|
36
|
-
|
|
37
32
|
if (this.channels !== otherImage.channels) {
|
|
38
33
|
throw new Error('subtractImage: both images must have the same number of channels');
|
|
39
34
|
}
|
|
40
|
-
|
|
41
35
|
let newImage = this.clone();
|
|
42
36
|
channels = (0, _channel.validateArrayOfChannels)(this, {
|
|
43
37
|
channels: channels
|
|
44
38
|
});
|
|
45
|
-
|
|
46
39
|
for (let j = 0; j < channels.length; j++) {
|
|
47
40
|
let c = channels[j];
|
|
48
|
-
|
|
49
41
|
for (let i = c; i < this.data.length; i += this.channels) {
|
|
50
42
|
let value = this.data[i] - otherImage.data[i];
|
|
51
|
-
|
|
52
43
|
if (absolute) {
|
|
53
44
|
newImage.data[i] = Math.abs(value);
|
|
54
45
|
} else {
|
|
@@ -56,6 +47,5 @@ function subtractImage(otherImage, options = {}) {
|
|
|
56
47
|
}
|
|
57
48
|
}
|
|
58
49
|
}
|
|
59
|
-
|
|
60
50
|
return newImage;
|
|
61
51
|
}
|
|
@@ -8,46 +8,38 @@ exports.checkColumn = checkColumn;
|
|
|
8
8
|
exports.checkInterpolation = checkInterpolation;
|
|
9
9
|
exports.checkRow = checkRow;
|
|
10
10
|
exports.validInterpolations = void 0;
|
|
11
|
-
|
|
12
11
|
function checkRow(image, row) {
|
|
13
12
|
if (row < 0 || row >= image.height) {
|
|
14
13
|
throw new RangeError(`row must be included between 0 and ${image.height - 1}. Current value: ${row}`);
|
|
15
14
|
}
|
|
16
15
|
}
|
|
17
|
-
|
|
18
16
|
function checkColumn(image, column) {
|
|
19
17
|
if (column < 0 || column >= image.width) {
|
|
20
18
|
throw new RangeError(`column must be included between 0 and ${image.width - 1}. Current value: ${column}`);
|
|
21
19
|
}
|
|
22
20
|
}
|
|
23
|
-
|
|
24
21
|
function checkChannel(image, channel) {
|
|
25
22
|
if (channel < 0 || channel >= image.channels) {
|
|
26
23
|
throw new RangeError(`channel must be included between 0 and ${image.channels - 1}. Current value: ${channel}`);
|
|
27
24
|
}
|
|
28
25
|
}
|
|
26
|
+
|
|
29
27
|
/**
|
|
30
28
|
* @typedef {('nearestNeighbor'|'bilinear')} InterpolationAlgorithm
|
|
31
29
|
*/
|
|
32
|
-
|
|
33
|
-
|
|
34
30
|
const validInterpolations = {
|
|
35
31
|
nearestneighbor: 'nearestNeighbor',
|
|
36
32
|
nearestneighbour: 'nearestNeighbor',
|
|
37
33
|
bilinear: 'bilinear'
|
|
38
34
|
};
|
|
39
35
|
exports.validInterpolations = validInterpolations;
|
|
40
|
-
|
|
41
36
|
function checkInterpolation(interpolation) {
|
|
42
37
|
if (typeof interpolation !== 'string') {
|
|
43
38
|
throw new TypeError('interpolation must be a string');
|
|
44
39
|
}
|
|
45
|
-
|
|
46
40
|
interpolation = interpolation.toLowerCase();
|
|
47
|
-
|
|
48
41
|
if (!validInterpolations[interpolation]) {
|
|
49
42
|
throw new RangeError(`invalid interpolation algorithm: ${interpolation}`);
|
|
50
43
|
}
|
|
51
|
-
|
|
52
44
|
return validInterpolations[interpolation];
|
|
53
45
|
}
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = copyImage;
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* Make a copy of the current image
|
|
10
9
|
* @memberof Image
|
|
@@ -19,7 +18,6 @@ function copyImage(fromImage, toImage, x, y) {
|
|
|
19
18
|
let fromHeight = fromImage.height;
|
|
20
19
|
let toWidth = toImage.width;
|
|
21
20
|
let channels = fromImage.channels;
|
|
22
|
-
|
|
23
21
|
for (let i = 0; i < fromWidth; i++) {
|
|
24
22
|
for (let j = 0; j < fromHeight; j++) {
|
|
25
23
|
for (let k = 0; k < channels; k++) {
|