optimized canvas handling

pull/50/head
Vladimir Mandic 2020-11-02 17:25:35 -05:00
parent 00d525b207
commit 9781699e95
15 changed files with 405 additions and 331 deletions

View File

@ -5947,10 +5947,12 @@ class Human {
this.version = app.version; this.version = app.version;
this.defaults = defaults; this.defaults = defaults;
this.config = defaults; this.config = defaults;
this.fx = tf.ENV.flags.IS_BROWSER && typeof document !== "undefined" ? new fxImage.Canvas() : null; this.fx = null;
this.state = "idle"; this.state = "idle";
this.numTensors = 0; this.numTensors = 0;
this.analyzeMemoryLeaks = false; this.analyzeMemoryLeaks = false;
this.inCanvas = null;
this.outCanvas = null;
this.models = { this.models = {
facemesh: null, facemesh: null,
posenet: null, posenet: null,
@ -6027,12 +6029,14 @@ class Human {
} }
} }
tfImage(input) { tfImage(input) {
let filtered; let tensor;
const originalWidth = input.naturalWidth || input.videoWidth || input.width || input.shape && input.shape[1] > 0; if (input instanceof tf.Tensor) {
const originalHeight = input.naturalHeight || input.videoHeight || input.height || input.shape && input.shape[2] > 0; tensor = tf.clone(input);
let targetWidth = originalWidth; } else {
let targetHeight = originalHeight; const originalWidth = input.naturalWidth || input.videoWidth || input.width || input.shape && input.shape[1] > 0;
if (this.fx && this.config.filter.enabled && !(input instanceof tf.Tensor)) { const originalHeight = input.naturalHeight || input.videoHeight || input.height || input.shape && input.shape[2] > 0;
let targetWidth = originalWidth;
let targetHeight = originalHeight;
if (this.config.filter.width > 0) if (this.config.filter.width > 0)
targetWidth = this.config.filter.width; targetWidth = this.config.filter.width;
else if (this.config.filter.height > 0) else if (this.config.filter.height > 0)
@ -6041,60 +6045,69 @@ class Human {
targetHeight = this.config.filter.height; targetHeight = this.config.filter.height;
else if (this.config.filter.width > 0) else if (this.config.filter.width > 0)
targetHeight = originalHeight * (this.config.filter.width / originalWidth); targetHeight = originalHeight * (this.config.filter.width / originalWidth);
const offscreenCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas"); if (!this.inCanvas || this.inCanvas.width !== originalWidth || this.inCanvas.height !== originalHeight) {
if (offscreenCanvas.width !== targetWidth) this.inCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas");
offscreenCanvas.width = targetWidth; if (this.inCanvas.width !== targetWidth)
if (offscreenCanvas.height !== targetHeight) this.inCanvas.width = targetWidth;
offscreenCanvas.height = targetHeight; if (this.inCanvas.height !== targetHeight)
const ctx = offscreenCanvas.getContext("2d"); this.inCanvas.height = targetHeight;
}
const ctx = this.inCanvas.getContext("2d");
if (input instanceof ImageData) if (input instanceof ImageData)
ctx.putImageData(input, 0, 0); ctx.putImageData(input, 0, 0);
else else
ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, offscreenCanvas.width, offscreenCanvas.height); ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, this.inCanvas.width, this.inCanvas.height);
this.fx.reset(); if (this.config.filter.enabled) {
this.fx.addFilter("brightness", this.config.filter.brightness); if (!this.outCanvas || this.inCanvas.width !== this.outCanvas.width || this.inCanvas.height !== this.outCanvas.height) {
if (this.config.filter.contrast !== 0) this.outCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(this.inCanvas.width, this.inCanvas.height) : document.createElement("canvas");
this.fx.addFilter("contrast", this.config.filter.contrast); if (this.outCanvas.width !== this.inCanvas.width)
if (this.config.filter.sharpness !== 0) this.outCanvas.width = this.inCanvas.width;
this.fx.addFilter("sharpen", this.config.filter.sharpness); if (this.outCanvas.height !== this.inCanvas.height)
if (this.config.filter.blur !== 0) this.outCanvas.height = this.inCanvas.height;
this.fx.addFilter("blur", this.config.filter.blur); }
if (this.config.filter.saturation !== 0) if (!this.fx)
this.fx.addFilter("saturation", this.config.filter.saturation); this.fx = tf.ENV.flags.IS_BROWSER && typeof document !== "undefined" ? new fxImage.Canvas({canvas: this.outCanvas}) : null;
if (this.config.filter.hue !== 0) this.fx.reset();
this.fx.addFilter("hue", this.config.filter.hue); this.fx.addFilter("brightness", this.config.filter.brightness);
if (this.config.filter.negative) if (this.config.filter.contrast !== 0)
this.fx.addFilter("negative"); this.fx.addFilter("contrast", this.config.filter.contrast);
if (this.config.filter.sepia) if (this.config.filter.sharpness !== 0)
this.fx.addFilter("sepia"); this.fx.addFilter("sharpen", this.config.filter.sharpness);
if (this.config.filter.vintage) if (this.config.filter.blur !== 0)
this.fx.addFilter("brownie"); this.fx.addFilter("blur", this.config.filter.blur);
if (this.config.filter.sepia) if (this.config.filter.saturation !== 0)
this.fx.addFilter("sepia"); this.fx.addFilter("saturation", this.config.filter.saturation);
if (this.config.filter.kodachrome) if (this.config.filter.hue !== 0)
this.fx.addFilter("kodachrome"); this.fx.addFilter("hue", this.config.filter.hue);
if (this.config.filter.technicolor) if (this.config.filter.negative)
this.fx.addFilter("technicolor"); this.fx.addFilter("negative");
if (this.config.filter.polaroid) if (this.config.filter.sepia)
this.fx.addFilter("polaroid"); this.fx.addFilter("sepia");
if (this.config.filter.pixelate !== 0) if (this.config.filter.vintage)
this.fx.addFilter("pixelate", this.config.filter.pixelate); this.fx.addFilter("brownie");
filtered = this.fx.apply(offscreenCanvas); if (this.config.filter.sepia)
} this.fx.addFilter("sepia");
let tensor; if (this.config.filter.kodachrome)
if (input instanceof tf.Tensor) { this.fx.addFilter("kodachrome");
tensor = tf.clone(input); if (this.config.filter.technicolor)
} else { this.fx.addFilter("technicolor");
const canvas = filtered || input; if (this.config.filter.polaroid)
this.fx.addFilter("polaroid");
if (this.config.filter.pixelate !== 0)
this.fx.addFilter("pixelate", this.config.filter.pixelate);
this.outCanvas = this.fx.apply(this.inCanvas);
}
if (!this.outCanvas)
this.outCanvas = this.inCanvas;
let pixels; let pixels;
if (this.config.backend === "webgl" || canvas instanceof ImageData) { if (this.config.backend === "webgl" || this.outCanvas instanceof ImageData) {
pixels = tf.browser.fromPixels(canvas); pixels = tf.browser.fromPixels(this.outCanvas);
} else { } else {
const tempCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas"); const tempCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas");
tempCanvas.width = targetWidth; tempCanvas.width = targetWidth;
tempCanvas.height = targetHeight; tempCanvas.height = targetHeight;
const tempCtx = tempCanvas.getContext("2d"); const tempCtx = tempCanvas.getContext("2d");
tempCtx.drawImage(canvas, 0, 0); tempCtx.drawImage(this.outCanvas, 0, 0);
const data = tempCtx.getImageData(0, 0, targetWidth, targetHeight); const data = tempCtx.getImageData(0, 0, targetWidth, targetHeight);
pixels = tf.browser.fromPixels(data); pixels = tf.browser.fromPixels(data);
} }
@ -6103,7 +6116,7 @@ class Human {
pixels.dispose(); pixels.dispose();
casted.dispose(); casted.dispose();
} }
return {tensor, canvas: this.config.filter.return ? filtered : null}; return {tensor, canvas: this.config.filter.return ? this.outCanvas : null};
} }
async detect(input, userConfig = {}) { async detect(input, userConfig = {}) {
this.state = "config"; this.state = "config";

File diff suppressed because one or more lines are too long

View File

@ -120,7 +120,7 @@
"imports": [] "imports": []
}, },
"src/human.js": { "src/human.js": {
"bytes": 13768, "bytes": 14560,
"imports": [ "imports": [
{ {
"path": "src/facemesh/facemesh.js" "path": "src/facemesh/facemesh.js"
@ -275,7 +275,7 @@
"dist/human.esm-nobundle.js.map": { "dist/human.esm-nobundle.js.map": {
"imports": [], "imports": [],
"inputs": {}, "inputs": {},
"bytes": 254548 "bytes": 255849
}, },
"dist/human.esm-nobundle.js": { "dist/human.esm-nobundle.js": {
"imports": [], "imports": [],
@ -374,13 +374,13 @@
"bytesInOutput": 3012 "bytesInOutput": 3012
}, },
"src/human.js": { "src/human.js": {
"bytesInOutput": 11904 "bytesInOutput": 12748
}, },
"src/human.js": { "src/human.js": {
"bytesInOutput": 0 "bytesInOutput": 0
} }
}, },
"bytes": 158147 "bytes": 158991
} }
} }
} }

119
dist/human.esm.js vendored
View File

@ -72996,10 +72996,12 @@ class Human {
this.version = app.version; this.version = app.version;
this.defaults = defaults; this.defaults = defaults;
this.config = defaults; this.config = defaults;
this.fx = tf.ENV.flags.IS_BROWSER && typeof document !== "undefined" ? new fxImage.Canvas() : null; this.fx = null;
this.state = "idle"; this.state = "idle";
this.numTensors = 0; this.numTensors = 0;
this.analyzeMemoryLeaks = false; this.analyzeMemoryLeaks = false;
this.inCanvas = null;
this.outCanvas = null;
this.models = { this.models = {
facemesh: null, facemesh: null,
posenet: null, posenet: null,
@ -73076,12 +73078,14 @@ class Human {
} }
} }
tfImage(input) { tfImage(input) {
let filtered; let tensor;
const originalWidth = input.naturalWidth || input.videoWidth || input.width || input.shape && input.shape[1] > 0; if (input instanceof tf.Tensor) {
const originalHeight = input.naturalHeight || input.videoHeight || input.height || input.shape && input.shape[2] > 0; tensor = tf.clone(input);
let targetWidth = originalWidth; } else {
let targetHeight = originalHeight; const originalWidth = input.naturalWidth || input.videoWidth || input.width || input.shape && input.shape[1] > 0;
if (this.fx && this.config.filter.enabled && !(input instanceof tf.Tensor)) { const originalHeight = input.naturalHeight || input.videoHeight || input.height || input.shape && input.shape[2] > 0;
let targetWidth = originalWidth;
let targetHeight = originalHeight;
if (this.config.filter.width > 0) if (this.config.filter.width > 0)
targetWidth = this.config.filter.width; targetWidth = this.config.filter.width;
else if (this.config.filter.height > 0) else if (this.config.filter.height > 0)
@ -73090,60 +73094,69 @@ class Human {
targetHeight = this.config.filter.height; targetHeight = this.config.filter.height;
else if (this.config.filter.width > 0) else if (this.config.filter.width > 0)
targetHeight = originalHeight * (this.config.filter.width / originalWidth); targetHeight = originalHeight * (this.config.filter.width / originalWidth);
const offscreenCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas"); if (!this.inCanvas || this.inCanvas.width !== originalWidth || this.inCanvas.height !== originalHeight) {
if (offscreenCanvas.width !== targetWidth) this.inCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas");
offscreenCanvas.width = targetWidth; if (this.inCanvas.width !== targetWidth)
if (offscreenCanvas.height !== targetHeight) this.inCanvas.width = targetWidth;
offscreenCanvas.height = targetHeight; if (this.inCanvas.height !== targetHeight)
const ctx = offscreenCanvas.getContext("2d"); this.inCanvas.height = targetHeight;
}
const ctx = this.inCanvas.getContext("2d");
if (input instanceof ImageData) if (input instanceof ImageData)
ctx.putImageData(input, 0, 0); ctx.putImageData(input, 0, 0);
else else
ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, offscreenCanvas.width, offscreenCanvas.height); ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, this.inCanvas.width, this.inCanvas.height);
this.fx.reset(); if (this.config.filter.enabled) {
this.fx.addFilter("brightness", this.config.filter.brightness); if (!this.outCanvas || this.inCanvas.width !== this.outCanvas.width || this.inCanvas.height !== this.outCanvas.height) {
if (this.config.filter.contrast !== 0) this.outCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(this.inCanvas.width, this.inCanvas.height) : document.createElement("canvas");
this.fx.addFilter("contrast", this.config.filter.contrast); if (this.outCanvas.width !== this.inCanvas.width)
if (this.config.filter.sharpness !== 0) this.outCanvas.width = this.inCanvas.width;
this.fx.addFilter("sharpen", this.config.filter.sharpness); if (this.outCanvas.height !== this.inCanvas.height)
if (this.config.filter.blur !== 0) this.outCanvas.height = this.inCanvas.height;
this.fx.addFilter("blur", this.config.filter.blur); }
if (this.config.filter.saturation !== 0) if (!this.fx)
this.fx.addFilter("saturation", this.config.filter.saturation); this.fx = tf.ENV.flags.IS_BROWSER && typeof document !== "undefined" ? new fxImage.Canvas({canvas: this.outCanvas}) : null;
if (this.config.filter.hue !== 0) this.fx.reset();
this.fx.addFilter("hue", this.config.filter.hue); this.fx.addFilter("brightness", this.config.filter.brightness);
if (this.config.filter.negative) if (this.config.filter.contrast !== 0)
this.fx.addFilter("negative"); this.fx.addFilter("contrast", this.config.filter.contrast);
if (this.config.filter.sepia) if (this.config.filter.sharpness !== 0)
this.fx.addFilter("sepia"); this.fx.addFilter("sharpen", this.config.filter.sharpness);
if (this.config.filter.vintage) if (this.config.filter.blur !== 0)
this.fx.addFilter("brownie"); this.fx.addFilter("blur", this.config.filter.blur);
if (this.config.filter.sepia) if (this.config.filter.saturation !== 0)
this.fx.addFilter("sepia"); this.fx.addFilter("saturation", this.config.filter.saturation);
if (this.config.filter.kodachrome) if (this.config.filter.hue !== 0)
this.fx.addFilter("kodachrome"); this.fx.addFilter("hue", this.config.filter.hue);
if (this.config.filter.technicolor) if (this.config.filter.negative)
this.fx.addFilter("technicolor"); this.fx.addFilter("negative");
if (this.config.filter.polaroid) if (this.config.filter.sepia)
this.fx.addFilter("polaroid"); this.fx.addFilter("sepia");
if (this.config.filter.pixelate !== 0) if (this.config.filter.vintage)
this.fx.addFilter("pixelate", this.config.filter.pixelate); this.fx.addFilter("brownie");
filtered = this.fx.apply(offscreenCanvas); if (this.config.filter.sepia)
} this.fx.addFilter("sepia");
let tensor; if (this.config.filter.kodachrome)
if (input instanceof tf.Tensor) { this.fx.addFilter("kodachrome");
tensor = tf.clone(input); if (this.config.filter.technicolor)
} else { this.fx.addFilter("technicolor");
const canvas = filtered || input; if (this.config.filter.polaroid)
this.fx.addFilter("polaroid");
if (this.config.filter.pixelate !== 0)
this.fx.addFilter("pixelate", this.config.filter.pixelate);
this.outCanvas = this.fx.apply(this.inCanvas);
}
if (!this.outCanvas)
this.outCanvas = this.inCanvas;
let pixels; let pixels;
if (this.config.backend === "webgl" || canvas instanceof ImageData) { if (this.config.backend === "webgl" || this.outCanvas instanceof ImageData) {
pixels = tf.browser.fromPixels(canvas); pixels = tf.browser.fromPixels(this.outCanvas);
} else { } else {
const tempCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas"); const tempCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas");
tempCanvas.width = targetWidth; tempCanvas.width = targetWidth;
tempCanvas.height = targetHeight; tempCanvas.height = targetHeight;
const tempCtx = tempCanvas.getContext("2d"); const tempCtx = tempCanvas.getContext("2d");
tempCtx.drawImage(canvas, 0, 0); tempCtx.drawImage(this.outCanvas, 0, 0);
const data = tempCtx.getImageData(0, 0, targetWidth, targetHeight); const data = tempCtx.getImageData(0, 0, targetWidth, targetHeight);
pixels = tf.browser.fromPixels(data); pixels = tf.browser.fromPixels(data);
} }
@ -73152,7 +73165,7 @@ class Human {
pixels.dispose(); pixels.dispose();
casted.dispose(); casted.dispose();
} }
return {tensor, canvas: this.config.filter.return ? filtered : null}; return {tensor, canvas: this.config.filter.return ? this.outCanvas : null};
} }
async detect(input, userConfig = {}) { async detect(input, userConfig = {}) {
this.state = "config"; this.state = "config";

File diff suppressed because one or more lines are too long

8
dist/human.esm.json vendored
View File

@ -294,7 +294,7 @@
"imports": [] "imports": []
}, },
"src/human.js": { "src/human.js": {
"bytes": 13768, "bytes": 14560,
"imports": [ "imports": [
{ {
"path": "node_modules/@tensorflow/tfjs/dist/tf.node.js" "path": "node_modules/@tensorflow/tfjs/dist/tf.node.js"
@ -481,7 +481,7 @@
"dist/human.esm.js.map": { "dist/human.esm.js.map": {
"imports": [], "imports": [],
"inputs": {}, "inputs": {},
"bytes": 5127854 "bytes": 5129155
}, },
"dist/human.esm.js": { "dist/human.esm.js": {
"imports": [], "imports": [],
@ -637,13 +637,13 @@
"bytesInOutput": 3012 "bytesInOutput": 3012
}, },
"src/human.js": { "src/human.js": {
"bytesInOutput": 11894 "bytesInOutput": 12738
}, },
"src/human.js": { "src/human.js": {
"bytesInOutput": 0 "bytesInOutput": 0
} }
}, },
"bytes": 2927113 "bytes": 2927957
} }
} }
} }

119
dist/human.js vendored
View File

@ -73001,10 +73001,12 @@ var Human = (() => {
this.version = app.version; this.version = app.version;
this.defaults = defaults; this.defaults = defaults;
this.config = defaults; this.config = defaults;
this.fx = tf.ENV.flags.IS_BROWSER && typeof document !== "undefined" ? new fxImage.Canvas() : null; this.fx = null;
this.state = "idle"; this.state = "idle";
this.numTensors = 0; this.numTensors = 0;
this.analyzeMemoryLeaks = false; this.analyzeMemoryLeaks = false;
this.inCanvas = null;
this.outCanvas = null;
this.models = { this.models = {
facemesh: null, facemesh: null,
posenet: null, posenet: null,
@ -73081,12 +73083,14 @@ var Human = (() => {
} }
} }
tfImage(input) { tfImage(input) {
let filtered; let tensor;
const originalWidth = input.naturalWidth || input.videoWidth || input.width || input.shape && input.shape[1] > 0; if (input instanceof tf.Tensor) {
const originalHeight = input.naturalHeight || input.videoHeight || input.height || input.shape && input.shape[2] > 0; tensor = tf.clone(input);
let targetWidth = originalWidth; } else {
let targetHeight = originalHeight; const originalWidth = input.naturalWidth || input.videoWidth || input.width || input.shape && input.shape[1] > 0;
if (this.fx && this.config.filter.enabled && !(input instanceof tf.Tensor)) { const originalHeight = input.naturalHeight || input.videoHeight || input.height || input.shape && input.shape[2] > 0;
let targetWidth = originalWidth;
let targetHeight = originalHeight;
if (this.config.filter.width > 0) if (this.config.filter.width > 0)
targetWidth = this.config.filter.width; targetWidth = this.config.filter.width;
else if (this.config.filter.height > 0) else if (this.config.filter.height > 0)
@ -73095,60 +73099,69 @@ var Human = (() => {
targetHeight = this.config.filter.height; targetHeight = this.config.filter.height;
else if (this.config.filter.width > 0) else if (this.config.filter.width > 0)
targetHeight = originalHeight * (this.config.filter.width / originalWidth); targetHeight = originalHeight * (this.config.filter.width / originalWidth);
const offscreenCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas"); if (!this.inCanvas || this.inCanvas.width !== originalWidth || this.inCanvas.height !== originalHeight) {
if (offscreenCanvas.width !== targetWidth) this.inCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas");
offscreenCanvas.width = targetWidth; if (this.inCanvas.width !== targetWidth)
if (offscreenCanvas.height !== targetHeight) this.inCanvas.width = targetWidth;
offscreenCanvas.height = targetHeight; if (this.inCanvas.height !== targetHeight)
const ctx = offscreenCanvas.getContext("2d"); this.inCanvas.height = targetHeight;
}
const ctx = this.inCanvas.getContext("2d");
if (input instanceof ImageData) if (input instanceof ImageData)
ctx.putImageData(input, 0, 0); ctx.putImageData(input, 0, 0);
else else
ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, offscreenCanvas.width, offscreenCanvas.height); ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, this.inCanvas.width, this.inCanvas.height);
this.fx.reset(); if (this.config.filter.enabled) {
this.fx.addFilter("brightness", this.config.filter.brightness); if (!this.outCanvas || this.inCanvas.width !== this.outCanvas.width || this.inCanvas.height !== this.outCanvas.height) {
if (this.config.filter.contrast !== 0) this.outCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(this.inCanvas.width, this.inCanvas.height) : document.createElement("canvas");
this.fx.addFilter("contrast", this.config.filter.contrast); if (this.outCanvas.width !== this.inCanvas.width)
if (this.config.filter.sharpness !== 0) this.outCanvas.width = this.inCanvas.width;
this.fx.addFilter("sharpen", this.config.filter.sharpness); if (this.outCanvas.height !== this.inCanvas.height)
if (this.config.filter.blur !== 0) this.outCanvas.height = this.inCanvas.height;
this.fx.addFilter("blur", this.config.filter.blur); }
if (this.config.filter.saturation !== 0) if (!this.fx)
this.fx.addFilter("saturation", this.config.filter.saturation); this.fx = tf.ENV.flags.IS_BROWSER && typeof document !== "undefined" ? new fxImage.Canvas({canvas: this.outCanvas}) : null;
if (this.config.filter.hue !== 0) this.fx.reset();
this.fx.addFilter("hue", this.config.filter.hue); this.fx.addFilter("brightness", this.config.filter.brightness);
if (this.config.filter.negative) if (this.config.filter.contrast !== 0)
this.fx.addFilter("negative"); this.fx.addFilter("contrast", this.config.filter.contrast);
if (this.config.filter.sepia) if (this.config.filter.sharpness !== 0)
this.fx.addFilter("sepia"); this.fx.addFilter("sharpen", this.config.filter.sharpness);
if (this.config.filter.vintage) if (this.config.filter.blur !== 0)
this.fx.addFilter("brownie"); this.fx.addFilter("blur", this.config.filter.blur);
if (this.config.filter.sepia) if (this.config.filter.saturation !== 0)
this.fx.addFilter("sepia"); this.fx.addFilter("saturation", this.config.filter.saturation);
if (this.config.filter.kodachrome) if (this.config.filter.hue !== 0)
this.fx.addFilter("kodachrome"); this.fx.addFilter("hue", this.config.filter.hue);
if (this.config.filter.technicolor) if (this.config.filter.negative)
this.fx.addFilter("technicolor"); this.fx.addFilter("negative");
if (this.config.filter.polaroid) if (this.config.filter.sepia)
this.fx.addFilter("polaroid"); this.fx.addFilter("sepia");
if (this.config.filter.pixelate !== 0) if (this.config.filter.vintage)
this.fx.addFilter("pixelate", this.config.filter.pixelate); this.fx.addFilter("brownie");
filtered = this.fx.apply(offscreenCanvas); if (this.config.filter.sepia)
} this.fx.addFilter("sepia");
let tensor; if (this.config.filter.kodachrome)
if (input instanceof tf.Tensor) { this.fx.addFilter("kodachrome");
tensor = tf.clone(input); if (this.config.filter.technicolor)
} else { this.fx.addFilter("technicolor");
const canvas = filtered || input; if (this.config.filter.polaroid)
this.fx.addFilter("polaroid");
if (this.config.filter.pixelate !== 0)
this.fx.addFilter("pixelate", this.config.filter.pixelate);
this.outCanvas = this.fx.apply(this.inCanvas);
}
if (!this.outCanvas)
this.outCanvas = this.inCanvas;
let pixels; let pixels;
if (this.config.backend === "webgl" || canvas instanceof ImageData) { if (this.config.backend === "webgl" || this.outCanvas instanceof ImageData) {
pixels = tf.browser.fromPixels(canvas); pixels = tf.browser.fromPixels(this.outCanvas);
} else { } else {
const tempCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas"); const tempCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas");
tempCanvas.width = targetWidth; tempCanvas.width = targetWidth;
tempCanvas.height = targetHeight; tempCanvas.height = targetHeight;
const tempCtx = tempCanvas.getContext("2d"); const tempCtx = tempCanvas.getContext("2d");
tempCtx.drawImage(canvas, 0, 0); tempCtx.drawImage(this.outCanvas, 0, 0);
const data = tempCtx.getImageData(0, 0, targetWidth, targetHeight); const data = tempCtx.getImageData(0, 0, targetWidth, targetHeight);
pixels = tf.browser.fromPixels(data); pixels = tf.browser.fromPixels(data);
} }
@ -73157,7 +73170,7 @@ var Human = (() => {
pixels.dispose(); pixels.dispose();
casted.dispose(); casted.dispose();
} }
return {tensor, canvas: this.config.filter.return ? filtered : null}; return {tensor, canvas: this.config.filter.return ? this.outCanvas : null};
} }
async detect(input, userConfig = {}) { async detect(input, userConfig = {}) {
this.state = "config"; this.state = "config";

4
dist/human.js.map vendored

File diff suppressed because one or more lines are too long

8
dist/human.json vendored
View File

@ -294,7 +294,7 @@
"imports": [] "imports": []
}, },
"src/human.js": { "src/human.js": {
"bytes": 13768, "bytes": 14560,
"imports": [ "imports": [
{ {
"path": "node_modules/@tensorflow/tfjs/dist/tf.node.js" "path": "node_modules/@tensorflow/tfjs/dist/tf.node.js"
@ -481,7 +481,7 @@
"dist/human.js.map": { "dist/human.js.map": {
"imports": [], "imports": [],
"inputs": {}, "inputs": {},
"bytes": 5131716 "bytes": 5133045
}, },
"dist/human.js": { "dist/human.js": {
"imports": [], "imports": [],
@ -637,10 +637,10 @@
"bytesInOutput": 3144 "bytesInOutput": 3144
}, },
"src/human.js": { "src/human.js": {
"bytesInOutput": 13235 "bytesInOutput": 14131
} }
}, },
"bytes": 3073187 "bytes": 3074083
} }
} }
} }

View File

@ -5950,10 +5950,12 @@ class Human {
this.version = app.version; this.version = app.version;
this.defaults = defaults; this.defaults = defaults;
this.config = defaults; this.config = defaults;
this.fx = tf.ENV.flags.IS_BROWSER && typeof document !== "undefined" ? new fxImage.Canvas() : null; this.fx = null;
this.state = "idle"; this.state = "idle";
this.numTensors = 0; this.numTensors = 0;
this.analyzeMemoryLeaks = false; this.analyzeMemoryLeaks = false;
this.inCanvas = null;
this.outCanvas = null;
this.models = { this.models = {
facemesh: null, facemesh: null,
posenet: null, posenet: null,
@ -6030,12 +6032,14 @@ class Human {
} }
} }
tfImage(input) { tfImage(input) {
let filtered; let tensor;
const originalWidth = input.naturalWidth || input.videoWidth || input.width || input.shape && input.shape[1] > 0; if (input instanceof tf.Tensor) {
const originalHeight = input.naturalHeight || input.videoHeight || input.height || input.shape && input.shape[2] > 0; tensor = tf.clone(input);
let targetWidth = originalWidth; } else {
let targetHeight = originalHeight; const originalWidth = input.naturalWidth || input.videoWidth || input.width || input.shape && input.shape[1] > 0;
if (this.fx && this.config.filter.enabled && !(input instanceof tf.Tensor)) { const originalHeight = input.naturalHeight || input.videoHeight || input.height || input.shape && input.shape[2] > 0;
let targetWidth = originalWidth;
let targetHeight = originalHeight;
if (this.config.filter.width > 0) if (this.config.filter.width > 0)
targetWidth = this.config.filter.width; targetWidth = this.config.filter.width;
else if (this.config.filter.height > 0) else if (this.config.filter.height > 0)
@ -6044,60 +6048,69 @@ class Human {
targetHeight = this.config.filter.height; targetHeight = this.config.filter.height;
else if (this.config.filter.width > 0) else if (this.config.filter.width > 0)
targetHeight = originalHeight * (this.config.filter.width / originalWidth); targetHeight = originalHeight * (this.config.filter.width / originalWidth);
const offscreenCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas"); if (!this.inCanvas || this.inCanvas.width !== originalWidth || this.inCanvas.height !== originalHeight) {
if (offscreenCanvas.width !== targetWidth) this.inCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas");
offscreenCanvas.width = targetWidth; if (this.inCanvas.width !== targetWidth)
if (offscreenCanvas.height !== targetHeight) this.inCanvas.width = targetWidth;
offscreenCanvas.height = targetHeight; if (this.inCanvas.height !== targetHeight)
const ctx = offscreenCanvas.getContext("2d"); this.inCanvas.height = targetHeight;
}
const ctx = this.inCanvas.getContext("2d");
if (input instanceof ImageData) if (input instanceof ImageData)
ctx.putImageData(input, 0, 0); ctx.putImageData(input, 0, 0);
else else
ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, offscreenCanvas.width, offscreenCanvas.height); ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, this.inCanvas.width, this.inCanvas.height);
this.fx.reset(); if (this.config.filter.enabled) {
this.fx.addFilter("brightness", this.config.filter.brightness); if (!this.outCanvas || this.inCanvas.width !== this.outCanvas.width || this.inCanvas.height !== this.outCanvas.height) {
if (this.config.filter.contrast !== 0) this.outCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(this.inCanvas.width, this.inCanvas.height) : document.createElement("canvas");
this.fx.addFilter("contrast", this.config.filter.contrast); if (this.outCanvas.width !== this.inCanvas.width)
if (this.config.filter.sharpness !== 0) this.outCanvas.width = this.inCanvas.width;
this.fx.addFilter("sharpen", this.config.filter.sharpness); if (this.outCanvas.height !== this.inCanvas.height)
if (this.config.filter.blur !== 0) this.outCanvas.height = this.inCanvas.height;
this.fx.addFilter("blur", this.config.filter.blur); }
if (this.config.filter.saturation !== 0) if (!this.fx)
this.fx.addFilter("saturation", this.config.filter.saturation); this.fx = tf.ENV.flags.IS_BROWSER && typeof document !== "undefined" ? new fxImage.Canvas({canvas: this.outCanvas}) : null;
if (this.config.filter.hue !== 0) this.fx.reset();
this.fx.addFilter("hue", this.config.filter.hue); this.fx.addFilter("brightness", this.config.filter.brightness);
if (this.config.filter.negative) if (this.config.filter.contrast !== 0)
this.fx.addFilter("negative"); this.fx.addFilter("contrast", this.config.filter.contrast);
if (this.config.filter.sepia) if (this.config.filter.sharpness !== 0)
this.fx.addFilter("sepia"); this.fx.addFilter("sharpen", this.config.filter.sharpness);
if (this.config.filter.vintage) if (this.config.filter.blur !== 0)
this.fx.addFilter("brownie"); this.fx.addFilter("blur", this.config.filter.blur);
if (this.config.filter.sepia) if (this.config.filter.saturation !== 0)
this.fx.addFilter("sepia"); this.fx.addFilter("saturation", this.config.filter.saturation);
if (this.config.filter.kodachrome) if (this.config.filter.hue !== 0)
this.fx.addFilter("kodachrome"); this.fx.addFilter("hue", this.config.filter.hue);
if (this.config.filter.technicolor) if (this.config.filter.negative)
this.fx.addFilter("technicolor"); this.fx.addFilter("negative");
if (this.config.filter.polaroid) if (this.config.filter.sepia)
this.fx.addFilter("polaroid"); this.fx.addFilter("sepia");
if (this.config.filter.pixelate !== 0) if (this.config.filter.vintage)
this.fx.addFilter("pixelate", this.config.filter.pixelate); this.fx.addFilter("brownie");
filtered = this.fx.apply(offscreenCanvas); if (this.config.filter.sepia)
} this.fx.addFilter("sepia");
let tensor; if (this.config.filter.kodachrome)
if (input instanceof tf.Tensor) { this.fx.addFilter("kodachrome");
tensor = tf.clone(input); if (this.config.filter.technicolor)
} else { this.fx.addFilter("technicolor");
const canvas = filtered || input; if (this.config.filter.polaroid)
this.fx.addFilter("polaroid");
if (this.config.filter.pixelate !== 0)
this.fx.addFilter("pixelate", this.config.filter.pixelate);
this.outCanvas = this.fx.apply(this.inCanvas);
}
if (!this.outCanvas)
this.outCanvas = this.inCanvas;
let pixels; let pixels;
if (this.config.backend === "webgl" || canvas instanceof ImageData) { if (this.config.backend === "webgl" || this.outCanvas instanceof ImageData) {
pixels = tf.browser.fromPixels(canvas); pixels = tf.browser.fromPixels(this.outCanvas);
} else { } else {
const tempCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas"); const tempCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas");
tempCanvas.width = targetWidth; tempCanvas.width = targetWidth;
tempCanvas.height = targetHeight; tempCanvas.height = targetHeight;
const tempCtx = tempCanvas.getContext("2d"); const tempCtx = tempCanvas.getContext("2d");
tempCtx.drawImage(canvas, 0, 0); tempCtx.drawImage(this.outCanvas, 0, 0);
const data = tempCtx.getImageData(0, 0, targetWidth, targetHeight); const data = tempCtx.getImageData(0, 0, targetWidth, targetHeight);
pixels = tf.browser.fromPixels(data); pixels = tf.browser.fromPixels(data);
} }
@ -6106,7 +6119,7 @@ class Human {
pixels.dispose(); pixels.dispose();
casted.dispose(); casted.dispose();
} }
return {tensor, canvas: this.config.filter.return ? filtered : null}; return {tensor, canvas: this.config.filter.return ? this.outCanvas : null};
} }
async detect(input, userConfig = {}) { async detect(input, userConfig = {}) {
this.state = "config"; this.state = "config";

File diff suppressed because one or more lines are too long

119
dist/human.node.js vendored
View File

@ -74041,10 +74041,12 @@ class Human {
this.version = app.version; this.version = app.version;
this.defaults = defaults; this.defaults = defaults;
this.config = defaults; this.config = defaults;
this.fx = tf.ENV.flags.IS_BROWSER && typeof document !== "undefined" ? new fxImage.Canvas() : null; this.fx = null;
this.state = "idle"; this.state = "idle";
this.numTensors = 0; this.numTensors = 0;
this.analyzeMemoryLeaks = false; this.analyzeMemoryLeaks = false;
this.inCanvas = null;
this.outCanvas = null;
this.models = { this.models = {
facemesh: null, facemesh: null,
posenet: null, posenet: null,
@ -74121,12 +74123,14 @@ class Human {
} }
} }
tfImage(input) { tfImage(input) {
let filtered; let tensor;
const originalWidth = input.naturalWidth || input.videoWidth || input.width || input.shape && input.shape[1] > 0; if (input instanceof tf.Tensor) {
const originalHeight = input.naturalHeight || input.videoHeight || input.height || input.shape && input.shape[2] > 0; tensor = tf.clone(input);
let targetWidth = originalWidth; } else {
let targetHeight = originalHeight; const originalWidth = input.naturalWidth || input.videoWidth || input.width || input.shape && input.shape[1] > 0;
if (this.fx && this.config.filter.enabled && !(input instanceof tf.Tensor)) { const originalHeight = input.naturalHeight || input.videoHeight || input.height || input.shape && input.shape[2] > 0;
let targetWidth = originalWidth;
let targetHeight = originalHeight;
if (this.config.filter.width > 0) if (this.config.filter.width > 0)
targetWidth = this.config.filter.width; targetWidth = this.config.filter.width;
else if (this.config.filter.height > 0) else if (this.config.filter.height > 0)
@ -74135,60 +74139,69 @@ class Human {
targetHeight = this.config.filter.height; targetHeight = this.config.filter.height;
else if (this.config.filter.width > 0) else if (this.config.filter.width > 0)
targetHeight = originalHeight * (this.config.filter.width / originalWidth); targetHeight = originalHeight * (this.config.filter.width / originalWidth);
const offscreenCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas"); if (!this.inCanvas || this.inCanvas.width !== originalWidth || this.inCanvas.height !== originalHeight) {
if (offscreenCanvas.width !== targetWidth) this.inCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas");
offscreenCanvas.width = targetWidth; if (this.inCanvas.width !== targetWidth)
if (offscreenCanvas.height !== targetHeight) this.inCanvas.width = targetWidth;
offscreenCanvas.height = targetHeight; if (this.inCanvas.height !== targetHeight)
const ctx = offscreenCanvas.getContext("2d"); this.inCanvas.height = targetHeight;
}
const ctx = this.inCanvas.getContext("2d");
if (input instanceof ImageData) if (input instanceof ImageData)
ctx.putImageData(input, 0, 0); ctx.putImageData(input, 0, 0);
else else
ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, offscreenCanvas.width, offscreenCanvas.height); ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, this.inCanvas.width, this.inCanvas.height);
this.fx.reset(); if (this.config.filter.enabled) {
this.fx.addFilter("brightness", this.config.filter.brightness); if (!this.outCanvas || this.inCanvas.width !== this.outCanvas.width || this.inCanvas.height !== this.outCanvas.height) {
if (this.config.filter.contrast !== 0) this.outCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(this.inCanvas.width, this.inCanvas.height) : document.createElement("canvas");
this.fx.addFilter("contrast", this.config.filter.contrast); if (this.outCanvas.width !== this.inCanvas.width)
if (this.config.filter.sharpness !== 0) this.outCanvas.width = this.inCanvas.width;
this.fx.addFilter("sharpen", this.config.filter.sharpness); if (this.outCanvas.height !== this.inCanvas.height)
if (this.config.filter.blur !== 0) this.outCanvas.height = this.inCanvas.height;
this.fx.addFilter("blur", this.config.filter.blur); }
if (this.config.filter.saturation !== 0) if (!this.fx)
this.fx.addFilter("saturation", this.config.filter.saturation); this.fx = tf.ENV.flags.IS_BROWSER && typeof document !== "undefined" ? new fxImage.Canvas({canvas: this.outCanvas}) : null;
if (this.config.filter.hue !== 0) this.fx.reset();
this.fx.addFilter("hue", this.config.filter.hue); this.fx.addFilter("brightness", this.config.filter.brightness);
if (this.config.filter.negative) if (this.config.filter.contrast !== 0)
this.fx.addFilter("negative"); this.fx.addFilter("contrast", this.config.filter.contrast);
if (this.config.filter.sepia) if (this.config.filter.sharpness !== 0)
this.fx.addFilter("sepia"); this.fx.addFilter("sharpen", this.config.filter.sharpness);
if (this.config.filter.vintage) if (this.config.filter.blur !== 0)
this.fx.addFilter("brownie"); this.fx.addFilter("blur", this.config.filter.blur);
if (this.config.filter.sepia) if (this.config.filter.saturation !== 0)
this.fx.addFilter("sepia"); this.fx.addFilter("saturation", this.config.filter.saturation);
if (this.config.filter.kodachrome) if (this.config.filter.hue !== 0)
this.fx.addFilter("kodachrome"); this.fx.addFilter("hue", this.config.filter.hue);
if (this.config.filter.technicolor) if (this.config.filter.negative)
this.fx.addFilter("technicolor"); this.fx.addFilter("negative");
if (this.config.filter.polaroid) if (this.config.filter.sepia)
this.fx.addFilter("polaroid"); this.fx.addFilter("sepia");
if (this.config.filter.pixelate !== 0) if (this.config.filter.vintage)
this.fx.addFilter("pixelate", this.config.filter.pixelate); this.fx.addFilter("brownie");
filtered = this.fx.apply(offscreenCanvas); if (this.config.filter.sepia)
} this.fx.addFilter("sepia");
let tensor; if (this.config.filter.kodachrome)
if (input instanceof tf.Tensor) { this.fx.addFilter("kodachrome");
tensor = tf.clone(input); if (this.config.filter.technicolor)
} else { this.fx.addFilter("technicolor");
const canvas = filtered || input; if (this.config.filter.polaroid)
this.fx.addFilter("polaroid");
if (this.config.filter.pixelate !== 0)
this.fx.addFilter("pixelate", this.config.filter.pixelate);
this.outCanvas = this.fx.apply(this.inCanvas);
}
if (!this.outCanvas)
this.outCanvas = this.inCanvas;
let pixels; let pixels;
if (this.config.backend === "webgl" || canvas instanceof ImageData) { if (this.config.backend === "webgl" || this.outCanvas instanceof ImageData) {
pixels = tf.browser.fromPixels(canvas); pixels = tf.browser.fromPixels(this.outCanvas);
} else { } else {
const tempCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas"); const tempCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement("canvas");
tempCanvas.width = targetWidth; tempCanvas.width = targetWidth;
tempCanvas.height = targetHeight; tempCanvas.height = targetHeight;
const tempCtx = tempCanvas.getContext("2d"); const tempCtx = tempCanvas.getContext("2d");
tempCtx.drawImage(canvas, 0, 0); tempCtx.drawImage(this.outCanvas, 0, 0);
const data = tempCtx.getImageData(0, 0, targetWidth, targetHeight); const data = tempCtx.getImageData(0, 0, targetWidth, targetHeight);
pixels = tf.browser.fromPixels(data); pixels = tf.browser.fromPixels(data);
} }
@ -74197,7 +74210,7 @@ class Human {
pixels.dispose(); pixels.dispose();
casted.dispose(); casted.dispose();
} }
return {tensor, canvas: this.config.filter.return ? filtered : null}; return {tensor, canvas: this.config.filter.return ? this.outCanvas : null};
} }
async detect(input, userConfig = {}) { async detect(input, userConfig = {}) {
this.state = "config"; this.state = "config";

File diff suppressed because one or more lines are too long

View File

@ -120,7 +120,7 @@
"imports": [] "imports": []
}, },
"src/human.js": { "src/human.js": {
"bytes": 13768, "bytes": 14560,
"imports": [ "imports": [
{ {
"path": "src/facemesh/facemesh.js" "path": "src/facemesh/facemesh.js"
@ -275,7 +275,7 @@
"dist/human.node-nobundle.js.map": { "dist/human.node-nobundle.js.map": {
"imports": [], "imports": [],
"inputs": {}, "inputs": {},
"bytes": 268701 "bytes": 270803
}, },
"dist/human.node-nobundle.js": { "dist/human.node-nobundle.js": {
"imports": [], "imports": [],
@ -377,10 +377,10 @@
"bytesInOutput": 47 "bytesInOutput": 47
}, },
"src/human.js": { "src/human.js": {
"bytesInOutput": 11904 "bytesInOutput": 12748
} }
}, },
"bytes": 158304 "bytes": 159148
} }
} }
} }

View File

@ -61,10 +61,13 @@ class Human {
this.version = app.version; this.version = app.version;
this.defaults = defaults; this.defaults = defaults;
this.config = defaults; this.config = defaults;
this.fx = (tf.ENV.flags.IS_BROWSER && (typeof document !== 'undefined')) ? new fxImage.Canvas() : null; this.fx = null;
this.state = 'idle'; this.state = 'idle';
this.numTensors = 0; this.numTensors = 0;
this.analyzeMemoryLeaks = false; this.analyzeMemoryLeaks = false;
// internal temp canvases
this.inCanvas = null;
this.outCanvas = null;
// object that contains all initialized models // object that contains all initialized models
this.models = { this.models = {
facemesh: null, facemesh: null,
@ -160,56 +163,62 @@ class Human {
} }
tfImage(input) { tfImage(input) {
// let imageData;
let filtered;
const originalWidth = input.naturalWidth || input.videoWidth || input.width || (input.shape && (input.shape[1] > 0));
const originalHeight = input.naturalHeight || input.videoHeight || input.height || (input.shape && (input.shape[2] > 0));
let targetWidth = originalWidth;
let targetHeight = originalHeight;
if (this.fx && this.config.filter.enabled && !(input instanceof tf.Tensor)) {
if (this.config.filter.width > 0) targetWidth = this.config.filter.width;
else if (this.config.filter.height > 0) targetWidth = originalWidth * (this.config.filter.height / originalHeight);
if (this.config.filter.height > 0) targetHeight = this.config.filter.height;
else if (this.config.filter.width > 0) targetHeight = originalHeight * (this.config.filter.width / originalWidth);
const offscreenCanvas = (typeof OffscreenCanvas !== 'undefined') ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement('canvas');
if (offscreenCanvas.width !== targetWidth) offscreenCanvas.width = targetWidth;
if (offscreenCanvas.height !== targetHeight) offscreenCanvas.height = targetHeight;
const ctx = offscreenCanvas.getContext('2d');
if (input instanceof ImageData) ctx.putImageData(input, 0, 0);
else ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, offscreenCanvas.width, offscreenCanvas.height);
this.fx.reset();
this.fx.addFilter('brightness', this.config.filter.brightness); // must have at least one filter enabled
if (this.config.filter.contrast !== 0) this.fx.addFilter('contrast', this.config.filter.contrast);
if (this.config.filter.sharpness !== 0) this.fx.addFilter('sharpen', this.config.filter.sharpness);
if (this.config.filter.blur !== 0) this.fx.addFilter('blur', this.config.filter.blur);
if (this.config.filter.saturation !== 0) this.fx.addFilter('saturation', this.config.filter.saturation);
if (this.config.filter.hue !== 0) this.fx.addFilter('hue', this.config.filter.hue);
if (this.config.filter.negative) this.fx.addFilter('negative');
if (this.config.filter.sepia) this.fx.addFilter('sepia');
if (this.config.filter.vintage) this.fx.addFilter('brownie');
if (this.config.filter.sepia) this.fx.addFilter('sepia');
if (this.config.filter.kodachrome) this.fx.addFilter('kodachrome');
if (this.config.filter.technicolor) this.fx.addFilter('technicolor');
if (this.config.filter.polaroid) this.fx.addFilter('polaroid');
if (this.config.filter.pixelate !== 0) this.fx.addFilter('pixelate', this.config.filter.pixelate);
filtered = this.fx.apply(offscreenCanvas);
}
let tensor; let tensor;
if (input instanceof tf.Tensor) { if (input instanceof tf.Tensor) {
tensor = tf.clone(input); tensor = tf.clone(input);
} else { } else {
const canvas = filtered || input; const originalWidth = input.naturalWidth || input.videoWidth || input.width || (input.shape && (input.shape[1] > 0));
const originalHeight = input.naturalHeight || input.videoHeight || input.height || (input.shape && (input.shape[2] > 0));
let targetWidth = originalWidth;
let targetHeight = originalHeight;
if (this.config.filter.width > 0) targetWidth = this.config.filter.width;
else if (this.config.filter.height > 0) targetWidth = originalWidth * (this.config.filter.height / originalHeight);
if (this.config.filter.height > 0) targetHeight = this.config.filter.height;
else if (this.config.filter.width > 0) targetHeight = originalHeight * (this.config.filter.width / originalWidth);
if (!this.inCanvas || (this.inCanvas.width !== originalWidth) || (this.inCanvas.height !== originalHeight)) {
this.inCanvas = (typeof OffscreenCanvas !== 'undefined') ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement('canvas');
if (this.inCanvas.width !== targetWidth) this.inCanvas.width = targetWidth;
if (this.inCanvas.height !== targetHeight) this.inCanvas.height = targetHeight;
}
const ctx = this.inCanvas.getContext('2d');
if (input instanceof ImageData) ctx.putImageData(input, 0, 0);
else ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, this.inCanvas.width, this.inCanvas.height);
if (this.config.filter.enabled) {
if (!this.outCanvas || (this.inCanvas.width !== this.outCanvas.width) || (this.inCanvas.height !== this.outCanvas.height)) {
this.outCanvas = (typeof OffscreenCanvas !== 'undefined') ? new OffscreenCanvas(this.inCanvas.width, this.inCanvas.height) : document.createElement('canvas');
if (this.outCanvas.width !== this.inCanvas.width) this.outCanvas.width = this.inCanvas.width;
if (this.outCanvas.height !== this.inCanvas.height) this.outCanvas.height = this.inCanvas.height;
}
if (!this.fx) this.fx = (tf.ENV.flags.IS_BROWSER && (typeof document !== 'undefined')) ? new fxImage.Canvas({ canvas: this.outCanvas }) : null;
this.fx.reset();
this.fx.addFilter('brightness', this.config.filter.brightness); // must have at least one filter enabled
if (this.config.filter.contrast !== 0) this.fx.addFilter('contrast', this.config.filter.contrast);
if (this.config.filter.sharpness !== 0) this.fx.addFilter('sharpen', this.config.filter.sharpness);
if (this.config.filter.blur !== 0) this.fx.addFilter('blur', this.config.filter.blur);
if (this.config.filter.saturation !== 0) this.fx.addFilter('saturation', this.config.filter.saturation);
if (this.config.filter.hue !== 0) this.fx.addFilter('hue', this.config.filter.hue);
if (this.config.filter.negative) this.fx.addFilter('negative');
if (this.config.filter.sepia) this.fx.addFilter('sepia');
if (this.config.filter.vintage) this.fx.addFilter('brownie');
if (this.config.filter.sepia) this.fx.addFilter('sepia');
if (this.config.filter.kodachrome) this.fx.addFilter('kodachrome');
if (this.config.filter.technicolor) this.fx.addFilter('technicolor');
if (this.config.filter.polaroid) this.fx.addFilter('polaroid');
if (this.config.filter.pixelate !== 0) this.fx.addFilter('pixelate', this.config.filter.pixelate);
this.outCanvas = this.fx.apply(this.inCanvas);
}
if (!this.outCanvas) this.outCanvas = this.inCanvas;
let pixels; let pixels;
if ((this.config.backend === 'webgl') || (canvas instanceof ImageData)) { if ((this.config.backend === 'webgl') || (this.outCanvas instanceof ImageData)) {
// tf kernel-optimized method to get imagedata, also if input is imagedata, just use it // tf kernel-optimized method to get imagedata, also if input is imagedata, just use it
pixels = tf.browser.fromPixels(canvas); pixels = tf.browser.fromPixels(this.outCanvas);
} else { } else {
// cpu and wasm kernel does not implement efficient fromPixels method nor we can use canvas as-is, so we do a silly one more canvas // cpu and wasm kernel does not implement efficient fromPixels method nor we can use canvas as-is, so we do a silly one more canvas
const tempCanvas = (typeof OffscreenCanvas !== 'undefined') ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement('canvas'); const tempCanvas = (typeof OffscreenCanvas !== 'undefined') ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement('canvas');
tempCanvas.width = targetWidth; tempCanvas.width = targetWidth;
tempCanvas.height = targetHeight; tempCanvas.height = targetHeight;
const tempCtx = tempCanvas.getContext('2d'); const tempCtx = tempCanvas.getContext('2d');
tempCtx.drawImage(canvas, 0, 0); tempCtx.drawImage(this.outCanvas, 0, 0);
const data = tempCtx.getImageData(0, 0, targetWidth, targetHeight); const data = tempCtx.getImageData(0, 0, targetWidth, targetHeight);
pixels = tf.browser.fromPixels(data); pixels = tf.browser.fromPixels(data);
} }
@ -218,7 +227,7 @@ class Human {
pixels.dispose(); pixels.dispose();
casted.dispose(); casted.dispose();
} }
return { tensor, canvas: this.config.filter.return ? filtered : null }; return { tensor, canvas: this.config.filter.return ? this.outCanvas : null };
} }
async detect(input, userConfig = {}) { async detect(input, userConfig = {}) {