added warmup for nodejs

pull/70/head
Vladimir Mandic 2021-01-30 13:23:07 -05:00
parent 6fdc50600f
commit 6387b5afbb
19 changed files with 757 additions and 723 deletions

View File

@ -6,6 +6,8 @@ const tf = require('@tensorflow/tfjs-node'); // or const tf = require('@tensorfl
// load specific version of Human library that matches TensorFlow mode // load specific version of Human library that matches TensorFlow mode
const Human = require('../dist/human.node.js').default; // or const Human = require('../dist/human.node-gpu.js').default; const Human = require('../dist/human.node.js').default; // or const Human = require('../dist/human.node-gpu.js').default;
let human = null;
const myConfig = { const myConfig = {
backend: 'tensorflow', backend: 'tensorflow',
console: true, console: true,
@ -25,13 +27,16 @@ const myConfig = {
}, },
}; };
async function detect(input) { async function init() {
// wait until tf is ready // wait until tf is ready
await tf.ready(); await tf.ready();
// create instance of human // create instance of human
const human = new Human(myConfig); human = new Human(myConfig);
// pre-load models // pre-load models
await human.load(); await human.load();
}
async function detect(input) {
// read input image file and create tensor to be used for processing // read input image file and create tensor to be used for processing
const buffer = fs.readFileSync(input); const buffer = fs.readFileSync(input);
const decoded = human.tf.node.decodeImage(buffer); const decoded = human.tf.node.decodeImage(buffer);
@ -40,6 +45,7 @@ async function detect(input) {
decoded.dispose(); decoded.dispose();
casted.dispose(); casted.dispose();
// image shape contains image dimensions and depth // image shape contains image dimensions and depth
log.warn('Face model is disabled in NodeJS due to missing required TFJS functions');
log.state('Processing:', image.shape); log.state('Processing:', image.shape);
// must disable face model when runing in tfjs-node as it's missing required ops // must disable face model when runing in tfjs-node as it's missing required ops
// see <https://github.com/tensorflow/tfjs/issues/4066> // see <https://github.com/tensorflow/tfjs/issues/4066>
@ -52,11 +58,26 @@ async function detect(input) {
log.data(result); log.data(result);
} }
async function test() {
log.state('Processing embedded warmup image');
log.warn('Face model is disabled in NodeJS due to missing required TFJS functions');
myConfig.face.enabled = false;
myConfig.warmup = 'full';
const result = await human.warmup(myConfig);
log.data(result);
}
async function main() { async function main() {
log.info('NodeJS:', process.version); log.info('NodeJS:', process.version);
if (process.argv.length !== 3) log.error('Parameters: <input image>'); await init();
else if (!fs.existsSync(process.argv[2])) log.error(`File not found: ${process.argv[2]}`); if (process.argv.length !== 3) {
else detect(process.argv[2]); log.warn('Parameters: <input image> missing');
await test();
} else if (!fs.existsSync(process.argv[2])) {
log.error(`File not found: ${process.argv[2]}`);
} else {
await detect(process.argv[2]);
}
} }
main(); main();

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": { "inputs": {
"dist/human.esm.js": { "dist/human.esm.js": {
"bytes": 1347090, "bytes": 1347321,
"imports": [] "imports": []
}, },
"demo/draw.js": { "demo/draw.js": {
@ -42,14 +42,14 @@
"dist/demo-browser-index.js.map": { "dist/demo-browser-index.js.map": {
"imports": [], "imports": [],
"inputs": {}, "inputs": {},
"bytes": 2022516 "bytes": 2023220
}, },
"dist/demo-browser-index.js": { "dist/demo-browser-index.js": {
"imports": [], "imports": [],
"exports": [], "exports": [],
"inputs": { "inputs": {
"dist/human.esm.js": { "dist/human.esm.js": {
"bytesInOutput": 1338559 "bytesInOutput": 1338790
}, },
"demo/draw.js": { "demo/draw.js": {
"bytesInOutput": 6204 "bytesInOutput": 6204
@ -64,7 +64,7 @@
"bytesInOutput": 16815 "bytesInOutput": 16815
} }
}, },
"bytes": 1386418 "bytes": 1386649
} }
} }
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

442
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

12
dist/human.esm.json vendored
View File

@ -429,7 +429,7 @@
"imports": [] "imports": []
}, },
"src/human.js": { "src/human.js": {
"bytes": 18229, "bytes": 18719,
"imports": [ "imports": [
{ {
"path": "src/log.js", "path": "src/log.js",
@ -502,7 +502,7 @@
"dist/human.esm.js.map": { "dist/human.esm.js.map": {
"imports": [], "imports": [],
"inputs": {}, "inputs": {},
"bytes": 1926654 "bytes": 1927417
}, },
"dist/human.esm.js": { "dist/human.esm.js": {
"imports": [], "imports": [],
@ -601,13 +601,13 @@
"bytesInOutput": 252 "bytesInOutput": 252
}, },
"dist/tfjs.esm.js": { "dist/tfjs.esm.js": {
"bytesInOutput": 1062882 "bytesInOutput": 1062880
}, },
"src/tfjs/backend.js": { "src/tfjs/backend.js": {
"bytesInOutput": 1205 "bytesInOutput": 1205
}, },
"src/human.js": { "src/human.js": {
"bytesInOutput": 9983 "bytesInOutput": 10250
}, },
"src/handpose/box.js": { "src/handpose/box.js": {
"bytesInOutput": 938 "bytesInOutput": 938
@ -616,7 +616,7 @@
"bytesInOutput": 816 "bytesInOutput": 816
}, },
"config.js": { "config.js": {
"bytesInOutput": 1460 "bytesInOutput": 1426
}, },
"src/sample.js": { "src/sample.js": {
"bytesInOutput": 55295 "bytesInOutput": 55295
@ -625,7 +625,7 @@
"bytesInOutput": 16 "bytesInOutput": 16
} }
}, },
"bytes": 1347090 "bytes": 1347321
} }
} }
} }

432
dist/human.js vendored

File diff suppressed because one or more lines are too long

4
dist/human.js.map vendored

File diff suppressed because one or more lines are too long

12
dist/human.json vendored
View File

@ -429,7 +429,7 @@
"imports": [] "imports": []
}, },
"src/human.js": { "src/human.js": {
"bytes": 18229, "bytes": 18719,
"imports": [ "imports": [
{ {
"path": "src/log.js", "path": "src/log.js",
@ -502,7 +502,7 @@
"dist/human.js.map": { "dist/human.js.map": {
"imports": [], "imports": [],
"inputs": {}, "inputs": {},
"bytes": 1926671 "bytes": 1927434
}, },
"dist/human.js": { "dist/human.js": {
"imports": [], "imports": [],
@ -596,13 +596,13 @@
"bytesInOutput": 2480 "bytesInOutput": 2480
}, },
"src/human.js": { "src/human.js": {
"bytesInOutput": 10019 "bytesInOutput": 10286
}, },
"src/log.js": { "src/log.js": {
"bytesInOutput": 252 "bytesInOutput": 252
}, },
"dist/tfjs.esm.js": { "dist/tfjs.esm.js": {
"bytesInOutput": 1062882 "bytesInOutput": 1062880
}, },
"src/tfjs/backend.js": { "src/tfjs/backend.js": {
"bytesInOutput": 1205 "bytesInOutput": 1205
@ -614,7 +614,7 @@
"bytesInOutput": 816 "bytesInOutput": 816
}, },
"config.js": { "config.js": {
"bytesInOutput": 1460 "bytesInOutput": 1426
}, },
"src/sample.js": { "src/sample.js": {
"bytesInOutput": 55295 "bytesInOutput": 55295
@ -623,7 +623,7 @@
"bytesInOutput": 16 "bytesInOutput": 16
} }
}, },
"bytes": 1347132 "bytes": 1347363
} }
} }
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

10
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

10
dist/human.node.json vendored
View File

@ -429,7 +429,7 @@
"imports": [] "imports": []
}, },
"src/human.js": { "src/human.js": {
"bytes": 18229, "bytes": 18719,
"imports": [ "imports": [
{ {
"path": "src/log.js", "path": "src/log.js",
@ -502,7 +502,7 @@
"dist/human.node-gpu.js.map": { "dist/human.node-gpu.js.map": {
"imports": [], "imports": [],
"inputs": {}, "inputs": {},
"bytes": 709400 "bytes": 710163
}, },
"dist/human.node-gpu.js": { "dist/human.node-gpu.js": {
"imports": [], "imports": [],
@ -599,7 +599,7 @@
"bytesInOutput": 2478 "bytesInOutput": 2478
}, },
"src/human.js": { "src/human.js": {
"bytesInOutput": 10118 "bytesInOutput": 10397
}, },
"src/log.js": { "src/log.js": {
"bytesInOutput": 251 "bytesInOutput": 251
@ -614,7 +614,7 @@
"bytesInOutput": 812 "bytesInOutput": 812
}, },
"config.js": { "config.js": {
"bytesInOutput": 1460 "bytesInOutput": 1426
}, },
"src/sample.js": { "src/sample.js": {
"bytesInOutput": 55295 "bytesInOutput": 55295
@ -623,7 +623,7 @@
"bytesInOutput": 16 "bytesInOutput": 16
} }
}, },
"bytes": 278297 "bytes": 278542
} }
} }
} }

10
dist/tfjs.esm.json vendored
View File

@ -1,23 +1,23 @@
{ {
"inputs": { "inputs": {
"node_modules/@tensorflow/tfjs/package.json": { "node_modules/@tensorflow/tfjs/package.json": {
"bytes": 5108, "bytes": 5093,
"imports": [] "imports": []
}, },
"node_modules/@tensorflow/tfjs-core/package.json": { "node_modules/@tensorflow/tfjs-core/package.json": {
"bytes": 5357, "bytes": 5342,
"imports": [] "imports": []
}, },
"node_modules/@tensorflow/tfjs-data/package.json": { "node_modules/@tensorflow/tfjs-data/package.json": {
"bytes": 4186, "bytes": 4171,
"imports": [] "imports": []
}, },
"node_modules/@tensorflow/tfjs-layers/package.json": { "node_modules/@tensorflow/tfjs-layers/package.json": {
"bytes": 3934, "bytes": 3919,
"imports": [] "imports": []
}, },
"node_modules/@tensorflow/tfjs-converter/package.json": { "node_modules/@tensorflow/tfjs-converter/package.json": {
"bytes": 4761, "bytes": 4746,
"imports": [] "imports": []
}, },
"node_modules/@tensorflow/tfjs-core/dist/backends/backend.js": { "node_modules/@tensorflow/tfjs-core/dist/backends/backend.js": {

View File

@ -444,7 +444,7 @@ class Human {
} }
if (blob) { if (blob) {
const bitmap = await createImageBitmap(blob); const bitmap = await createImageBitmap(blob);
res = await this.detect(bitmap, config); res = await this.detect(bitmap, this.config);
bitmap.close(); bitmap.close();
} }
return res; return res;
@ -474,13 +474,25 @@ class Human {
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0); ctx.drawImage(img, 0, 0);
const data = ctx.getImageData(0, 0, size, size); const data = ctx.getImageData(0, 0, size, size);
this.detect(data, config).then((res) => resolve(res)); this.detect(data, this.config).then((res) => resolve(res));
}; };
if (src) img.src = src; if (src) img.src = src;
else resolve(null); else resolve(null);
}); });
} }
async warmupNode() {
const atob = (str) => Buffer.from(str, 'base64');
const img = this.config.warmup === 'face' ? atob(sample.face) : atob(sample.body);
const data = tf.node.decodeJpeg(img);
const expanded = data.expandDims(0);
tf.dispose(data);
// log('Input:', expanded);
const res = await this.detect(expanded, this.config);
tf.dispose(expanded);
return res;
}
async warmup(userConfig) { async warmup(userConfig) {
const t0 = now(); const t0 = now();
if (userConfig) this.config = mergeDeep(this.config, userConfig); if (userConfig) this.config = mergeDeep(this.config, userConfig);
@ -488,7 +500,8 @@ class Human {
this.config.videoOptimized = false; this.config.videoOptimized = false;
let res; let res;
if (typeof createImageBitmap === 'function') res = await this.warmupBitmap(); if (typeof createImageBitmap === 'function') res = await this.warmupBitmap();
else res = await this.warmupCanvas(); else if (typeof Image !== 'undefined') res = await this.warmupCanvas();
else res = await this.warmupNode();
this.config.videoOptimized = video; this.config.videoOptimized = video;
const t1 = now(); const t1 = now();
log('Warmup', this.config.warmup, Math.round(t1 - t0), 'ms', res); log('Warmup', this.config.warmup, Math.round(t1 - t0), 'ms', res);