fix imagefx and add dev builds

pull/70/head
Vladimir Mandic 2021-02-21 07:20:58 -05:00
parent 1b2aba1b51
commit 9f90fcab7f
28 changed files with 849 additions and 835 deletions

Binary file not shown.

Binary file not shown.

View File

@ -12,10 +12,10 @@ const userConfig = {}; // add any user configuration overrides
/*
const userConfig = {
// backend: 'humangl',
backend: 'wasm',
async: false,
videoOptimized: false,
face: { enabled: true, detector: { modelPath: '../models/faceboxes.json' }, iris: { enabled: false }, mesh: { enabled: false }, age: { enabled: false }, gender: { enabled: false }, emotion: { enabled: true } },
face: { enabled: true, iris: { enabled: false }, mesh: { enabled: true }, age: { enabled: true }, gender: { enabled: true }, emotion: { enabled: true } },
body: { enabled: false },
hand: { enabled: false },
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
{
"inputs": {
"dist/human.esm.js": {
"bytes": 1347469,
"bytes": 1347222,
"imports": []
},
"demo/draw.js": {
@ -17,7 +17,7 @@
"imports": []
},
"demo/browser.js": {
"bytes": 26752,
"bytes": 26690,
"imports": [
{
"path": "dist/human.esm.js",
@ -43,14 +43,14 @@
"imports": [],
"exports": [],
"inputs": {},
"bytes": 2022314
"bytes": 2021862
},
"dist/demo-browser-index.js": {
"imports": [],
"exports": [],
"inputs": {
"dist/human.esm.js": {
"bytesInOutput": 1339993
"bytesInOutput": 1339746
},
"demo/draw.js": {
"bytesInOutput": 6204
@ -65,7 +65,7 @@
"bytesInOutput": 17340
}
},
"bytes": 1388377
"bytes": 1388130
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

492
dist/human.esm.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

16
dist/human.esm.json vendored
View File

@ -388,11 +388,11 @@
"imports": []
},
"src/imagefx.js": {
"bytes": 19372,
"bytes": 19267,
"imports": []
},
"src/image.ts": {
"bytes": 5902,
"bytes": 5869,
"imports": [
{
"path": "src/log.ts",
@ -421,7 +421,7 @@
"imports": []
},
"src/human.ts": {
"bytes": 19703,
"bytes": 19720,
"imports": [
{
"path": "src/log.ts",
@ -499,7 +499,7 @@
"imports": [],
"exports": [],
"inputs": {},
"bytes": 1925031
"bytes": 1924685
},
"dist/human.esm.js": {
"imports": [],
@ -517,7 +517,7 @@
"bytesInOutput": 252
},
"dist/tfjs.esm.js": {
"bytesInOutput": 1064608
"bytesInOutput": 1064610
},
"src/tfjs/backend.ts": {
"bytesInOutput": 1205
@ -538,7 +538,7 @@
"bytesInOutput": 5040
},
"src/human.ts": {
"bytesInOutput": 10617
"bytesInOutput": 10441
},
"src/faceboxes/faceboxes.ts": {
"bytesInOutput": 1549
@ -610,7 +610,7 @@
"bytesInOutput": 10975
},
"src/image.ts": {
"bytesInOutput": 2452
"bytesInOutput": 2379
},
"config.js": {
"bytesInOutput": 1426
@ -622,7 +622,7 @@
"bytesInOutput": 2572
}
},
"bytes": 1347469
"bytes": 1347222
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

18
dist/human.node.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

16
dist/human.node.json vendored
View File

@ -388,11 +388,11 @@
"imports": []
},
"src/imagefx.js": {
"bytes": 19372,
"bytes": 19267,
"imports": []
},
"src/image.ts": {
"bytes": 5902,
"bytes": 5869,
"imports": [
{
"path": "src/log.ts",
@ -421,7 +421,7 @@
"imports": []
},
"src/human.ts": {
"bytes": 19703,
"bytes": 19720,
"imports": [
{
"path": "src/log.ts",
@ -499,7 +499,7 @@
"imports": [],
"exports": [],
"inputs": {},
"bytes": 705616
"bytes": 705270
},
"dist/human.node-gpu.js": {
"imports": [],
@ -515,7 +515,7 @@
"bytesInOutput": 1677
},
"src/human.ts": {
"bytesInOutput": 10625
"bytesInOutput": 10449
},
"src/log.ts": {
"bytesInOutput": 251
@ -548,7 +548,7 @@
"bytesInOutput": 822
},
"src/gender/gender.ts": {
"bytesInOutput": 1302
"bytesInOutput": 1310
},
"src/emotion/emotion.ts": {
"bytesInOutput": 1247
@ -605,7 +605,7 @@
"bytesInOutput": 2391
},
"src/image.ts": {
"bytesInOutput": 2458
"bytesInOutput": 2362
},
"src/imagefx.js": {
"bytesInOutput": 10973
@ -620,7 +620,7 @@
"bytesInOutput": 2569
}
},
"bytes": 277039
"bytes": 276775
}
}
}

492
dist/human.ts vendored

File diff suppressed because one or more lines are too long

4
dist/human.ts.map vendored

File diff suppressed because one or more lines are too long

16
dist/human.tson vendored
View File

@ -388,11 +388,11 @@
"imports": []
},
"src/imagefx.js": {
"bytes": 19372,
"bytes": 19267,
"imports": []
},
"src/image.ts": {
"bytes": 5902,
"bytes": 5869,
"imports": [
{
"path": "src/log.ts",
@ -421,7 +421,7 @@
"imports": []
},
"src/human.ts": {
"bytes": 19703,
"bytes": 19720,
"imports": [
{
"path": "src/log.ts",
@ -499,7 +499,7 @@
"imports": [],
"exports": [],
"inputs": {},
"bytes": 1925042
"bytes": 1924696
},
"dist/human.ts": {
"imports": [],
@ -512,13 +512,13 @@
"bytesInOutput": 1690
},
"src/human.ts": {
"bytesInOutput": 10653
"bytesInOutput": 10477
},
"src/log.ts": {
"bytesInOutput": 252
},
"dist/tfjs.esm.js": {
"bytesInOutput": 1064608
"bytesInOutput": 1064610
},
"src/tfjs/backend.ts": {
"bytesInOutput": 1205
@ -608,7 +608,7 @@
"bytesInOutput": 10975
},
"src/image.ts": {
"bytesInOutput": 2452
"bytesInOutput": 2379
},
"config.js": {
"bytesInOutput": 1426
@ -620,7 +620,7 @@
"bytesInOutput": 2572
}
},
"bytes": 1347511
"bytes": 1347264
}
}
}

42
package-lock.json generated
View File

@ -366,9 +366,9 @@
"dev": true
},
"@types/node": {
"version": "14.14.30",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.30.tgz",
"integrity": "sha512-gUWhy8s45fQp4PqqKecsnOkdW0kt1IaKjgOIR3HPokkzTmQj9ji2wWFID5THu1MKrtO+d4s2lVrlEhXUsPXSvg==",
"version": "14.14.31",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz",
"integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==",
"dev": true
},
"@types/node-fetch": {
@ -665,15 +665,15 @@
}
},
"array-includes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.2.tgz",
"integrity": "sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw==",
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz",
"integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==",
"dev": true,
"requires": {
"call-bind": "^1.0.0",
"call-bind": "^1.0.2",
"define-properties": "^1.1.3",
"es-abstract": "^1.18.0-next.1",
"get-intrinsic": "^1.0.1",
"es-abstract": "^1.18.0-next.2",
"get-intrinsic": "^1.1.1",
"is-string": "^1.0.5"
}
},
@ -1026,9 +1026,9 @@
}
},
"esbuild": {
"version": "0.8.49",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.8.49.tgz",
"integrity": "sha512-itiFVYv5UZz4NooO7/Y0bRGVDGz/M/cxKbl6zyNI5pnKaz1mZjvZXAFhhDVz6rGCmcdTKj5oag6rh8DaaSSmfQ==",
"version": "0.8.50",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.8.50.tgz",
"integrity": "sha512-oidFLXssA7IccYzkqLVZSqNJDwDq8Mh/vqvrW+3fPWM7iUiC5O2bCllhnO8+K9LlyL/2Z6n+WwRJAz9fqSIVRg==",
"dev": true
},
"escalade": {
@ -1433,9 +1433,9 @@
}
},
"file-entry-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz",
"integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==",
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
"dev": true,
"requires": {
"flat-cache": "^3.0.4"
@ -1942,9 +1942,9 @@
}
},
"lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"lru-cache": {
@ -2837,9 +2837,9 @@
"dev": true
},
"typescript": {
"version": "4.3.0-dev.20210219",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.0-dev.20210219.tgz",
"integrity": "sha512-9ttM1StIx+z2L4NnLGaYkOKIJWWFwzL4KuvhQXfulqjl4PnNjAsrl5QKAbI07oEvS2wn4rUdGHYQnCxh3/biWQ==",
"version": "4.3.0-dev.20210221",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.0-dev.20210221.tgz",
"integrity": "sha512-XmZXakfRX7wuViUlU1k6E21gp+aQ+eIOgahlhXRaakuv4mkK3fEs+hA93/cucOlRwpDU9R/UgN5UuU4CDr9wag==",
"dev": true
},
"uri-js": {

View File

@ -33,13 +33,13 @@
"@tensorflow/tfjs-layers": "^3.1.0",
"@tensorflow/tfjs-node": "^3.1.0",
"@tensorflow/tfjs-node-gpu": "^3.1.0",
"@types/node": "^14.14.30",
"@types/node": "^14.14.31",
"@typescript-eslint/eslint-plugin": "^4.15.1",
"@typescript-eslint/parser": "^4.15.1",
"@vladmandic/pilogger": "^0.2.14",
"chokidar": "^3.5.1",
"dayjs": "^1.10.4",
"esbuild": "^0.8.49",
"esbuild": "^0.8.50",
"eslint": "^7.20.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.22.1",
@ -50,7 +50,7 @@
"seedrandom": "^3.0.5",
"simple-git": "^2.35.1",
"tslib": "^2.1.0",
"typescript": "^4.3.0-dev.20210219"
"typescript": "^4.3.0-dev.20210221"
},
"scripts": {
"start": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation src/node.js",

View File

@ -40,16 +40,27 @@ const tsconfig = {
};
// common configuration
const common = {
banner,
minifyWhitespace: true,
minifyIdentifiers: true,
minifySyntax: true,
bundle: true,
sourcemap: true,
logLevel: 'error',
target: 'es2018',
tsconfig: 'server/tfjs-tsconfig.json',
const config = {
common: {
banner,
tsconfig: 'server/tfjs-tsconfig.json',
bundle: true,
logLevel: 'error',
},
debug: {
minifyWhitespace: false,
minifyIdentifiers: false,
minifySyntax: false,
sourcemap: true,
target: 'es2018',
},
production: {
minifyWhitespace: true,
minifyIdentifiers: true,
minifySyntax: true,
sourcemap: true,
target: 'es2018',
},
};
const targets = {
@ -194,14 +205,14 @@ function compile(fileNames, options) {
}
// rebuild on file change
async function build(f, msg) {
async function build(f, msg, dev = false) {
if (busy) {
log.state('Build: busy...');
setTimeout(() => build(f, msg), 500);
return;
}
busy = true;
log.info('Build: file', msg, f, 'target:', common.target);
log.info('Build: file', msg, f, 'type:', dev ? 'debug' : 'production', 'config:', dev ? config.debug : config.production);
if (!es) es = await esbuild.startService();
// common build options
try {
@ -210,7 +221,8 @@ async function build(f, msg) {
for (const [targetName, targetOptions] of Object.entries(targetGroup)) {
// if triggered from watch mode, rebuild only browser bundle
// if ((require.main !== module) && (targetGroupName !== 'browserBundle')) continue;
await es.build({ ...common, ...targetOptions });
if (dev) await es.build({ ...config.common, ...config.debug, ...targetOptions });
else await es.build({ ...config.common, ...config.production, ...targetOptions });
const stats = await getStats(targetOptions.metafile);
log.state(`Build for: ${targetGroupName} type: ${targetName}:`, stats);
}

View File

@ -57,7 +57,7 @@ const mime = {
let last = Date.now();
async function buildAll(evt, msg) {
const now = Date.now();
if ((now - last) > options.minElapsed) build.build(evt, msg);
if ((now - last) > options.minElapsed) build.build(evt, msg, true);
else log.state('Build: merge event file', msg, evt);
last = now;
}
@ -153,7 +153,7 @@ async function main() {
server2.on('error', (err) => log.error('HTTP2 server:', err.message || err));
server2.listen(options.httpsPort);
}
await build.build('all', 'startup');
await build.build('all', 'startup', true);
}
main();

View File

@ -346,13 +346,15 @@ class Human {
return faceRes;
}
async image(input, userConfig = {}) {
/*
async processImage(input, userConfig = {}) {
this.state = 'image';
this.config = mergeDeep(this.config, userConfig);
const process = image.process(input, this.config);
process?.tensor?.dispose();
return process?.canvas;
}
*/
// main detect function
async detect(input, userConfig = {}) {

View File

@ -7,6 +7,8 @@ import * as fxImage from './imagefx';
// internal temp canvases
let inCanvas = null;
let outCanvas = null;
// instance of fximage
let fx = null;
// process input image and return tensor
// input can be tensor, imagedata, htmlimageelement, htmlvideoelement
@ -37,29 +39,30 @@ export function process(input, config) {
if (input instanceof ImageData) ctx.putImageData(input, 0, 0);
else ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, inCanvas.width, inCanvas.height);
if (config.filter.enabled) {
if (!this.fx || !outCanvas || (inCanvas.width !== outCanvas.width) || (inCanvas.height !== outCanvas.height)) {
if (!fx || !outCanvas || (inCanvas.width !== outCanvas.width) || (inCanvas.height !== outCanvas.height)) {
outCanvas = (typeof OffscreenCanvas !== 'undefined') ? new OffscreenCanvas(inCanvas.width, inCanvas.height) : document.createElement('canvas');
if (outCanvas.width !== inCanvas.width) outCanvas.width = inCanvas.width;
if (outCanvas.height !== inCanvas.height) outCanvas.height = inCanvas.height;
this.fx = tf.ENV.flags.IS_BROWSER ? new fxImage.GLImageFilter({ canvas: outCanvas }) : null; // && (typeof document !== 'undefined')
log('created FX filter');
fx = tf.ENV.flags.IS_BROWSER ? new fxImage.GLImageFilter({ canvas: outCanvas }) : null; // && (typeof document !== 'undefined')
}
if (!this.fx) return inCanvas;
this.fx.reset();
this.fx.addFilter('brightness', config.filter.brightness); // must have at least one filter enabled
if (config.filter.contrast !== 0) this.fx.addFilter('contrast', config.filter.contrast);
if (config.filter.sharpness !== 0) this.fx.addFilter('sharpen', config.filter.sharpness);
if (config.filter.blur !== 0) this.fx.addFilter('blur', config.filter.blur);
if (config.filter.saturation !== 0) this.fx.addFilter('saturation', config.filter.saturation);
if (config.filter.hue !== 0) this.fx.addFilter('hue', config.filter.hue);
if (config.filter.negative) this.fx.addFilter('negative');
if (config.filter.sepia) this.fx.addFilter('sepia');
if (config.filter.vintage) this.fx.addFilter('brownie');
if (config.filter.sepia) this.fx.addFilter('sepia');
if (config.filter.kodachrome) this.fx.addFilter('kodachrome');
if (config.filter.technicolor) this.fx.addFilter('technicolor');
if (config.filter.polaroid) this.fx.addFilter('polaroid');
if (config.filter.pixelate !== 0) this.fx.addFilter('pixelate', config.filter.pixelate);
this.fx.apply(inCanvas);
if (!fx) return inCanvas;
fx.reset();
fx.addFilter('brightness', config.filter.brightness); // must have at least one filter enabled
if (config.filter.contrast !== 0) fx.addFilter('contrast', config.filter.contrast);
if (config.filter.sharpness !== 0) fx.addFilter('sharpen', config.filter.sharpness);
if (config.filter.blur !== 0) fx.addFilter('blur', config.filter.blur);
if (config.filter.saturation !== 0) fx.addFilter('saturation', config.filter.saturation);
if (config.filter.hue !== 0) fx.addFilter('hue', config.filter.hue);
if (config.filter.negative) fx.addFilter('negative');
if (config.filter.sepia) fx.addFilter('sepia');
if (config.filter.vintage) fx.addFilter('brownie');
if (config.filter.sepia) fx.addFilter('sepia');
if (config.filter.kodachrome) fx.addFilter('kodachrome');
if (config.filter.technicolor) fx.addFilter('technicolor');
if (config.filter.polaroid) fx.addFilter('polaroid');
if (config.filter.pixelate !== 0) fx.addFilter('pixelate', config.filter.pixelate);
fx.apply(inCanvas);
// read pixel data
/*
const gl = outCanvas.getContext('webgl');
@ -83,7 +86,7 @@ export function process(input, config) {
*/
} else {
outCanvas = inCanvas;
if (this.fx) this.fx = null;
if (fx) fx = null;
}
let pixels;
if (outCanvas.data) {

View File

@ -97,8 +97,6 @@ export function GLImageFilter(params) {
// eslint-disable-next-line no-unused-expressions
(_vertexBuffer = gl.createBuffer(), gl.bindBuffer(gl.ARRAY_BUFFER, _vertexBuffer));
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// Note sure if this is a good idea; at least it makes texture loading
// in Ejecta instant.
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
}
gl.viewport(0, 0, _width, _height);

1
types/human.d.ts vendored
View File

@ -38,7 +38,6 @@ declare class Human {
embedding: any;
iris: number;
}[]>;
image(input: any, userConfig?: {}): Promise<null | undefined>;
detect(input: any, userConfig?: {}): Promise<unknown>;
warmupBitmap(): Promise<any>;
warmupCanvas(): Promise<unknown>;