mirror of https://github.com/vladmandic/human
added warmup for nodejs
parent
6fdc50600f
commit
6387b5afbb
31
demo/node.js
31
demo/node.js
|
@ -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
|
@ -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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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": {
|
||||||
|
|
19
src/human.js
19
src/human.js
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue