2020-11-21 18:21:47 +01:00
|
|
|
const log = require('@vladmandic/pilogger');
|
2020-10-14 02:52:30 +02:00
|
|
|
const fs = require('fs');
|
|
|
|
const process = require('process');
|
2021-03-12 18:54:08 +01:00
|
|
|
|
|
|
|
// for NodeJS, `tfjs-node` or `tfjs-node-gpu` should be loaded before using Human
|
2020-11-21 18:21:47 +01:00
|
|
|
const tf = require('@tensorflow/tfjs-node'); // or const tf = require('@tensorflow/tfjs-node-gpu');
|
2021-03-12 18:54:08 +01:00
|
|
|
|
2020-11-21 18:21:47 +01:00
|
|
|
// 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;
|
2020-10-14 02:52:30 +02:00
|
|
|
|
2021-01-30 19:23:07 +01:00
|
|
|
let human = null;
|
|
|
|
|
2020-11-21 18:21:47 +01:00
|
|
|
const myConfig = {
|
2021-03-21 22:47:00 +01:00
|
|
|
// backend: 'tensorflow',
|
2020-10-16 16:12:12 +02:00
|
|
|
console: true,
|
2020-10-19 17:03:48 +02:00
|
|
|
videoOptimized: false,
|
2021-02-06 23:41:53 +01:00
|
|
|
async: false,
|
2020-10-14 02:52:30 +02:00
|
|
|
face: {
|
2021-03-04 16:33:08 +01:00
|
|
|
enabled: true,
|
2021-03-12 18:54:08 +01:00
|
|
|
detector: { modelPath: 'file://models/blazeface-back.json', enabled: true, rotation: false },
|
2021-03-10 00:32:35 +01:00
|
|
|
mesh: { modelPath: 'file://models/facemesh.json', enabled: true },
|
2021-03-04 16:33:08 +01:00
|
|
|
iris: { modelPath: 'file://models/iris.json', enabled: true },
|
2021-03-21 22:47:00 +01:00
|
|
|
description: { modelPath: 'file://models/faceres.json', enabled: true },
|
2021-03-04 16:33:08 +01:00
|
|
|
emotion: { modelPath: 'file://models/emotion.json', enabled: true },
|
2021-03-21 22:47:00 +01:00
|
|
|
age: { modelPath: 'file://models/age.json', enabled: false },
|
|
|
|
gender: { modelPath: 'file://models/gender.json', enabled: false },
|
|
|
|
embedding: { modelPath: 'file://models/mobileface.json', enabled: false },
|
2020-10-14 02:52:30 +02:00
|
|
|
},
|
2021-03-12 18:54:08 +01:00
|
|
|
// body: { modelPath: 'file://models/blazepose.json', enabled: true },
|
|
|
|
body: { modelPath: 'file://models/posenet.json', enabled: true },
|
2020-10-14 02:52:30 +02:00
|
|
|
hand: {
|
2021-03-04 16:33:08 +01:00
|
|
|
enabled: true,
|
2020-11-03 15:34:36 +01:00
|
|
|
detector: { modelPath: 'file://models/handdetect.json' },
|
|
|
|
skeleton: { modelPath: 'file://models/handskeleton.json' },
|
2020-10-14 02:52:30 +02:00
|
|
|
},
|
2021-03-17 23:36:12 +01:00
|
|
|
object: { modelPath: 'file://models/nanodet.json', enabled: true },
|
2020-10-14 02:52:30 +02:00
|
|
|
};
|
|
|
|
|
2021-01-30 19:23:07 +01:00
|
|
|
async function init() {
|
2020-11-21 18:21:47 +01:00
|
|
|
// wait until tf is ready
|
2020-10-14 02:52:30 +02:00
|
|
|
await tf.ready();
|
2020-11-21 18:21:47 +01:00
|
|
|
// create instance of human
|
2021-01-30 19:23:07 +01:00
|
|
|
human = new Human(myConfig);
|
2020-11-21 18:21:47 +01:00
|
|
|
// pre-load models
|
2021-03-04 16:33:08 +01:00
|
|
|
log.info('Human:', human.version);
|
|
|
|
log.info('Active Configuration', human.config);
|
2020-11-21 18:21:47 +01:00
|
|
|
await human.load();
|
2021-03-04 16:33:08 +01:00
|
|
|
const loaded = Object.keys(human.models).filter((a) => human.models[a]);
|
|
|
|
log.info('Loaded:', loaded);
|
|
|
|
log.info('Memory state:', human.tf.engine().memory());
|
2021-01-30 19:23:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
async function detect(input) {
|
2020-11-21 18:21:47 +01:00
|
|
|
// read input image file and create tensor to be used for processing
|
2020-10-14 02:52:30 +02:00
|
|
|
const buffer = fs.readFileSync(input);
|
2020-11-21 18:21:47 +01:00
|
|
|
const decoded = human.tf.node.decodeImage(buffer);
|
2020-10-19 17:03:48 +02:00
|
|
|
const casted = decoded.toFloat();
|
|
|
|
const image = casted.expandDims(0);
|
|
|
|
decoded.dispose();
|
|
|
|
casted.dispose();
|
2020-11-21 18:21:47 +01:00
|
|
|
// image shape contains image dimensions and depth
|
|
|
|
log.state('Processing:', image.shape);
|
|
|
|
// run actual detection
|
|
|
|
const result = await human.detect(image, myConfig);
|
2021-03-10 00:32:35 +01:00
|
|
|
// no need to print results as they are printed to console during detection from within the library due to human.config.debug set
|
2020-11-21 18:21:47 +01:00
|
|
|
// dispose image tensor as we no longer need it
|
2020-10-14 17:43:33 +02:00
|
|
|
image.dispose();
|
2020-11-21 18:21:47 +01:00
|
|
|
// print data to console
|
2021-03-10 00:32:35 +01:00
|
|
|
return result;
|
2020-10-14 02:52:30 +02:00
|
|
|
}
|
|
|
|
|
2021-01-30 19:23:07 +01:00
|
|
|
async function test() {
|
2021-03-06 16:38:04 +01:00
|
|
|
// test with embedded full body image
|
|
|
|
let result;
|
|
|
|
|
2021-02-06 23:41:53 +01:00
|
|
|
log.state('Processing embedded warmup image: face');
|
|
|
|
myConfig.warmup = 'face';
|
2021-03-06 16:38:04 +01:00
|
|
|
result = await human.warmup(myConfig);
|
2021-02-08 17:39:09 +01:00
|
|
|
|
2021-02-06 23:41:53 +01:00
|
|
|
log.state('Processing embedded warmup image: full');
|
2021-01-30 19:23:07 +01:00
|
|
|
myConfig.warmup = 'full';
|
2021-03-06 16:38:04 +01:00
|
|
|
result = await human.warmup(myConfig);
|
2021-03-10 00:32:35 +01:00
|
|
|
// no need to print results as they are printed to console during detection from within the library due to human.config.debug set
|
|
|
|
return result;
|
2021-01-30 19:23:07 +01:00
|
|
|
}
|
|
|
|
|
2020-10-14 02:52:30 +02:00
|
|
|
async function main() {
|
2021-03-06 16:38:04 +01:00
|
|
|
log.header();
|
2021-03-04 16:33:08 +01:00
|
|
|
log.info('Current folder:', process.env.PWD);
|
2021-01-30 19:23:07 +01:00
|
|
|
await init();
|
|
|
|
if (process.argv.length !== 3) {
|
|
|
|
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]);
|
|
|
|
}
|
2020-10-14 02:52:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
main();
|