add full nodejs test coverage

pull/134/head
Vladimir Mandic 2021-04-15 09:43:55 -04:00
parent 900194b7f8
commit 6137611924
16 changed files with 340 additions and 54 deletions

View File

@ -1,6 +1,6 @@
# @vladmandic/human # @vladmandic/human
Version: **1.5.1** Version: **1.5.2**
Description: **Human: AI-powered 3D Face Detection & Rotation Tracking, Face Description & Recognition, Body Pose Tracking, 3D Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction, Gesture Recognition** Description: **Human: AI-powered 3D Face Detection & Rotation Tracking, Face Description & Recognition, Body Pose Tracking, 3D Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction, Gesture Recognition**
Author: **Vladimir Mandic <mandic00@live.com>** Author: **Vladimir Mandic <mandic00@live.com>**
@ -9,8 +9,9 @@ Repository: **<git+https://github.com/vladmandic/human.git>**
## Changelog ## Changelog
### **HEAD -> main** 2021/04/13 mandic00@live.com ### **1.5.2** 2021/04/14 mandic00@live.com
- experimental node-wasm support
### **1.5.1** 2021/04/13 mandic00@live.com ### **1.5.1** 2021/04/13 mandic00@live.com

View File

@ -2,7 +2,7 @@
## Big Ticket Items ## Big Ticket Items
- Improve automated testing framework - N/A
## Explore Models ## Explore Models

File diff suppressed because one or more lines are too long

2
dist/human.esm.js vendored

File diff suppressed because one or more lines are too long

2
dist/human.js vendored

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

2
dist/human.node.js vendored

File diff suppressed because one or more lines are too long

View File

@ -21,11 +21,11 @@
"url": "git+https://github.com/vladmandic/human.git" "url": "git+https://github.com/vladmandic/human.git"
}, },
"scripts": { "scripts": {
"start": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation demo/node.js", "start": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught demo/node.js",
"dev": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught server/serve.js", "dev": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught server/serve.js",
"build": "rimraf dist/* typedoc/* types/* && node --trace-warnings --unhandled-rejections=strict --trace-uncaught server/build.js", "build": "rimraf dist/* typedoc/* types/* && node --trace-warnings --unhandled-rejections=strict --trace-uncaught server/build.js",
"lint": "eslint src server demo test", "lint": "eslint src server demo test",
"test": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation test/test-node.js" "test": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught test/test.js"
}, },
"keywords": [ "keywords": [
"human", "human",
@ -61,14 +61,14 @@
"@tensorflow/tfjs-layers": "^3.4.0", "@tensorflow/tfjs-layers": "^3.4.0",
"@tensorflow/tfjs-node": "^3.4.0", "@tensorflow/tfjs-node": "^3.4.0",
"@tensorflow/tfjs-node-gpu": "^3.4.0", "@tensorflow/tfjs-node-gpu": "^3.4.0",
"@types/node": "^14.14.37", "@types/node": "^14.14.39",
"@typescript-eslint/eslint-plugin": "^4.22.0", "@typescript-eslint/eslint-plugin": "^4.22.0",
"@typescript-eslint/parser": "^4.22.0", "@typescript-eslint/parser": "^4.22.0",
"@vladmandic/pilogger": "^0.2.16", "@vladmandic/pilogger": "^0.2.17",
"canvas": "^2.7.0", "canvas": "^2.7.0",
"chokidar": "^3.5.1", "chokidar": "^3.5.1",
"dayjs": "^1.10.4", "dayjs": "^1.10.4",
"esbuild": "^0.11.10", "esbuild": "^0.11.11",
"eslint": "^7.24.0", "eslint": "^7.24.0",
"eslint-config-airbnb-base": "^14.2.1", "eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.22.1", "eslint-plugin-import": "^2.22.1",

4
server/build.js Executable file → Normal file
View File

@ -1,6 +1,5 @@
#!/usr/bin/env -S node --trace-warnings
const ts = require('typescript'); const ts = require('typescript');
const path = require('path');
const log = require('@vladmandic/pilogger'); const log = require('@vladmandic/pilogger');
const esbuild = require('esbuild'); const esbuild = require('esbuild');
const TypeDoc = require('typedoc'); const TypeDoc = require('typedoc');
@ -265,6 +264,7 @@ async function build(f, msg, dev = false) {
} }
if (require.main === module) { if (require.main === module) {
log.logFile(path.join(__dirname, 'build.log'));
log.header(); log.header();
build('all', 'startup'); build('all', 'startup');
} else { } else {

34
server/build.log Normal file
View File

@ -0,0 +1,34 @@
2021-04-15 09:36:00 INFO:  @vladmandic/human version 1.5.2
2021-04-15 09:36:00 INFO:  User: vlado Platform: linux Arch: x64 Node: v15.7.0
2021-04-15 09:36:00 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true,"sourcemap":true,"bundle":true,"metafile":true,"target":"es2018"}
2021-04-15 09:36:00 STATE: Build for: node type: tfjs: {"imports":1,"importBytes":39,"outputBytes":733,"outputFiles":"dist/tfjs.esm.js"}
2021-04-15 09:36:00 STATE: Build for: node type: node: {"imports":46,"importBytes":545147,"outputBytes":304326,"outputFiles":"dist/human.node.js"}
2021-04-15 09:36:00 STATE: Build for: nodeGPU type: tfjs: {"imports":1,"importBytes":43,"outputBytes":737,"outputFiles":"dist/tfjs.esm.js"}
2021-04-15 09:36:00 STATE: Build for: nodeGPU type: node: {"imports":46,"importBytes":545151,"outputBytes":304334,"outputFiles":"dist/human.node-gpu.js"}
2021-04-15 09:36:00 STATE: Build for: nodeWASM type: tfjs: {"imports":1,"importBytes":81,"outputBytes":783,"outputFiles":"dist/tfjs.esm.js"}
2021-04-15 09:36:00 STATE: Build for: nodeWASM type: node: {"imports":46,"importBytes":545197,"outputBytes":304378,"outputFiles":"dist/human.node-wasm.js"}
2021-04-15 09:36:00 STATE: Build for: browserNoBundle type: tfjs: {"imports":1,"importBytes":2488,"outputBytes":1394,"outputFiles":"dist/tfjs.esm.js"}
2021-04-15 09:36:00 STATE: Build for: browserNoBundle type: esm: {"imports":46,"importBytes":545808,"outputBytes":304324,"outputFiles":"dist/human.esm-nobundle.js"}
2021-04-15 09:36:01 STATE: Build for: browserBundle type: tfjs: {"modules":1262,"moduleBytes":4068263,"imports":7,"importBytes":2488,"outputBytes":1097287,"outputFiles":"dist/tfjs.esm.js"}
2021-04-15 09:36:01 STATE: Build for: browserBundle type: iife: {"imports":46,"importBytes":1641701,"outputBytes":1397747,"outputFiles":"dist/human.js"}
2021-04-15 09:36:02 STATE: Build for: browserBundle type: esm: {"imports":46,"importBytes":1641701,"outputBytes":1397705,"outputFiles":"dist/human.esm.js"}
2021-04-15 09:36:02 INFO:  Generate types: ["src/human.ts"]
2021-04-15 09:36:07 INFO:  Update Change log: ["/home/vlado/dev/human/CHANGELOG.md"]
2021-04-15 09:36:07 INFO:  Generate TypeDocs: ["src/human.ts"]
2021-04-15 09:40:34 INFO:  @vladmandic/human version 1.5.2
2021-04-15 09:40:34 INFO:  User: vlado Platform: linux Arch: x64 Node: v15.7.0
2021-04-15 09:40:34 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true,"sourcemap":true,"bundle":true,"metafile":true,"target":"es2018"}
2021-04-15 09:40:34 STATE: Build for: node type: tfjs: {"imports":1,"importBytes":39,"outputBytes":733,"outputFiles":"dist/tfjs.esm.js"}
2021-04-15 09:40:34 STATE: Build for: node type: node: {"imports":46,"importBytes":545147,"outputBytes":304326,"outputFiles":"dist/human.node.js"}
2021-04-15 09:40:34 STATE: Build for: nodeGPU type: tfjs: {"imports":1,"importBytes":43,"outputBytes":737,"outputFiles":"dist/tfjs.esm.js"}
2021-04-15 09:40:35 STATE: Build for: nodeGPU type: node: {"imports":46,"importBytes":545151,"outputBytes":304334,"outputFiles":"dist/human.node-gpu.js"}
2021-04-15 09:40:35 STATE: Build for: nodeWASM type: tfjs: {"imports":1,"importBytes":81,"outputBytes":783,"outputFiles":"dist/tfjs.esm.js"}
2021-04-15 09:40:35 STATE: Build for: nodeWASM type: node: {"imports":46,"importBytes":545197,"outputBytes":304378,"outputFiles":"dist/human.node-wasm.js"}
2021-04-15 09:40:35 STATE: Build for: browserNoBundle type: tfjs: {"imports":1,"importBytes":2488,"outputBytes":1394,"outputFiles":"dist/tfjs.esm.js"}
2021-04-15 09:40:35 STATE: Build for: browserNoBundle type: esm: {"imports":46,"importBytes":545808,"outputBytes":304324,"outputFiles":"dist/human.esm-nobundle.js"}
2021-04-15 09:40:35 STATE: Build for: browserBundle type: tfjs: {"modules":1262,"moduleBytes":4068263,"imports":7,"importBytes":2488,"outputBytes":1097287,"outputFiles":"dist/tfjs.esm.js"}
2021-04-15 09:40:36 STATE: Build for: browserBundle type: iife: {"imports":46,"importBytes":1641701,"outputBytes":1397747,"outputFiles":"dist/human.js"}
2021-04-15 09:40:36 STATE: Build for: browserBundle type: esm: {"imports":46,"importBytes":1641701,"outputBytes":1397705,"outputFiles":"dist/human.esm.js"}
2021-04-15 09:40:36 INFO:  Generate types: ["src/human.ts"]
2021-04-15 09:40:41 INFO:  Update Change log: ["/home/vlado/dev/human/CHANGELOG.md"]
2021-04-15 09:40:41 INFO:  Generate TypeDocs: ["src/human.ts"]

2
server/serve.js Executable file → Normal file
View File

@ -1,5 +1,3 @@
#!/usr/bin/env -S node --trace-warnings
/* /*
micro http2 server with file monitoring and automatic app rebuild micro http2 server with file monitoring and automatic app rebuild
- can process concurrent http requests - can process concurrent http requests

View File

@ -4,22 +4,23 @@
### NodeJS using TensorFlow library ### NodeJS using TensorFlow library
- Image filters are disabled due to lack of Canvas and WeBGL access
- Face rotation is disabled for `NodeJS` platform: - Face rotation is disabled for `NodeJS` platform:
`Kernel 'RotateWithOffset' not registered for backend 'tensorflow'` `Kernel 'RotateWithOffset' not registered for backend 'tensorflow'`
<https://github.com/tensorflow/tfjs/issues/4606> <https://github.com/tensorflow/tfjs/issues/4606>
- Image filters are disabled due to lack of Canvas and WeBGL access
### NodeJS with GPU acceleation using CUDA ### NodeJS with GPU acceleation using CUDA
- Image filters are disabled due to lack of Canvas and WeBGL access
- Face rotation is disabled for `NodeJS` platform: - Face rotation is disabled for `NodeJS` platform:
`Kernel 'RotateWithOffset' not registered for backend 'tensorflow'` `Kernel 'RotateWithOffset' not registered for backend 'tensorflow'`
<https://github.com/tensorflow/tfjs/issues/4606> <https://github.com/tensorflow/tfjs/issues/4606>
- Image filters are disabled due to lack of Canvas and WeBGL access
### NodeJS using WASM ### NodeJS using WASM
- Requires dev http server - Requires dev http server
See <https://github.com/tensorflow/tfjs/issues/4927> See <https://github.com/tensorflow/tfjs/issues/4927>
- Image filters are disabled due to lack of Canvas and WeBGL access
- Only supported input is Tensor due to missing image decoders - Only supported input is Tensor due to missing image decoders
- Warmup returns null and is marked as failed - Warmup returns null and is marked as failed
Missing native Image implementation in NodeJS Missing native Image implementation in NodeJS

View File

@ -1,23 +1,25 @@
const process = require('process'); const process = require('process');
const path = require('path');
const log = require('@vladmandic/pilogger');
const canvasJS = require('canvas'); const canvasJS = require('canvas');
const fetch = require('node-fetch').default; const fetch = require('node-fetch').default;
let config; let config;
log.info('test:', path.basename(process.argv[1]));
const log = (status, ...data) => {
if (typeof process.send !== 'undefined') process.send([status, data]);
else process.stdout.write(JSON.stringify(data));
};
async function testHTTP() { async function testHTTP() {
if (config.modelBasePath.startsWith('file:')) return true; if (config.modelBasePath.startsWith('file:')) return true;
return new Promise((resolve) => { return new Promise((resolve) => {
fetch(config.modelBasePath) fetch(config.modelBasePath)
.then((res) => { .then((res) => {
if (res && res.ok) log.state('passed: model server:', config.modelBasePath); if (res && res.ok) log('state', 'passed: model server:', config.modelBasePath);
else log.error('failed: model server:', config.modelBasePath); else log('error', 'failed: model server:', config.modelBasePath);
resolve(res && res.ok); resolve(res && res.ok);
}) })
.catch((err) => { .catch((err) => {
log.error('failed: model server:', err.message); log('error', 'failed: model server:', err.message);
resolve(false); resolve(false);
}); });
}); });
@ -28,7 +30,7 @@ async function getImage(human, input) {
try { try {
img = await canvasJS.loadImage(input); img = await canvasJS.loadImage(input);
} catch (err) { } catch (err) {
log.error('failed: load image', input, err.message); log('error', 'failed: load image', input, err.message);
return img; return img;
} }
const canvas = canvasJS.createCanvas(img.width, img.height); const canvas = canvasJS.createCanvas(img.width, img.height);
@ -42,8 +44,8 @@ async function getImage(human, input) {
const reshape = human.tf.reshape(rgb, [1, canvas.width, canvas.height, 3]); // move extra dim from the end of tensor and use it as batch number instead const reshape = human.tf.reshape(rgb, [1, canvas.width, canvas.height, 3]); // move extra dim from the end of tensor and use it as batch number instead
return reshape; return reshape;
}); });
if (res && res.shape[0] === 1 && res.shape[3] === 3) log.state('passed: load image:', input, res.shape); if (res && res.shape[0] === 1 && res.shape[3] === 3) log('state', 'passed: load image:', input, res.shape);
else log.error('failed: load image:', input, res); else log('error', 'failed: load image:', input, res);
return res; return res;
} }
@ -51,31 +53,31 @@ function printResults(detect) {
const person = (detect.face && detect.face[0]) ? { confidence: detect.face[0].confidence, age: detect.face[0].age, gender: detect.face[0].gender } : {}; const person = (detect.face && detect.face[0]) ? { confidence: detect.face[0].confidence, age: detect.face[0].age, gender: detect.face[0].gender } : {};
const object = (detect.object && detect.object[0]) ? { score: detect.object[0].score, class: detect.object[0].label } : {}; const object = (detect.object && detect.object[0]) ? { score: detect.object[0].score, class: detect.object[0].label } : {};
const body = (detect.body && detect.body[0]) ? { score: detect.body[0].score, keypoints: detect.body[0].keypoints.length } : {}; const body = (detect.body && detect.body[0]) ? { score: detect.body[0].score, keypoints: detect.body[0].keypoints.length } : {};
if (detect.face) log.data(' result: face:', detect.face?.length, 'body:', detect.body?.length, 'hand:', detect.hand?.length, 'gesture:', detect.gesture?.length, 'object:', detect.object?.length, person, object, body); if (detect.face) log('data', ' result: face:', detect.face?.length, 'body:', detect.body?.length, 'hand:', detect.hand?.length, 'gesture:', detect.gesture?.length, 'object:', detect.object?.length, person, object, body);
if (detect.performance) log.data(' result: performance:', 'load:', detect?.performance.load, 'total:', detect.performance?.total); if (detect.performance) log('data', ' result: performance:', 'load:', detect?.performance.load, 'total:', detect.performance?.total);
} }
async function testInstance(human) { async function testInstance(human) {
if (human) log.state('passed: create human'); if (human) log('state', 'passed: create human');
else log.error('failed: create human'); else log('error', 'failed: create human');
// if (!human.tf) human.tf = tf; // if (!human.tf) human.tf = tf;
log.info('human version:', human.version); log('info', 'human version:', human.version);
log.info('platform:', human.sysinfo.platform, 'agent:', human.sysinfo.agent); log('info', 'platform:', human.sysinfo.platform, 'agent:', human.sysinfo.agent);
log.info('tfjs version:', human.tf.version.tfjs); log('info', 'tfjs version:', human.tf.version.tfjs);
await human.load(); await human.load();
if (config.backend === human.tf.getBackend()) log.state('passed: set backend:', config.backend); if (config.backend === human.tf.getBackend()) log('state', 'passed: set backend:', config.backend);
else log.error('failed: set backend:', config.backend); else log('error', 'failed: set backend:', config.backend);
if (human.models) { if (human.models) {
log.state('passed: load models'); log('state', 'passed: load models');
const keys = Object.keys(human.models); const keys = Object.keys(human.models);
const loaded = keys.filter((model) => human.models[model]); const loaded = keys.filter((model) => human.models[model]);
log.data(' result: defined models:', keys.length, 'loaded models:', loaded.length); log('state', ' result: defined models:', keys.length, 'loaded models:', loaded.length);
return true; return true;
} }
log.error('failed: load models'); log('error', 'failed: load models');
return false; return false;
} }
@ -84,36 +86,36 @@ async function testWarmup(human, title) {
try { try {
warmup = await human.warmup(config); warmup = await human.warmup(config);
} catch (err) { } catch (err) {
log.error('error warmup'); log('error', 'error warmup');
} }
if (warmup) { if (warmup) {
log.state('passed: warmup:', config.warmup, title); log('state', 'passed: warmup:', config.warmup, title);
printResults(warmup); printResults(warmup);
return true; return true;
} }
log.error('failed: warmup:', config.warmup, title); log('error', 'failed: warmup:', config.warmup, title);
return false; return false;
} }
async function testDetect(human, input, title) { async function testDetect(human, input, title) {
const image = input ? await getImage(human, input) : human.tf.randomNormal([1, 1024, 1024, 3]); const image = input ? await getImage(human, input) : human.tf.randomNormal([1, 1024, 1024, 3]);
if (!image) { if (!image) {
log.error('failed: detect: input is null'); log('error', 'failed: detect: input is null');
return false; return false;
} }
let detect; let detect;
try { try {
detect = await human.detect(image, config); detect = await human.detect(image, config);
} catch (err) { } catch (err) {
log.error('error: detect', err); log('error', 'error: detect', err);
} }
if (image instanceof human.tf.Tensor) human.tf.dispose(image); if (image instanceof human.tf.Tensor) human.tf.dispose(image);
if (detect) { if (detect) {
log.state('passed: detect:', input || 'random', title); log('state', 'passed: detect:', input || 'random', title);
printResults(detect); printResults(detect);
return true; return true;
} }
log.error('failed: detect', input || 'random', title); log('error', 'failed: detect', input || 'random', title);
return false; return false;
} }
@ -121,7 +123,7 @@ async function test(Human, inputConfig) {
config = inputConfig; config = inputConfig;
const ok = await testHTTP(); const ok = await testHTTP();
if (!ok) { if (!ok) {
log.warn('aborting test'); log('error', 'aborting test');
return; return;
} }
const t0 = process.hrtime.bigint(); const t0 = process.hrtime.bigint();
@ -134,7 +136,7 @@ async function test(Human, inputConfig) {
config.warmup = 'body'; config.warmup = 'body';
await testWarmup(human, 'default'); await testWarmup(human, 'default');
log.info('test body variants'); log('info', 'test body variants');
config.body = { modelPath: 'posenet.json', enabled: true }; config.body = { modelPath: 'posenet.json', enabled: true };
await testDetect(human, 'assets/human-sample-body.jpg', 'posenet'); await testDetect(human, 'assets/human-sample-body.jpg', 'posenet');
config.body = { modelPath: 'efficientpose.json', enabled: true }; config.body = { modelPath: 'efficientpose.json', enabled: true };
@ -143,12 +145,12 @@ async function test(Human, inputConfig) {
await testDetect(human, 'assets/human-sample-body.jpg', 'blazepose'); await testDetect(human, 'assets/human-sample-body.jpg', 'blazepose');
await testDetect(human, null, 'default'); await testDetect(human, null, 'default');
log.info('test: first instance'); log('info', 'test: first instance');
await testDetect(human, 'assets/sample-me.jpg', 'default'); await testDetect(human, 'assets/sample-me.jpg', 'default');
log.info('test: second instance'); log('info', 'test: second instance');
const second = new Human(config); const second = new Human(config);
await testDetect(second, 'assets/sample-me.jpg', 'default'); await testDetect(second, 'assets/sample-me.jpg', 'default');
log.info('test: concurrent'); log('info', 'test: concurrent');
await Promise.all([ await Promise.all([
testDetect(human, 'assets/human-sample-face.jpg', 'default'), testDetect(human, 'assets/human-sample-face.jpg', 'default'),
testDetect(second, 'assets/human-sample-face.jpg', 'default'), testDetect(second, 'assets/human-sample-face.jpg', 'default'),
@ -156,7 +158,7 @@ async function test(Human, inputConfig) {
testDetect(second, 'assets/human-sample-body.jpg', 'default'), testDetect(second, 'assets/human-sample-body.jpg', 'default'),
]); ]);
const t1 = process.hrtime.bigint(); const t1 = process.hrtime.bigint();
log.info('test complete:', Math.trunc(parseInt((t1 - t0).toString()) / 1000 / 1000), 'ms'); log('info', 'test complete:', Math.trunc(parseInt((t1 - t0).toString()) / 1000 / 1000), 'ms');
} }
exports.test = test; exports.test = test;

69
test/test.js Normal file
View File

@ -0,0 +1,69 @@
const path = require('path');
const process = require('process');
const { fork } = require('child_process');
const log = require('@vladmandic/pilogger');
const tests = [
'test-node.js',
'test-node-gpu.js',
'test-node-wasm.js',
];
const ignore = [
'cpu_feature_guard.cc',
'rebuild TensorFlow',
'xla_gpu_device.cc',
'cudart_stub.cc',
'cuda_driver.cc:326',
'cpu_allocator_impl.cc',
];
const status = {
passed: 0,
failed: 0,
};
function logMessage(test, data) {
log[data[0]](test, ...data[1]);
if (data[1][0].startsWith('passed')) status.passed++;
if (data[1][0].startsWith('failed')) status.failed++;
}
function logStdIO(ok, test, buffer) {
const lines = buffer.toString().split(/\r\n|\n\r|\n|\r/);
const filtered = lines.filter((line) => {
for (const ignoreString of ignore) {
if (line.includes(ignoreString)) return false;
}
return true;
});
for (const line of filtered) {
if (line.length < 2) continue;
if (ok) log.data(test, 'stdout:', line);
else log.warn(test, 'stderr:', line);
}
}
async function runTest(test) {
return new Promise((resolve) => {
log.info(test, 'start');
const child = fork(path.join(__dirname, test), [], { silent: true });
child.on('message', (data) => logMessage(test, data));
child.on('error', (data) => log.error(test, ':', data.message || data));
child.on('close', (code) => resolve(code));
child.stdout?.on('data', (data) => logStdIO(true, test, data));
child.stderr?.on('data', (data) => logStdIO(false, test, data));
});
}
async function testAll() {
log.logFile(path.join(__dirname, 'test.log'));
log.header();
process.on('unhandledRejection', (data) => log.error('nodejs unhandled rejection', data));
process.on('uncaughtException', (data) => log.error('nodejs unhandled exception', data));
log.info('tests:', tests);
for (const test of tests) await runTest(test);
log.info('status:', status);
}
testAll();

181
test/test.log Normal file
View File

@ -0,0 +1,181 @@
2021-04-15 09:33:11 INFO:  @vladmandic/human version 1.5.2
2021-04-15 09:33:11 INFO:  User: vlado Platform: linux Arch: x64 Node: v15.7.0
2021-04-15 09:33:11 INFO:  tests: ["test-node.js","test-node-gpu.js","test-node-wasm.js"]
2021-04-15 09:33:11 INFO:  test-node.js start
2021-04-15 09:33:12 STATE: test-node.js passed: create human
2021-04-15 09:33:12 INFO:  test-node.js human version: 1.5.2
2021-04-15 09:33:12 INFO:  test-node.js platform: linux x64 agent: NodeJS v15.7.0
2021-04-15 09:33:12 INFO:  test-node.js tfjs version: 3.4.0
2021-04-15 09:33:12 STATE: test-node.js passed: set backend: tensorflow
2021-04-15 09:33:12 STATE: test-node.js passed: load models
2021-04-15 09:33:12 STATE: test-node.js result: defined models: 12 loaded models: 6
2021-04-15 09:33:12 STATE: test-node.js passed: warmup: none default
2021-04-15 09:33:13 STATE: test-node.js passed: warmup: face default
2021-04-15 09:33:13 DATA:  test-node.js result: face: 1 body: 0 hand: 0 gesture: 2 object: 1 {"confidence":1,"age":23.6,"gender":"female"} {"score":0.52,"class":"person"} {}
2021-04-15 09:33:13 DATA:  test-node.js result: performance: load: 485 total: 1252
2021-04-15 09:33:15 STATE: test-node.js passed: warmup: body default
2021-04-15 09:33:15 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.95,"keypoints":17}
2021-04-15 09:33:15 DATA:  test-node.js result: performance: load: 485 total: 1305
2021-04-15 09:33:15 INFO:  test-node.js test body variants
2021-04-15 09:33:16 STATE: test-node.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3]
2021-04-15 09:33:17 STATE: test-node.js passed: detect: assets/human-sample-body.jpg posenet
2021-04-15 09:33:17 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.95,"keypoints":17}
2021-04-15 09:33:17 DATA:  test-node.js result: performance: load: 485 total: 1246
2021-04-15 09:33:18 STATE: test-node.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3]
2021-04-15 09:33:20 STATE: test-node.js passed: detect: assets/human-sample-body.jpg efficientpose
2021-04-15 09:33:20 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.75,"keypoints":13}
2021-04-15 09:33:20 DATA:  test-node.js result: performance: load: 485 total: 1851
2021-04-15 09:33:21 STATE: test-node.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3]
2021-04-15 09:33:22 STATE: test-node.js passed: detect: assets/human-sample-body.jpg blazepose
2021-04-15 09:33:22 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":1,"keypoints":39}
2021-04-15 09:33:22 DATA:  test-node.js result: performance: load: 485 total: 1320
2021-04-15 09:33:23 STATE: test-node.js passed: detect: random default
2021-04-15 09:33:23 DATA:  test-node.js result: face: 0 body: 1 hand: 0 gesture: 1 object: 0 {} {} {"score":1,"keypoints":39}
2021-04-15 09:33:23 DATA:  test-node.js result: performance: load: 485 total: 692
2021-04-15 09:33:23 INFO:  test-node.js test: first instance
2021-04-15 09:33:24 STATE: test-node.js passed: load image: assets/sample-me.jpg [1,700,700,3]
2021-04-15 09:33:25 STATE: test-node.js passed: detect: assets/sample-me.jpg default
2021-04-15 09:33:25 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 2 {"confidence":1,"age":39.2,"gender":"male"} {"score":0.7,"class":"person"} {"score":1,"keypoints":39}
2021-04-15 09:33:25 DATA:  test-node.js result: performance: load: 485 total: 1038
2021-04-15 09:33:25 INFO:  test-node.js test: second instance
2021-04-15 09:33:25 STATE: test-node.js passed: load image: assets/sample-me.jpg [1,700,700,3]
2021-04-15 09:33:26 STATE: test-node.js passed: detect: assets/sample-me.jpg default
2021-04-15 09:33:26 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 2 {"confidence":1,"age":39.2,"gender":"male"} {"score":0.7,"class":"person"} {"score":1,"keypoints":39}
2021-04-15 09:33:26 DATA:  test-node.js result: performance: load: 6 total: 1200
2021-04-15 09:33:26 INFO:  test-node.js test: concurrent
2021-04-15 09:33:26 STATE: test-node.js passed: load image: assets/human-sample-face.jpg [1,256,256,3]
2021-04-15 09:33:26 STATE: test-node.js passed: load image: assets/human-sample-face.jpg [1,256,256,3]
2021-04-15 09:33:27 STATE: test-node.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3]
2021-04-15 09:33:28 STATE: test-node.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3]
2021-04-15 09:33:33 STATE: test-node.js passed: detect: assets/human-sample-face.jpg default
2021-04-15 09:33:33 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 1 {"confidence":1,"age":23.6,"gender":"female"} {"score":0.53,"class":"person"} {"score":1,"keypoints":39}
2021-04-15 09:33:33 DATA:  test-node.js result: performance: load: 485 total: 4406
2021-04-15 09:33:33 STATE: test-node.js passed: detect: assets/human-sample-face.jpg default
2021-04-15 09:33:33 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 1 {"confidence":1,"age":23.6,"gender":"female"} {"score":0.53,"class":"person"} {"score":1,"keypoints":39}
2021-04-15 09:33:33 DATA:  test-node.js result: performance: load: 6 total: 4407
2021-04-15 09:33:33 STATE: test-node.js passed: detect: assets/human-sample-body.jpg default
2021-04-15 09:33:33 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":1,"keypoints":39}
2021-04-15 09:33:33 DATA:  test-node.js result: performance: load: 485 total: 4406
2021-04-15 09:33:33 STATE: test-node.js passed: detect: assets/human-sample-body.jpg default
2021-04-15 09:33:33 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":1,"keypoints":39}
2021-04-15 09:33:33 DATA:  test-node.js result: performance: load: 6 total: 4407
2021-04-15 09:33:33 INFO:  test-node.js test complete: 21236 ms
2021-04-15 09:33:33 INFO:  test-node-gpu.js start
2021-04-15 09:33:33 WARN:  test-node-gpu.js stderr: 2021-04-15 09:33:33.862585: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory
2021-04-15 09:33:33 WARN:  test-node-gpu.js stderr: 2021-04-15 09:33:33.916618: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory
2021-04-15 09:33:33 WARN:  test-node-gpu.js stderr: 2021-04-15 09:33:33.916711: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (wyse): /proc/driver/nvidia/version does not exist
2021-04-15 09:33:34 STATE: test-node-gpu.js passed: create human
2021-04-15 09:33:34 INFO:  test-node-gpu.js human version: 1.5.2
2021-04-15 09:33:34 INFO:  test-node-gpu.js platform: linux x64 agent: NodeJS v15.7.0
2021-04-15 09:33:34 INFO:  test-node-gpu.js tfjs version: 3.4.0
2021-04-15 09:33:34 STATE: test-node-gpu.js passed: set backend: tensorflow
2021-04-15 09:33:34 STATE: test-node-gpu.js passed: load models
2021-04-15 09:33:34 STATE: test-node-gpu.js result: defined models: 12 loaded models: 6
2021-04-15 09:33:34 STATE: test-node-gpu.js passed: warmup: none default
2021-04-15 09:33:35 STATE: test-node-gpu.js passed: warmup: face default
2021-04-15 09:33:35 DATA:  test-node-gpu.js result: face: 1 body: 0 hand: 0 gesture: 2 object: 1 {"confidence":1,"age":23.6,"gender":"female"} {"score":0.52,"class":"person"} {}
2021-04-15 09:33:35 DATA:  test-node-gpu.js result: performance: load: 464 total: 1274
2021-04-15 09:33:37 STATE: test-node-gpu.js passed: warmup: body default
2021-04-15 09:33:37 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.95,"keypoints":17}
2021-04-15 09:33:37 DATA:  test-node-gpu.js result: performance: load: 464 total: 1295
2021-04-15 09:33:37 INFO:  test-node-gpu.js test body variants
2021-04-15 09:33:38 STATE: test-node-gpu.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3]
2021-04-15 09:33:39 STATE: test-node-gpu.js passed: detect: assets/human-sample-body.jpg posenet
2021-04-15 09:33:39 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.95,"keypoints":17}
2021-04-15 09:33:39 DATA:  test-node-gpu.js result: performance: load: 464 total: 1285
2021-04-15 09:33:40 STATE: test-node-gpu.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3]
2021-04-15 09:33:42 STATE: test-node-gpu.js passed: detect: assets/human-sample-body.jpg efficientpose
2021-04-15 09:33:42 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.75,"keypoints":13}
2021-04-15 09:33:42 DATA:  test-node-gpu.js result: performance: load: 464 total: 2037
2021-04-15 09:33:43 STATE: test-node-gpu.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3]
2021-04-15 09:33:44 STATE: test-node-gpu.js passed: detect: assets/human-sample-body.jpg blazepose
2021-04-15 09:33:44 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":1,"keypoints":39}
2021-04-15 09:33:44 DATA:  test-node-gpu.js result: performance: load: 464 total: 1433
2021-04-15 09:33:45 STATE: test-node-gpu.js passed: detect: random default
2021-04-15 09:33:45 DATA:  test-node-gpu.js result: face: 0 body: 1 hand: 0 gesture: 1 object: 0 {} {} {"score":1,"keypoints":39}
2021-04-15 09:33:45 DATA:  test-node-gpu.js result: performance: load: 464 total: 714
2021-04-15 09:33:45 INFO:  test-node-gpu.js test: first instance
2021-04-15 09:33:46 STATE: test-node-gpu.js passed: load image: assets/sample-me.jpg [1,700,700,3]
2021-04-15 09:33:47 STATE: test-node-gpu.js passed: detect: assets/sample-me.jpg default
2021-04-15 09:33:47 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 2 {"confidence":1,"age":39.2,"gender":"male"} {"score":0.7,"class":"person"} {"score":1,"keypoints":39}
2021-04-15 09:33:47 DATA:  test-node-gpu.js result: performance: load: 464 total: 1050
2021-04-15 09:33:47 INFO:  test-node-gpu.js test: second instance
2021-04-15 09:33:47 STATE: test-node-gpu.js passed: load image: assets/sample-me.jpg [1,700,700,3]
2021-04-15 09:33:48 STATE: test-node-gpu.js passed: detect: assets/sample-me.jpg default
2021-04-15 09:33:48 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 2 {"confidence":1,"age":39.2,"gender":"male"} {"score":0.7,"class":"person"} {"score":1,"keypoints":39}
2021-04-15 09:33:48 DATA:  test-node-gpu.js result: performance: load: 4 total: 1028
2021-04-15 09:33:48 INFO:  test-node-gpu.js test: concurrent
2021-04-15 09:33:48 STATE: test-node-gpu.js passed: load image: assets/human-sample-face.jpg [1,256,256,3]
2021-04-15 09:33:48 STATE: test-node-gpu.js passed: load image: assets/human-sample-face.jpg [1,256,256,3]
2021-04-15 09:33:49 STATE: test-node-gpu.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3]
2021-04-15 09:33:50 STATE: test-node-gpu.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3]
2021-04-15 09:33:55 STATE: test-node-gpu.js passed: detect: assets/human-sample-face.jpg default
2021-04-15 09:33:55 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 1 {"confidence":1,"age":23.6,"gender":"female"} {"score":0.53,"class":"person"} {"score":1,"keypoints":39}
2021-04-15 09:33:55 DATA:  test-node-gpu.js result: performance: load: 464 total: 4261
2021-04-15 09:33:55 STATE: test-node-gpu.js passed: detect: assets/human-sample-face.jpg default
2021-04-15 09:33:55 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 1 {"confidence":1,"age":23.6,"gender":"female"} {"score":0.53,"class":"person"} {"score":1,"keypoints":39}
2021-04-15 09:33:55 DATA:  test-node-gpu.js result: performance: load: 4 total: 4261
2021-04-15 09:33:55 STATE: test-node-gpu.js passed: detect: assets/human-sample-body.jpg default
2021-04-15 09:33:55 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":1,"keypoints":39}
2021-04-15 09:33:55 DATA:  test-node-gpu.js result: performance: load: 464 total: 4261
2021-04-15 09:33:55 STATE: test-node-gpu.js passed: detect: assets/human-sample-body.jpg default
2021-04-15 09:33:55 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":1,"keypoints":39}
2021-04-15 09:33:55 DATA:  test-node-gpu.js result: performance: load: 4 total: 4261
2021-04-15 09:33:55 INFO:  test-node-gpu.js test complete: 21151 ms
2021-04-15 09:33:55 INFO:  test-node-wasm.js start
2021-04-15 09:33:55 STATE: test-node-wasm.js passed: model server: http://localhost:10030/models/
2021-04-15 09:33:55 STATE: test-node-wasm.js passed: create human
2021-04-15 09:33:55 INFO:  test-node-wasm.js human version: 1.5.2
2021-04-15 09:33:55 INFO:  test-node-wasm.js platform: linux x64 agent: NodeJS v15.7.0
2021-04-15 09:33:55 INFO:  test-node-wasm.js tfjs version: 3.4.0
2021-04-15 09:33:56 STATE: test-node-wasm.js passed: set backend: wasm
2021-04-15 09:33:56 STATE: test-node-wasm.js passed: load models
2021-04-15 09:33:56 STATE: test-node-wasm.js result: defined models: 12 loaded models: 5
2021-04-15 09:33:56 STATE: test-node-wasm.js passed: warmup: none default
2021-04-15 09:33:56 ERROR: test-node-wasm.js failed: warmup: face default
2021-04-15 09:33:56 ERROR: test-node-wasm.js failed: warmup: body default
2021-04-15 09:33:56 INFO:  test-node-wasm.js test body variants
2021-04-15 09:33:58 STATE: test-node-wasm.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3]
2021-04-15 09:34:01 STATE: test-node-wasm.js passed: detect: assets/human-sample-body.jpg posenet
2021-04-15 09:34:01 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 0 {"confidence":1,"age":28.5,"gender":"female"} {} {"score":0.93,"keypoints":17}
2021-04-15 09:34:01 DATA:  test-node-wasm.js result: performance: load: 827 total: 2835
2021-04-15 09:34:02 STATE: test-node-wasm.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3]
2021-04-15 09:34:08 STATE: test-node-wasm.js passed: detect: assets/human-sample-body.jpg efficientpose
2021-04-15 09:34:08 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 0 {"confidence":1,"age":28.5,"gender":"female"} {} {"score":0.5,"keypoints":16}
2021-04-15 09:34:08 DATA:  test-node-wasm.js result: performance: load: 827 total: 5024
2021-04-15 09:34:09 STATE: test-node-wasm.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3]
2021-04-15 09:34:12 STATE: test-node-wasm.js passed: detect: assets/human-sample-body.jpg blazepose
2021-04-15 09:34:12 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 0 {"confidence":1,"age":28.5,"gender":"female"} {} {"score":1,"keypoints":39}
2021-04-15 09:34:12 DATA:  test-node-wasm.js result: performance: load: 827 total: 2437
2021-04-15 09:34:13 STATE: test-node-wasm.js passed: detect: random default
2021-04-15 09:34:13 DATA:  test-node-wasm.js result: face: 0 body: 1 hand: 0 gesture: 1 object: 0 {} {} {"score":1,"keypoints":39}
2021-04-15 09:34:13 DATA:  test-node-wasm.js result: performance: load: 827 total: 1384
2021-04-15 09:34:13 INFO:  test-node-wasm.js test: first instance
2021-04-15 09:34:14 STATE: test-node-wasm.js passed: load image: assets/sample-me.jpg [1,700,700,3]
2021-04-15 09:34:16 STATE: test-node-wasm.js passed: detect: assets/sample-me.jpg default
2021-04-15 09:34:16 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 0 {"confidence":1,"age":39.2,"gender":"male"} {} {"score":1,"keypoints":39}
2021-04-15 09:34:16 DATA:  test-node-wasm.js result: performance: load: 827 total: 2091
2021-04-15 09:34:16 INFO:  test-node-wasm.js test: second instance
2021-04-15 09:34:17 STATE: test-node-wasm.js passed: load image: assets/sample-me.jpg [1,700,700,3]
2021-04-15 09:34:19 STATE: test-node-wasm.js passed: detect: assets/sample-me.jpg default
2021-04-15 09:34:19 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 0 {"confidence":1,"age":39.2,"gender":"male"} {} {"score":1,"keypoints":39}
2021-04-15 09:34:19 DATA:  test-node-wasm.js result: performance: load: 3 total: 2065
2021-04-15 09:34:19 INFO:  test-node-wasm.js test: concurrent
2021-04-15 09:34:19 STATE: test-node-wasm.js passed: load image: assets/human-sample-face.jpg [1,256,256,3]
2021-04-15 09:34:19 STATE: test-node-wasm.js passed: load image: assets/human-sample-face.jpg [1,256,256,3]
2021-04-15 09:34:21 STATE: test-node-wasm.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3]
2021-04-15 09:34:23 STATE: test-node-wasm.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3]
2021-04-15 09:34:31 STATE: test-node-wasm.js passed: detect: assets/human-sample-face.jpg default
2021-04-15 09:34:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 0 {"confidence":1,"age":23.6,"gender":"female"} {} {"score":1,"keypoints":39}
2021-04-15 09:34:31 DATA:  test-node-wasm.js result: performance: load: 827 total: 7839
2021-04-15 09:34:31 STATE: test-node-wasm.js passed: detect: assets/human-sample-face.jpg default
2021-04-15 09:34:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 0 {"confidence":1,"age":23.6,"gender":"female"} {} {"score":1,"keypoints":39}
2021-04-15 09:34:31 DATA:  test-node-wasm.js result: performance: load: 3 total: 7839
2021-04-15 09:34:31 STATE: test-node-wasm.js passed: detect: assets/human-sample-body.jpg default
2021-04-15 09:34:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 0 {"confidence":1,"age":28.5,"gender":"female"} {} {"score":1,"keypoints":39}
2021-04-15 09:34:31 DATA:  test-node-wasm.js result: performance: load: 827 total: 7839
2021-04-15 09:34:31 STATE: test-node-wasm.js passed: detect: assets/human-sample-body.jpg default
2021-04-15 09:34:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 0 {"confidence":1,"age":28.5,"gender":"female"} {} {"score":1,"keypoints":39}
2021-04-15 09:34:31 DATA:  test-node-wasm.js result: performance: load: 3 total: 7839
2021-04-15 09:34:31 INFO:  test-node-wasm.js test complete: 35570 ms
2021-04-15 09:34:31 INFO:  status: {"passed":74,"failed":2}