image-js 0.35.2 → 0.35.4
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 +3 -10
- 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 -11
- 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 +2 -13
- package/lib/image/operator/paintMasks.js +2 -12
- package/lib/image/operator/paintPoints.js +0 -9
- package/lib/image/operator/paintPolygon.js +0 -14
- package/lib/image/operator/paintPolygons.js +0 -4
- package/lib/image/operator/paintPolyline.js +0 -7
- package/lib/image/operator/paintPolylines.js +0 -4
- package/lib/image/roi/Roi.js +27 -208
- 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 -17
- 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 +3 -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 +1 -1
- package/src/image/utility/setMatrix.js +4 -0
package/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
// Project: https://github.com/image-js/image-js
|
|
3
3
|
// Definitions by: Michaël Zasso <https://github.com/targos>
|
|
4
4
|
|
|
5
|
+
import Matrix from 'ml-matrix';
|
|
6
|
+
|
|
5
7
|
// Global variable exposed by UMD bundle
|
|
6
8
|
export as namespace IJS;
|
|
7
9
|
|
|
@@ -157,7 +159,7 @@ export declare class Image {
|
|
|
157
159
|
getRow(row: number, channel?: number): Array<number>;
|
|
158
160
|
getColumn(row: number, channel?: number): Array<number>;
|
|
159
161
|
getMatrix(options?: { channel?: number }): Matrix;
|
|
160
|
-
setMatrix(matrix: Matrix, options?: { channel?: number });
|
|
162
|
+
setMatrix(matrix: Matrix, options?: { channel?: number }): this;
|
|
161
163
|
getPixelsArray(): Array<Array<number>>;
|
|
162
164
|
getIntersection(mask2: Image): object;
|
|
163
165
|
getClosestCommonParent(mask: Image): Image;
|
|
@@ -328,15 +330,6 @@ export declare class Stack extends Array<Image> {
|
|
|
328
330
|
|
|
329
331
|
export declare class RoiManager {}
|
|
330
332
|
|
|
331
|
-
export declare class Matrix extends Array<Array<number>> {
|
|
332
|
-
constructor();
|
|
333
|
-
constructor(width: number, height: number, defaultValue?: number);
|
|
334
|
-
|
|
335
|
-
localMin(x: number, y: number): { position: Array<number>; value: number };
|
|
336
|
-
localMax(x: number, y: number): { position: Array<number>; value: number };
|
|
337
|
-
localSearch(x: number, y: number, value: number): Array<Array<number>>;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
333
|
export interface ImageConstructorOptions {
|
|
341
334
|
width?: number;
|
|
342
335
|
height?: number;
|
|
@@ -15,14 +15,12 @@ const ImageData = self.ImageData;
|
|
|
15
15
|
exports.ImageData = ImageData;
|
|
16
16
|
const DOMImage = self.Image;
|
|
17
17
|
exports.DOMImage = DOMImage;
|
|
18
|
-
|
|
19
18
|
function createCanvas(width, height) {
|
|
20
19
|
let canvas = self.document.createElement('canvas');
|
|
21
20
|
canvas.width = width;
|
|
22
21
|
canvas.height = height;
|
|
23
22
|
return canvas;
|
|
24
23
|
}
|
|
25
|
-
|
|
26
24
|
function fetchBinary(url, {
|
|
27
25
|
withCredentials = false
|
|
28
26
|
} = {}) {
|
|
@@ -31,20 +29,16 @@ function fetchBinary(url, {
|
|
|
31
29
|
xhr.open('GET', url, true);
|
|
32
30
|
xhr.responseType = 'arraybuffer';
|
|
33
31
|
xhr.withCredentials = withCredentials;
|
|
34
|
-
|
|
35
32
|
xhr.onload = function (e) {
|
|
36
33
|
if (this.status !== 200) reject(e);else resolve(this.response);
|
|
37
34
|
};
|
|
38
|
-
|
|
39
35
|
xhr.onerror = reject;
|
|
40
36
|
xhr.send();
|
|
41
37
|
});
|
|
42
38
|
}
|
|
43
|
-
|
|
44
39
|
function createWriteStream() {
|
|
45
40
|
throw new Error('createWriteStream does not exist in the browser');
|
|
46
41
|
}
|
|
47
|
-
|
|
48
42
|
function writeFile() {
|
|
49
43
|
throw new Error('writeFile does not exist in the browser');
|
|
50
44
|
}
|
|
@@ -4,11 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = extend;
|
|
7
|
-
|
|
8
7
|
var _background = _interopRequireDefault(require("./process/background"));
|
|
9
|
-
|
|
10
8
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
-
|
|
12
9
|
function extend(Worker) {
|
|
13
10
|
Worker.extendMethod('background', _background.default);
|
|
14
11
|
}
|
|
@@ -4,11 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _Image = _interopRequireDefault(require("../../../image/Image"));
|
|
9
|
-
|
|
10
8
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
-
|
|
12
9
|
const defaultOptions = {
|
|
13
10
|
regression: {
|
|
14
11
|
kernelType: 'polynomial',
|
|
@@ -25,36 +22,29 @@ const defaultOptions = {
|
|
|
25
22
|
sampling: 20,
|
|
26
23
|
include: []
|
|
27
24
|
};
|
|
28
|
-
|
|
29
25
|
function run(image, options, onStep) {
|
|
30
26
|
options = Object.assign({}, defaultOptions, options);
|
|
31
27
|
const manager = this.manager;
|
|
32
|
-
|
|
33
28
|
if (Array.isArray(image)) {
|
|
34
29
|
return Promise.all(image.map(function (img) {
|
|
35
30
|
const run = runOnce(manager, img, options);
|
|
36
|
-
|
|
37
31
|
if (typeof onStep === 'function') {
|
|
38
32
|
run.then(onStep);
|
|
39
33
|
}
|
|
40
|
-
|
|
41
34
|
return run;
|
|
42
35
|
}));
|
|
43
36
|
} else {
|
|
44
37
|
return runOnce(manager, image, options);
|
|
45
38
|
}
|
|
46
39
|
}
|
|
47
|
-
|
|
48
40
|
function runOnce(manager, image, options) {
|
|
49
41
|
return manager.post('data', [image, options]).then(function (response) {
|
|
50
42
|
for (let i in response) {
|
|
51
43
|
response[i] = new _Image.default(response[i]);
|
|
52
44
|
}
|
|
53
|
-
|
|
54
45
|
return response;
|
|
55
46
|
});
|
|
56
47
|
}
|
|
57
|
-
|
|
58
48
|
function work() {
|
|
59
49
|
worker.on('data', function (send, image, options) {
|
|
60
50
|
image = new IJS(image);
|
|
@@ -81,7 +71,6 @@ function work() {
|
|
|
81
71
|
result.result = corrected;
|
|
82
72
|
toTransfer.push(corrected.data.buffer);
|
|
83
73
|
send(result, toTransfer);
|
|
84
|
-
|
|
85
74
|
function maybeInclude(name, image) {
|
|
86
75
|
if (options.include.includes(name)) {
|
|
87
76
|
result[name] = image;
|
|
@@ -90,7 +79,6 @@ function work() {
|
|
|
90
79
|
}
|
|
91
80
|
});
|
|
92
81
|
}
|
|
93
|
-
|
|
94
82
|
const background = {
|
|
95
83
|
run,
|
|
96
84
|
work
|
|
@@ -4,43 +4,33 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _webWorkerManager = _interopRequireDefault(require("web-worker-manager"));
|
|
9
|
-
|
|
10
8
|
var _extend = _interopRequireDefault(require("./extend"));
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
10
|
class Worker {
|
|
15
11
|
constructor() {
|
|
16
12
|
this._url = null;
|
|
17
13
|
this._deps = [null];
|
|
18
14
|
}
|
|
19
|
-
|
|
20
15
|
checkUrl() {
|
|
21
16
|
if (this._url === null) {
|
|
22
17
|
throw new Error('image worker must be initialized with an URL');
|
|
23
18
|
}
|
|
24
19
|
}
|
|
25
|
-
|
|
26
20
|
get url() {
|
|
27
21
|
return this._url;
|
|
28
22
|
}
|
|
29
|
-
|
|
30
23
|
set url(value) {
|
|
31
24
|
if (typeof value !== 'string') {
|
|
32
25
|
throw new TypeError('worker URL must be a string');
|
|
33
26
|
}
|
|
34
|
-
|
|
35
27
|
this._url = value;
|
|
36
28
|
this._deps[0] = value;
|
|
37
29
|
}
|
|
38
|
-
|
|
39
30
|
static extendMethod(name, method) {
|
|
40
31
|
let manager;
|
|
41
32
|
let url;
|
|
42
33
|
let runner = {};
|
|
43
|
-
|
|
44
34
|
function run(...args) {
|
|
45
35
|
if (!manager) {
|
|
46
36
|
this.checkUrl();
|
|
@@ -50,10 +40,8 @@ class Worker {
|
|
|
50
40
|
});
|
|
51
41
|
runner.manager = manager;
|
|
52
42
|
}
|
|
53
|
-
|
|
54
43
|
return method.run.call(runner, ...args);
|
|
55
44
|
}
|
|
56
|
-
|
|
57
45
|
run.reset = function () {
|
|
58
46
|
if (manager) {
|
|
59
47
|
manager.terminate();
|
|
@@ -63,14 +51,9 @@ class Worker {
|
|
|
63
51
|
runner.manager = manager;
|
|
64
52
|
}
|
|
65
53
|
};
|
|
66
|
-
|
|
67
54
|
Worker.prototype[name] = run;
|
|
68
55
|
}
|
|
69
|
-
|
|
70
56
|
}
|
|
71
|
-
|
|
72
57
|
(0, _extend.default)(Worker);
|
|
73
|
-
|
|
74
58
|
var _default = new Worker();
|
|
75
|
-
|
|
76
59
|
exports.default = _default;
|
package/lib/image/Image.js
CHANGED
|
@@ -4,34 +4,21 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _bitMethods = _interopRequireDefault(require("./core/bitMethods"));
|
|
9
|
-
|
|
10
8
|
var _checkProcessable = _interopRequireDefault(require("./core/checkProcessable"));
|
|
11
|
-
|
|
12
9
|
var _export = _interopRequireDefault(require("./core/export"));
|
|
13
|
-
|
|
14
10
|
var _extend = require("./core/extend");
|
|
15
|
-
|
|
16
11
|
var _getRGBAData = _interopRequireDefault(require("./core/getRGBAData"));
|
|
17
|
-
|
|
18
12
|
var _kind = require("./core/kind");
|
|
19
|
-
|
|
20
13
|
var _kindNames = require("./core/kindNames");
|
|
21
|
-
|
|
22
14
|
var _load = _interopRequireDefault(require("./core/load"));
|
|
23
|
-
|
|
24
15
|
var _valueMethods = _interopRequireDefault(require("./core/valueMethods"));
|
|
25
|
-
|
|
26
16
|
var _extend2 = _interopRequireDefault(require("./extend"));
|
|
27
|
-
|
|
28
17
|
var _getImageParameters = _interopRequireDefault(require("./internal/getImageParameters"));
|
|
29
|
-
|
|
30
18
|
var _manager = _interopRequireDefault(require("./roi/manager"));
|
|
31
|
-
|
|
32
19
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
33
|
-
|
|
34
20
|
const objectToString = Object.prototype.toString;
|
|
21
|
+
|
|
35
22
|
/**
|
|
36
23
|
* Class representing an image.
|
|
37
24
|
* This class allows to manipulate easily images directly in the browser or in node.
|
|
@@ -197,7 +184,6 @@ const objectToString = Object.prototype.toString;
|
|
|
197
184
|
* // or
|
|
198
185
|
* const image = new Image({ width: 2, height: 3, data, kind: 'RGB'});
|
|
199
186
|
*/
|
|
200
|
-
|
|
201
187
|
class Image {
|
|
202
188
|
constructor(width, height, data, options) {
|
|
203
189
|
if (arguments.length === 1) {
|
|
@@ -213,40 +199,31 @@ class Image {
|
|
|
213
199
|
data
|
|
214
200
|
} = options);
|
|
215
201
|
}
|
|
216
|
-
|
|
217
202
|
if (width === undefined) width = 1;
|
|
218
203
|
if (height === undefined) height = 1;
|
|
219
204
|
if (options === undefined) options = {};
|
|
220
|
-
|
|
221
205
|
if (typeof options !== 'object' || options === null) {
|
|
222
206
|
throw new TypeError('options must be an object');
|
|
223
207
|
}
|
|
224
|
-
|
|
225
208
|
if (!Number.isInteger(width) || width <= 0) {
|
|
226
209
|
throw new RangeError('width must be a positive integer');
|
|
227
210
|
}
|
|
228
|
-
|
|
229
211
|
if (!Number.isInteger(height) || height <= 0) {
|
|
230
212
|
throw new RangeError('height must be a positive integer');
|
|
231
213
|
}
|
|
232
|
-
|
|
233
214
|
const {
|
|
234
215
|
kind = _kindNames.RGBA
|
|
235
216
|
} = options;
|
|
236
|
-
|
|
237
217
|
if (typeof kind !== 'string') {
|
|
238
218
|
throw new TypeError('kind must be a string');
|
|
239
219
|
}
|
|
240
|
-
|
|
241
220
|
const theKind = (0, _kind.getKind)(kind);
|
|
242
221
|
const kindDefinition = Object.assign({}, options);
|
|
243
|
-
|
|
244
222
|
for (const prop in theKind) {
|
|
245
223
|
if (kindDefinition[prop] === undefined) {
|
|
246
224
|
kindDefinition[prop] = theKind[prop];
|
|
247
225
|
}
|
|
248
226
|
}
|
|
249
|
-
|
|
250
227
|
(0, _kind.verifyKindDefinition)(kindDefinition);
|
|
251
228
|
const {
|
|
252
229
|
components,
|
|
@@ -257,85 +234,83 @@ class Image {
|
|
|
257
234
|
const size = width * height;
|
|
258
235
|
const channels = components + alpha;
|
|
259
236
|
const maxValue = bitDepth === 32 ? Number.MAX_VALUE : 2 ** bitDepth - 1;
|
|
260
|
-
|
|
261
237
|
if (data === undefined) {
|
|
262
238
|
data = (0, _kind.createPixelArray)(size, components, alpha, channels, bitDepth, maxValue);
|
|
263
239
|
} else {
|
|
264
240
|
const expectedLength = (0, _kind.getTheoreticalPixelArraySize)(size, channels, bitDepth);
|
|
265
|
-
|
|
266
241
|
if (data.length !== expectedLength) {
|
|
267
242
|
throw new RangeError(`incorrect data size: ${data.length}. Should be ${expectedLength}`);
|
|
268
243
|
}
|
|
269
244
|
}
|
|
245
|
+
|
|
270
246
|
/**
|
|
271
247
|
* Width of the image.
|
|
272
248
|
* @member {number}
|
|
273
249
|
*/
|
|
274
|
-
|
|
275
|
-
|
|
276
250
|
this.width = width;
|
|
251
|
+
|
|
277
252
|
/**
|
|
278
253
|
* Height of the image.
|
|
279
254
|
* @member {number}
|
|
280
255
|
*/
|
|
281
|
-
|
|
282
256
|
this.height = height;
|
|
257
|
+
|
|
283
258
|
/**
|
|
284
259
|
* Typed array holding the image data.
|
|
285
260
|
* @member {TypedArray}
|
|
286
261
|
*/
|
|
287
|
-
|
|
288
262
|
this.data = data;
|
|
263
|
+
|
|
289
264
|
/**
|
|
290
265
|
* Total number of pixels (width * height).
|
|
291
266
|
* @member {number}
|
|
292
267
|
*/
|
|
293
|
-
|
|
294
268
|
this.size = size;
|
|
269
|
+
|
|
295
270
|
/**
|
|
296
271
|
* Number of color channels in the image.
|
|
297
272
|
* A grey image has 1 component. An RGB image has 3 components.
|
|
298
273
|
* @member {number}
|
|
299
274
|
*/
|
|
300
|
-
|
|
301
275
|
this.components = components;
|
|
276
|
+
|
|
302
277
|
/**
|
|
303
278
|
* Alpha is 1 if there is an alpha channel, 0 otherwise.
|
|
304
279
|
* @member {number}
|
|
305
280
|
*/
|
|
306
|
-
|
|
307
281
|
this.alpha = alpha;
|
|
282
|
+
|
|
308
283
|
/**
|
|
309
284
|
* Number of bits per value in each channel.
|
|
310
285
|
* @member {number}
|
|
311
286
|
*/
|
|
312
|
-
|
|
313
287
|
this.bitDepth = bitDepth;
|
|
288
|
+
|
|
314
289
|
/**
|
|
315
290
|
* Maximum value that a pixel can have.
|
|
316
291
|
* @member {number}
|
|
317
292
|
*/
|
|
318
|
-
|
|
319
293
|
this.maxValue = maxValue;
|
|
294
|
+
|
|
320
295
|
/**
|
|
321
296
|
* Color model of the image.
|
|
322
297
|
* @member {ColorModel}
|
|
323
298
|
*/
|
|
324
|
-
|
|
325
299
|
this.colorModel = colorModel;
|
|
300
|
+
|
|
326
301
|
/**
|
|
327
302
|
* Total number of channels. Is equal to `image.components + image.alpha`.
|
|
328
303
|
* @member {number}
|
|
329
304
|
*/
|
|
330
|
-
|
|
331
305
|
this.channels = channels;
|
|
306
|
+
|
|
332
307
|
/**
|
|
333
308
|
* Metadata associated with the image.
|
|
334
309
|
* @member {object}
|
|
335
310
|
*/
|
|
311
|
+
this.meta = options.meta || {};
|
|
336
312
|
|
|
337
|
-
|
|
338
|
-
|
|
313
|
+
// TODO review those props
|
|
339
314
|
Object.defineProperty(this, 'parent', {
|
|
340
315
|
enumerable: false,
|
|
341
316
|
writable: true,
|
|
@@ -354,22 +329,21 @@ class Image {
|
|
|
354
329
|
get [Symbol.toStringTag]() {
|
|
355
330
|
return 'IJSImage';
|
|
356
331
|
}
|
|
357
|
-
|
|
358
332
|
static isImage(object) {
|
|
359
333
|
return objectToString.call(object) === '[object IJSImage]';
|
|
360
334
|
}
|
|
335
|
+
|
|
361
336
|
/**
|
|
362
337
|
* Creates an image from an HTML Canvas object
|
|
363
338
|
* @param {Canvas} canvas
|
|
364
339
|
* @return {Image}
|
|
365
340
|
*/
|
|
366
|
-
|
|
367
|
-
|
|
368
341
|
static fromCanvas(canvas) {
|
|
369
342
|
const ctx = canvas.getContext('2d');
|
|
370
343
|
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
371
344
|
return new Image(imageData.width, imageData.height, imageData.data);
|
|
372
345
|
}
|
|
346
|
+
|
|
373
347
|
/**
|
|
374
348
|
* Create a new Image based on the characteristics of another one.
|
|
375
349
|
* @param {Image} other
|
|
@@ -378,8 +352,6 @@ class Image {
|
|
|
378
352
|
* @example
|
|
379
353
|
* const newImage = Image.createFrom(image, { width: 100 });
|
|
380
354
|
*/
|
|
381
|
-
|
|
382
|
-
|
|
383
355
|
static createFrom(other, options) {
|
|
384
356
|
const newOptions = (0, _getImageParameters.default)(other);
|
|
385
357
|
Object.assign(newOptions, {
|
|
@@ -388,28 +360,25 @@ class Image {
|
|
|
388
360
|
}, options);
|
|
389
361
|
return new Image(newOptions);
|
|
390
362
|
}
|
|
363
|
+
|
|
391
364
|
/**
|
|
392
365
|
* Create a new manager for regions of interest based on the current image.
|
|
393
366
|
* @param {object} [options]
|
|
394
367
|
* @return {RoiManager}
|
|
395
368
|
*/
|
|
396
|
-
|
|
397
|
-
|
|
398
369
|
getRoiManager(options) {
|
|
399
370
|
return new _manager.default(this, options);
|
|
400
371
|
}
|
|
372
|
+
|
|
401
373
|
/**
|
|
402
374
|
* Create a copy a the current image, including its data.
|
|
403
375
|
* @instance
|
|
404
376
|
* @return {Image}
|
|
405
377
|
*/
|
|
406
|
-
|
|
407
|
-
|
|
408
378
|
clone() {
|
|
409
379
|
const newData = this.data.slice();
|
|
410
380
|
return new Image(this.width, this.height, newData, this);
|
|
411
381
|
}
|
|
412
|
-
|
|
413
382
|
apply(filter) {
|
|
414
383
|
for (let y = 0; y < this.height; y++) {
|
|
415
384
|
for (let x = 0; x < this.width; x++) {
|
|
@@ -418,9 +387,7 @@ class Image {
|
|
|
418
387
|
}
|
|
419
388
|
}
|
|
420
389
|
}
|
|
421
|
-
|
|
422
390
|
}
|
|
423
|
-
|
|
424
391
|
exports.default = Image;
|
|
425
392
|
(0, _valueMethods.default)(Image);
|
|
426
393
|
(0, _bitMethods.default)(Image);
|
|
@@ -4,11 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = getColorHistogram;
|
|
7
|
-
|
|
8
7
|
var _newArray = _interopRequireDefault(require("new-array"));
|
|
9
|
-
|
|
10
8
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
-
|
|
12
9
|
/**
|
|
13
10
|
* @memberof Image
|
|
14
11
|
* @instance
|
|
@@ -27,26 +24,21 @@ function getColorHistogram(options = {}) {
|
|
|
27
24
|
components: [3]
|
|
28
25
|
});
|
|
29
26
|
let nbSlotsCheck = Math.log(nbSlots) / Math.log(8);
|
|
30
|
-
|
|
31
27
|
if (nbSlotsCheck !== Math.floor(nbSlotsCheck)) {
|
|
32
28
|
throw new RangeError('nbSlots must be a power of 8. Usually 8, 64, 512 or 4096');
|
|
33
29
|
}
|
|
34
|
-
|
|
35
30
|
let bitShift = this.bitDepth - nbSlotsCheck;
|
|
36
31
|
let data = this.data;
|
|
37
32
|
let result = (0, _newArray.default)(Math.pow(8, nbSlotsCheck), 0);
|
|
38
33
|
let factor2 = Math.pow(2, nbSlotsCheck * 2);
|
|
39
34
|
let factor1 = Math.pow(2, nbSlotsCheck);
|
|
40
|
-
|
|
41
35
|
for (let i = 0; i < data.length; i += this.channels) {
|
|
42
36
|
let slot = (data[i] >> bitShift) * factor2 + (data[i + 1] >> bitShift) * factor1 + (data[i + 2] >> bitShift);
|
|
43
|
-
|
|
44
37
|
if (useAlpha && this.alpha) {
|
|
45
38
|
result[slot] += data[i + this.channels - 1] / this.maxValue;
|
|
46
39
|
} else {
|
|
47
40
|
result[slot]++;
|
|
48
41
|
}
|
|
49
42
|
}
|
|
50
|
-
|
|
51
43
|
return result;
|
|
52
44
|
}
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = countAlphaPixels;
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* Returns the number of transparent pixels
|
|
10
9
|
* @memberof Image
|
|
@@ -22,14 +21,12 @@ function countAlphaPixels(options = {}) {
|
|
|
22
21
|
alpha: 1
|
|
23
22
|
});
|
|
24
23
|
let count = 0;
|
|
25
|
-
|
|
26
24
|
if (alpha !== undefined) {
|
|
27
25
|
for (let i = this.components; i < this.data.length; i += this.channels) {
|
|
28
26
|
if (this.data[i] === alpha) {
|
|
29
27
|
count++;
|
|
30
28
|
}
|
|
31
29
|
}
|
|
32
|
-
|
|
33
30
|
return count;
|
|
34
31
|
} else {
|
|
35
32
|
// because there is an alpha channel all the pixels have an alpha
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = extendedPoints;
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* Allows to generate an array of points for a binary image (bit depth = 1)
|
|
10
9
|
* The points consider the beginning and the end of each pixel
|
|
@@ -18,16 +17,13 @@ function extendedPoints() {
|
|
|
18
17
|
bitDepth: [1]
|
|
19
18
|
});
|
|
20
19
|
const pixels = [];
|
|
21
|
-
|
|
22
20
|
for (let y = 0; y < this.height; y++) {
|
|
23
21
|
for (let x = 0; x < this.width; x++) {
|
|
24
22
|
if (this.getBitXY(x, y) === 1) {
|
|
25
23
|
pixels.push([x, y]);
|
|
26
|
-
|
|
27
24
|
if (this.getBitXY(x + 1, y) !== 1) {
|
|
28
25
|
pixels.push([x + 1, y]);
|
|
29
26
|
pixels.push([x + 1, y + 1]);
|
|
30
|
-
|
|
31
27
|
if (this.getBitXY(x, y + 1) !== 1) {
|
|
32
28
|
pixels.push([x, y + 1]);
|
|
33
29
|
}
|
|
@@ -36,15 +32,14 @@ function extendedPoints() {
|
|
|
36
32
|
pixels.push([x, y + 1]);
|
|
37
33
|
pixels.push([x + 1, y + 1]);
|
|
38
34
|
}
|
|
39
|
-
}
|
|
40
|
-
|
|
35
|
+
}
|
|
41
36
|
|
|
37
|
+
// this small optimization allows to reduce dramatically the number of points for MBR calculation
|
|
42
38
|
while (x < this.width - 2 && this.getBitXY(x + 1, y) === 1 && this.getBitXY(x + 2, y) === 1) {
|
|
43
39
|
x++;
|
|
44
40
|
}
|
|
45
41
|
}
|
|
46
42
|
}
|
|
47
43
|
}
|
|
48
|
-
|
|
49
44
|
return pixels;
|
|
50
45
|
}
|
|
@@ -5,13 +5,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.getHistogram = getHistogram;
|
|
7
7
|
exports.getHistograms = getHistograms;
|
|
8
|
-
|
|
9
8
|
var _isInteger = _interopRequireDefault(require("is-integer"));
|
|
10
|
-
|
|
11
9
|
var _newArray = _interopRequireDefault(require("new-array"));
|
|
12
|
-
|
|
13
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
|
-
|
|
15
11
|
/**
|
|
16
12
|
* Returns a histogram for the specified channel
|
|
17
13
|
* @memberof Image
|
|
@@ -31,20 +27,18 @@ function getHistogram(options = {}) {
|
|
|
31
27
|
this.checkProcessable('getHistogram', {
|
|
32
28
|
bitDepth: [1, 8, 16]
|
|
33
29
|
});
|
|
34
|
-
|
|
35
30
|
if (channel === undefined) {
|
|
36
31
|
if (this.components > 1) {
|
|
37
32
|
throw new RangeError('You need to define the channel for an image that contains more than one channel');
|
|
38
33
|
}
|
|
39
|
-
|
|
40
34
|
channel = 0;
|
|
41
35
|
}
|
|
42
|
-
|
|
43
36
|
return getChannelHistogram.call(this, channel, {
|
|
44
37
|
useAlpha,
|
|
45
38
|
maxSlots
|
|
46
39
|
});
|
|
47
40
|
}
|
|
41
|
+
|
|
48
42
|
/**
|
|
49
43
|
* Returns an array (number of channels) of array (number of slots) containing
|
|
50
44
|
* the number of data of a specific intensity.
|
|
@@ -64,8 +58,6 @@ function getHistogram(options = {}) {
|
|
|
64
58
|
* useAlpha: false
|
|
65
59
|
* });
|
|
66
60
|
*/
|
|
67
|
-
|
|
68
|
-
|
|
69
61
|
function getHistograms(options = {}) {
|
|
70
62
|
const {
|
|
71
63
|
maxSlots = 256,
|
|
@@ -75,30 +67,27 @@ function getHistograms(options = {}) {
|
|
|
75
67
|
bitDepth: [8, 16]
|
|
76
68
|
});
|
|
77
69
|
let results = new Array(useAlpha ? this.components : this.channels);
|
|
78
|
-
|
|
79
70
|
for (let i = 0; i < results.length; i++) {
|
|
80
71
|
results[i] = getChannelHistogram.call(this, i, {
|
|
81
72
|
useAlpha,
|
|
82
73
|
maxSlots
|
|
83
74
|
});
|
|
84
75
|
}
|
|
85
|
-
|
|
86
76
|
return results;
|
|
87
77
|
}
|
|
88
|
-
|
|
89
78
|
function getChannelHistogram(channel, options) {
|
|
90
79
|
let {
|
|
91
80
|
useAlpha,
|
|
92
81
|
maxSlots
|
|
93
|
-
} = options;
|
|
82
|
+
} = options;
|
|
83
|
+
|
|
84
|
+
// for a mask, return a number array containing count of black and white points (black = array[0], white = array[1])
|
|
94
85
|
|
|
95
86
|
if (this.bitDepth === 1) {
|
|
96
87
|
let blackWhiteCount = [0, 0];
|
|
97
|
-
|
|
98
88
|
for (let i = 0; i < this.height; i++) {
|
|
99
89
|
for (let j = 0; j < this.width; j++) {
|
|
100
90
|
let value = this.getBitXY(i, j);
|
|
101
|
-
|
|
102
91
|
if (value === 0) {
|
|
103
92
|
blackWhiteCount[0] += 1;
|
|
104
93
|
} else if (value === 1) {
|
|
@@ -106,31 +95,24 @@ function getChannelHistogram(channel, options) {
|
|
|
106
95
|
}
|
|
107
96
|
}
|
|
108
97
|
}
|
|
109
|
-
|
|
110
98
|
return blackWhiteCount;
|
|
111
99
|
}
|
|
112
|
-
|
|
113
100
|
let bitSlots = Math.log2(maxSlots);
|
|
114
|
-
|
|
115
101
|
if (!(0, _isInteger.default)(bitSlots)) {
|
|
116
102
|
throw new RangeError('maxSlots must be a power of 2, for example: 64, 256, 1024');
|
|
117
|
-
}
|
|
103
|
+
}
|
|
104
|
+
// we will compare the bitSlots to the bitDepth of the image
|
|
118
105
|
// based on this we will shift the values. This allows to generate a histogram
|
|
119
106
|
// of 16 grey even if the images has 256 shade of grey
|
|
120
107
|
|
|
121
|
-
|
|
122
108
|
let bitShift = 0;
|
|
123
|
-
|
|
124
109
|
if (this.bitDepth > bitSlots) {
|
|
125
110
|
bitShift = this.bitDepth - bitSlots;
|
|
126
111
|
}
|
|
127
|
-
|
|
128
112
|
let data = this.data;
|
|
129
113
|
let result = (0, _newArray.default)(Math.pow(2, Math.min(this.bitDepth, bitSlots)), 0);
|
|
130
|
-
|
|
131
114
|
if (useAlpha && this.alpha) {
|
|
132
115
|
let alphaChannelDiff = this.channels - channel - 1;
|
|
133
|
-
|
|
134
116
|
for (let i = channel; i < data.length; i += this.channels) {
|
|
135
117
|
result[data[i] >> bitShift] += data[i + alphaChannelDiff] / this.maxValue;
|
|
136
118
|
}
|
|
@@ -139,6 +121,5 @@ function getChannelHistogram(channel, options) {
|
|
|
139
121
|
result[data[i] >> bitShift]++;
|
|
140
122
|
}
|
|
141
123
|
}
|
|
142
|
-
|
|
143
124
|
return result;
|
|
144
125
|
}
|