mirror of https://github.com/vladmandic/human
add browser iife tests
parent
39634cb25d
commit
a222ce933f
|
@ -9,8 +9,9 @@
|
|||
|
||||
## Changelog
|
||||
|
||||
### **HEAD -> main** 2022/08/30 mandic00@live.com
|
||||
### **HEAD -> main** 2022/08/31 mandic00@live.com
|
||||
|
||||
- extend release tests
|
||||
- add model load exception handling
|
||||
- add softwarekernels config option
|
||||
- expand type safety
|
||||
|
|
8
TODO.md
8
TODO.md
|
@ -61,12 +61,12 @@ Enable via `about:config` -> `gfx.offscreencanvas.enabled`
|
|||
- Treat models that cannot be found & loaded as non-critical error
|
||||
Instead of creating runtime exception, `human` will now report that model could not be loaded
|
||||
- Improve `human.reset()` method to reset all config values to defaults
|
||||
- Host models in <human-models>
|
||||
- Host models in <https://github.com/vladmandic/human-models>
|
||||
Models can be directly used without downloading to local storage
|
||||
Example: `modelPath: 'https://vladmandic.github.io/human-models/models/facemesh.json'`
|
||||
Example: `modelBasePath: 'https://vladmandic.github.io/human-models/models/'`
|
||||
- Allow hosting models in **Google Cloud Bucket**
|
||||
Hosted models can be directly used without downloading to local storage
|
||||
Example: `modelPath: 'https://storage.googleapis.com/human-models/facemesh.json'`
|
||||
Example: `modelBasePath: 'https://storage.googleapis.com/human-models/'`
|
||||
- Stricter linting rules for both **TypeScript** and **JavaScript**
|
||||
See `./eslintrc.json` for details
|
||||
- Enhanced type safety across entire library
|
||||
|
@ -76,7 +76,7 @@ Enable via `about:config` -> `gfx.offscreencanvas.enabled`
|
|||
- Fix **NanoDet** module as alternative object detection
|
||||
- Fix `demo/multithread/node-multiprocess.js` demo
|
||||
- Fix `human.match` when using mixed descriptor lengths
|
||||
- Fix WASM feature detection issue in TFJS with Edge/Chromium
|
||||
- Fix **WASM** feature detection issue in TFJS with Edge/Chromium
|
||||
Example: `console.log(human.env.wasm)`
|
||||
- Increased test coverage
|
||||
**NodeJS**: Run using: `npm run test`
|
||||
|
|
|
@ -1,24 +1,3 @@
|
|||
# Test Results
|
||||
|
||||
## Automatic Tests
|
||||
# Automatic Tests
|
||||
|
||||
Not required for normal funcioning of library
|
||||
|
||||
### NodeJS using TensorFlow library
|
||||
|
||||
- Image filters are disabled due to lack of Canvas and WebGL access
|
||||
|
||||
### NodeJS using WASM
|
||||
|
||||
- Requires dev http server
|
||||
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
|
||||
|
||||
<br>
|
||||
|
||||
## Browser Tests
|
||||
|
||||
- Chrome/Edge: **All Passing**
|
||||
- Firefox: WebWorkers not supported due to missing support for `OffscreenCanvas`
|
||||
- Safari: **Limited Testing**
|
||||
|
|
|
@ -1,2 +1,7 @@
|
|||
#!/bin/sh
|
||||
"/mnt/c/Users/mandi/AppData/Local/Google/Chrome SxS/Application/chrome.exe" --enable-unsafe-gpu --allow-insecure-localhost --auto-open-devtools-for-tabs https://localhost:10031/test/browser.html
|
||||
|
||||
BROWSER="/mnt/c/Users/mandi/AppData/Local/Google/Chrome SxS/Application/chrome.exe"
|
||||
PARAMS="--enable-unsafe-gpu --allow-insecure-localhost --auto-open-devtools-for-tabs"
|
||||
|
||||
"$BROWSER" $PARAMS https://localhost:10031/test/test-browser-iife.html
|
||||
"$BROWSER" $PARAMS https://localhost:10031/test/test-browser-esm.html
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
2022-08-31 11:27:08 [32mDATA: [39m Build {"name":"@vladmandic/human","version":"2.9.4"}
|
||||
2022-08-31 11:27:08 [36mINFO: [39m Application: {"name":"@vladmandic/human","version":"2.9.4"}
|
||||
2022-08-31 11:27:08 [36mINFO: [39m Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
|
||||
2022-08-31 11:27:08 [36mINFO: [39m Toolchain: {"build":"0.7.11","esbuild":"0.15.6","typescript":"4.8.2","typedoc":"0.23.12","eslint":"8.23.0"}
|
||||
2022-08-31 11:27:08 [36mINFO: [39m Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
|
||||
2022-08-31 11:27:08 [35mSTATE:[39m Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]}
|
||||
2022-08-31 11:27:08 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":159,"outputBytes":608}
|
||||
2022-08-31 11:27:08 [35mSTATE:[39m Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":75,"inputBytes":655767,"outputBytes":308629}
|
||||
2022-08-31 11:27:08 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":167,"outputBytes":612}
|
||||
2022-08-31 11:27:08 [35mSTATE:[39m Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":75,"inputBytes":655771,"outputBytes":308633}
|
||||
2022-08-31 11:27:08 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":206,"outputBytes":664}
|
||||
2022-08-31 11:27:08 [35mSTATE:[39m Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":75,"inputBytes":655823,"outputBytes":308683}
|
||||
2022-08-31 11:27:08 [35mSTATE:[39m Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1125,"outputBytes":358}
|
||||
2022-08-31 11:27:08 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":1088,"outputBytes":583}
|
||||
2022-08-31 11:27:09 [35mSTATE:[39m Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":75,"inputBytes":655742,"outputBytes":307503}
|
||||
2022-08-31 11:27:09 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/custom","format":"esm","platform":"browser","input":"tfjs/tf-custom.ts","output":"dist/tfjs.esm.js","files":11,"inputBytes":1344,"outputBytes":2821914}
|
||||
2022-08-31 11:27:09 [35mSTATE:[39m Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":75,"inputBytes":3477073,"outputBytes":1687675}
|
||||
2022-08-31 11:27:09 [35mSTATE:[39m Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":75,"inputBytes":3477073,"outputBytes":3108312}
|
||||
2022-08-31 11:27:13 [35mSTATE:[39m Typings: {"input":"src/human.ts","output":"types/lib","files":30}
|
||||
2022-08-31 11:27:15 [35mSTATE:[39m TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":77,"generated":true}
|
||||
2022-08-31 11:27:15 [35mSTATE:[39m Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":6714,"outputBytes":3134}
|
||||
2022-08-31 11:27:15 [35mSTATE:[39m Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15488,"outputBytes":7788}
|
||||
2022-08-31 11:27:25 [35mSTATE:[39m Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":111,"errors":0,"warnings":0}
|
||||
2022-08-31 11:27:25 [35mSTATE:[39m ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
|
||||
2022-08-31 11:27:25 [35mSTATE:[39m Copy: {"input":"tfjs/tfjs.esm.d.ts"}
|
||||
2022-08-31 11:27:25 [36mINFO: [39m Done...
|
||||
2022-08-31 11:27:26 [35mSTATE:[39m API-Extractor: {"succeeeded":true,"errors":0,"warnings":198}
|
||||
2022-08-31 11:27:26 [35mSTATE:[39m Copy: {"input":"types/human.d.ts"}
|
||||
2022-08-31 11:27:26 [36mINFO: [39m Analyze models: {"folders":8,"result":"models/models.json"}
|
||||
2022-08-31 11:27:26 [35mSTATE:[39m Models {"folder":"./models","models":13}
|
||||
2022-08-31 11:27:26 [35mSTATE:[39m Models {"folder":"../human-models/models","models":42}
|
||||
2022-08-31 11:27:26 [35mSTATE:[39m Models {"folder":"../blazepose/model/","models":4}
|
||||
2022-08-31 11:27:26 [35mSTATE:[39m Models {"folder":"../anti-spoofing/model","models":1}
|
||||
2022-08-31 11:27:26 [35mSTATE:[39m Models {"folder":"../efficientpose/models","models":3}
|
||||
2022-08-31 11:27:26 [35mSTATE:[39m Models {"folder":"../insightface/models","models":5}
|
||||
2022-08-31 11:27:26 [35mSTATE:[39m Models {"folder":"../movenet/models","models":3}
|
||||
2022-08-31 11:27:26 [35mSTATE:[39m Models {"folder":"../nanodet/models","models":4}
|
||||
2022-08-31 11:27:27 [35mSTATE:[39m Models: {"count":57,"totalSize":383017442}
|
||||
2022-08-31 11:27:27 [36mINFO: [39m Human Build complete... {"logFile":"test/build.log"}
|
||||
2022-08-31 18:30:05 [32mDATA: [39m Build {"name":"@vladmandic/human","version":"2.9.4"}
|
||||
2022-08-31 18:30:05 [36mINFO: [39m Application: {"name":"@vladmandic/human","version":"2.9.4"}
|
||||
2022-08-31 18:30:05 [36mINFO: [39m Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
|
||||
2022-08-31 18:30:05 [36mINFO: [39m Toolchain: {"build":"0.7.11","esbuild":"0.15.6","typescript":"4.8.2","typedoc":"0.23.12","eslint":"8.23.0"}
|
||||
2022-08-31 18:30:05 [36mINFO: [39m Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
|
||||
2022-08-31 18:30:05 [35mSTATE:[39m Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]}
|
||||
2022-08-31 18:30:05 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":159,"outputBytes":608}
|
||||
2022-08-31 18:30:06 [35mSTATE:[39m Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":75,"inputBytes":655767,"outputBytes":308629}
|
||||
2022-08-31 18:30:06 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":167,"outputBytes":612}
|
||||
2022-08-31 18:30:06 [35mSTATE:[39m Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":75,"inputBytes":655771,"outputBytes":308633}
|
||||
2022-08-31 18:30:06 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":206,"outputBytes":664}
|
||||
2022-08-31 18:30:06 [35mSTATE:[39m Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":75,"inputBytes":655823,"outputBytes":308683}
|
||||
2022-08-31 18:30:06 [35mSTATE:[39m Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1125,"outputBytes":358}
|
||||
2022-08-31 18:30:06 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":1088,"outputBytes":583}
|
||||
2022-08-31 18:30:06 [35mSTATE:[39m Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":75,"inputBytes":655742,"outputBytes":307503}
|
||||
2022-08-31 18:30:06 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/custom","format":"esm","platform":"browser","input":"tfjs/tf-custom.ts","output":"dist/tfjs.esm.js","files":11,"inputBytes":1344,"outputBytes":2821914}
|
||||
2022-08-31 18:30:06 [35mSTATE:[39m Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":75,"inputBytes":3477073,"outputBytes":1687675}
|
||||
2022-08-31 18:30:06 [35mSTATE:[39m Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":75,"inputBytes":3477073,"outputBytes":3108312}
|
||||
2022-08-31 18:30:10 [35mSTATE:[39m Typings: {"input":"src/human.ts","output":"types/lib","files":30}
|
||||
2022-08-31 18:30:12 [35mSTATE:[39m TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":77,"generated":true}
|
||||
2022-08-31 18:30:12 [35mSTATE:[39m Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":6714,"outputBytes":3134}
|
||||
2022-08-31 18:30:12 [35mSTATE:[39m Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15488,"outputBytes":7788}
|
||||
2022-08-31 18:30:23 [35mSTATE:[39m Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":112,"errors":0,"warnings":0}
|
||||
2022-08-31 18:30:23 [35mSTATE:[39m ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
|
||||
2022-08-31 18:30:23 [35mSTATE:[39m Copy: {"input":"tfjs/tfjs.esm.d.ts"}
|
||||
2022-08-31 18:30:23 [36mINFO: [39m Done...
|
||||
2022-08-31 18:30:24 [35mSTATE:[39m API-Extractor: {"succeeeded":true,"errors":0,"warnings":198}
|
||||
2022-08-31 18:30:24 [35mSTATE:[39m Copy: {"input":"types/human.d.ts"}
|
||||
2022-08-31 18:30:24 [36mINFO: [39m Analyze models: {"folders":8,"result":"models/models.json"}
|
||||
2022-08-31 18:30:24 [35mSTATE:[39m Models {"folder":"./models","models":13}
|
||||
2022-08-31 18:30:24 [35mSTATE:[39m Models {"folder":"../human-models/models","models":42}
|
||||
2022-08-31 18:30:24 [35mSTATE:[39m Models {"folder":"../blazepose/model/","models":4}
|
||||
2022-08-31 18:30:24 [35mSTATE:[39m Models {"folder":"../anti-spoofing/model","models":1}
|
||||
2022-08-31 18:30:24 [35mSTATE:[39m Models {"folder":"../efficientpose/models","models":3}
|
||||
2022-08-31 18:30:24 [35mSTATE:[39m Models {"folder":"../insightface/models","models":5}
|
||||
2022-08-31 18:30:24 [35mSTATE:[39m Models {"folder":"../movenet/models","models":3}
|
||||
2022-08-31 18:30:24 [35mSTATE:[39m Models {"folder":"../nanodet/models","models":4}
|
||||
2022-08-31 18:30:24 [35mSTATE:[39m Models: {"count":57,"totalSize":383017442}
|
||||
2022-08-31 18:30:24 [36mINFO: [39m Human Build complete... {"logFile":"test/build.log"}
|
||||
|
|
|
@ -25,6 +25,6 @@
|
|||
<div id="events" class="events"></div>
|
||||
<div id="state" class="state"></div>
|
||||
<canvas id="canvas" class="canvas" width="256" height="256"></canvas>
|
||||
<script type="module" src="./browser.js"></script>
|
||||
<script type="module" src="./test-browser-esm.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -66,10 +66,7 @@ async function testDefault(title, testConfig = {}) {
|
|||
const t0 = human.now();
|
||||
let res;
|
||||
for (const model of Object.keys(human.models)) { // unload models
|
||||
if (human.models[model]) {
|
||||
// if (human.models[model].dispose) human.models[model].dispose();
|
||||
human.models[model] = null;
|
||||
}
|
||||
if (human.models[model]) human.models[model] = null;
|
||||
}
|
||||
human.reset();
|
||||
res = human.validate(testConfig); // validate
|
||||
|
@ -91,8 +88,6 @@ async function testDefault(title, testConfig = {}) {
|
|||
human.next(); // run interpolation
|
||||
const persons = res.persons; // run persons getter
|
||||
log(' summary', { persons: persons.length, face: res.face.length, body: res.body.length, hand: res.hand.length, object: res.object.length, gesture: res.gesture.length });
|
||||
// log(' memory', human.tf.memory());
|
||||
// log(' performance', human.performance);
|
||||
human.tf.dispose(input.tensor);
|
||||
log(` finished ${title}/${human.tf.getBackend()}`, { init: Math.round(t1 - t0), detect: Math.round(t2 - t1) });
|
||||
return res;
|
||||
|
@ -123,11 +118,7 @@ async function runBenchmark() {
|
|||
|
||||
async function main() {
|
||||
log('human tests');
|
||||
|
||||
// create instance
|
||||
human = new Human({ debug: true });
|
||||
|
||||
// explicit init
|
||||
await human.init();
|
||||
human.events.addEventListener('warmup', () => events('warmup'));
|
||||
human.events.addEventListener('image', () => events('image'));
|
||||
|
@ -139,7 +130,6 @@ async function main() {
|
|||
const env = JSON.parse(JSON.stringify(human.env));
|
||||
env.kernels = human.env.kernels.length;
|
||||
detailed('environment', env);
|
||||
// detailed('config', human.config);
|
||||
|
||||
for (const backend of backends) {
|
||||
human.config.backend = backend;
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Human Browser Tests</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, shrink-to-fit=yes">
|
||||
<meta name="keywords" content="Human">
|
||||
<meta name="application-name" content="Human">
|
||||
<meta name="description" content="Human: 3D Face Detection, Body Pose, Hand & Finger Tracking, Iris Tracking, Age & Gender Prediction, Emotion Prediction & Gesture Recognition; Author: Vladimir Mandic <https://github.com/vladmandic>">
|
||||
<meta name="msapplication-tooltip" content="Human: 3D Face Detection, Body Pose, Hand & Finger Tracking, Iris Tracking, Age & Gender Prediction, Emotion Prediction & Gesture Recognition; Author: Vladimir Mandic <https://github.com/vladmandic>">
|
||||
<link rel="shortcut icon" href="../../favicon.ico" type="image/x-icon">
|
||||
<link rel="apple-touch-icon" href="../../assets/icon.png">
|
||||
<style>
|
||||
@font-face { font-family: 'Lato'; font-display: swap; font-style: normal; font-weight: 100; src: local('Lato'), url('../../assets/lato-light.woff2') }
|
||||
html { font-family: 'Lato', 'Segoe UI'; font-size: 14px; font-variant: small-caps; }
|
||||
body { margin: 0; background: black; color: white; width: 100vw; }
|
||||
.canvas { position: fixed; bottom: 10px; right: 10px; width: 256px; height: 256px; z-index: 99; }
|
||||
.events { position: fixed; top: 10px; right: 10px; width: 12rem; height: 1.25rem; background-color: grey; padding: 8px; z-index: 99; }
|
||||
.state { position: fixed; top: 60px; right: 10px; width: 12rem; height: 1.25rem; background-color: grey; padding: 8px; z-index: 99; }
|
||||
.pre { line-height: 150%; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="log" class="pre"></pre>
|
||||
<div id="events" class="events"></div>
|
||||
<div id="state" class="state"></div>
|
||||
<canvas id="canvas" class="canvas" width="256" height="256"></canvas>
|
||||
<script src="../dist/human.js"></script>
|
||||
<script src="./test-browser-iife.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,117 @@
|
|||
/* global Human */
|
||||
|
||||
let human;
|
||||
|
||||
const backends = ['wasm', 'humangl', 'webgl', 'webgpu'];
|
||||
|
||||
const start = performance.now();
|
||||
|
||||
function str(long, ...msg) {
|
||||
if (!Array.isArray(msg)) return msg;
|
||||
let line = '';
|
||||
for (const entry of msg) {
|
||||
if (typeof entry === 'object') line += ' ' + JSON.stringify(entry, null, long ? 2 : 0).replace(/"/g, '').replace(/,/g, ', ').replace(/:/g, ': ');
|
||||
else line += ' ' + entry;
|
||||
}
|
||||
return line + '\n';
|
||||
}
|
||||
|
||||
let last = new Date();
|
||||
async function log(...msgs) {
|
||||
const dt = new Date();
|
||||
const ts = `${dt.getHours().toString().padStart(2, '0')}:${dt.getMinutes().toString().padStart(2, '0')}:${dt.getSeconds().toString().padStart(2, '0')}.${dt.getMilliseconds().toString().padStart(3, '0')}`;
|
||||
const elap = (dt - last).toString().padStart(5, '0');
|
||||
document.getElementById('log').innerHTML += ts + ' +' + elap + 'ms  ' + str(false, ...msgs);
|
||||
document.documentElement.scrollTop = document.documentElement.scrollHeight;
|
||||
console.log(ts, elap, ...msgs); // eslint-disable-line no-console
|
||||
last = dt;
|
||||
}
|
||||
|
||||
async function detailed(...msgs) {
|
||||
const dt = new Date();
|
||||
const ts = `${dt.getHours().toString().padStart(2, '0')}:${dt.getMinutes().toString().padStart(2, '0')}:${dt.getSeconds().toString().padStart(2, '0')}.${dt.getMilliseconds().toString().padStart(3, '0')}`;
|
||||
const elap = (dt - last).toString().padStart(5, '0');
|
||||
document.getElementById('log').innerHTML += ts + ' +' + elap + 'ms  ' + str(true, ...msgs);
|
||||
document.documentElement.scrollTop = document.documentElement.scrollHeight;
|
||||
console.log(ts, elap, ...msgs); // eslint-disable-line no-console
|
||||
last = dt;
|
||||
}
|
||||
|
||||
async function image(url) {
|
||||
const el = document.createElement('img');
|
||||
el.id = 'image';
|
||||
const loaded = new Promise((resolve) => { el.onload = () => resolve(true); });
|
||||
el.src = url;
|
||||
await loaded;
|
||||
return el;
|
||||
}
|
||||
|
||||
function draw(canvas = null) {
|
||||
const c = document.getElementById('canvas');
|
||||
const ctx = c.getContext('2d');
|
||||
if (canvas) ctx.drawImage(canvas, 0, 0, c.width, c.height);
|
||||
else ctx.clearRect(0, 0, c.width, c.height);
|
||||
}
|
||||
|
||||
async function events(event) {
|
||||
document.getElementById('events').innerText = `${Math.round(performance.now() - start)}ms Event: ${event}`;
|
||||
}
|
||||
|
||||
async function testDefault(title, testConfig = {}) {
|
||||
const t0 = human.now();
|
||||
let res;
|
||||
for (const model of Object.keys(human.models)) { // unload models
|
||||
if (human.models[model]) human.models[model] = null;
|
||||
}
|
||||
human.reset();
|
||||
res = human.validate(testConfig); // validate
|
||||
if (res && res.length > 0) log(' invalid configuration', res);
|
||||
log(`test ${title}/${human.tf.getBackend()}`, human.config);
|
||||
await human.load();
|
||||
const models = Object.keys(human.models).map((model) => ({ name: model, loaded: (human.models[model] !== null) }));
|
||||
log(' models', models);
|
||||
const ops = await human.check();
|
||||
if (ops && ops.length > 0) log(' missing ops', ops);
|
||||
const img = await image('../../samples/in/ai-body.jpg');
|
||||
const input = await human.image(img); // process image
|
||||
draw(input.canvas);
|
||||
res = await human.warmup({ warmup: 'face' }); // warmup
|
||||
draw(res.canvas);
|
||||
const t1 = human.now();
|
||||
res = await human.detect(input.tensor, testConfig); // run detect
|
||||
const t2 = human.now();
|
||||
human.next(); // run interpolation
|
||||
const persons = res.persons; // run persons getter
|
||||
log(' summary', { persons: persons.length, face: res.face.length, body: res.body.length, hand: res.hand.length, object: res.object.length, gesture: res.gesture.length });
|
||||
human.tf.dispose(input.tensor);
|
||||
log(` finished ${title}/${human.tf.getBackend()}`, { init: Math.round(t1 - t0), detect: Math.round(t2 - t1) });
|
||||
return res;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
log('human tests');
|
||||
human = new Human.Human({ debug: true });
|
||||
await human.init();
|
||||
human.events.addEventListener('warmup', () => events('warmup'));
|
||||
human.events.addEventListener('image', () => events('image'));
|
||||
human.events.addEventListener('detect', () => events('detect'));
|
||||
const timer = setInterval(() => { document.getElementById('state').innerText = `State: ${human.state}`; }, 10);
|
||||
log('version', human.version);
|
||||
log('tfjs', human.tf.version.tfjs);
|
||||
const env = JSON.parse(JSON.stringify(human.env));
|
||||
env.kernels = human.env.kernels.length;
|
||||
detailed('environment', env);
|
||||
for (const backend of backends) {
|
||||
human.config.backend = backend;
|
||||
await human.init(); // init
|
||||
if (human.tf.getBackend() !== backend) {
|
||||
log('desired', backend, 'detected', human.tf.getBackend());
|
||||
continue; // wrong backend
|
||||
}
|
||||
await testDefault('default', { debug: true });
|
||||
}
|
||||
log('tests complete');
|
||||
clearInterval(timer);
|
||||
}
|
||||
|
||||
main();
|
Loading…
Reference in New Issue