mirror of https://github.com/vladmandic/human
add benchmark info
parent
e54304e61a
commit
bb8785b3d4
1
TODO.md
1
TODO.md
|
@ -6,6 +6,7 @@ WebGL shader optimizations for faster load and initial detection
|
|||
|
||||
- Implement WebGL uniforms for shaders: <https://github.com/tensorflow/tfjs/issues/5205>
|
||||
- Fix shader packing: <https://github.com/tensorflow/tfjs/issues/5343>
|
||||
- Event emitters
|
||||
|
||||
<br>
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Human</title>
|
||||
<meta name="viewport" content="width=device-width" id="viewport">
|
||||
<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>">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<link rel="manifest" href="../manifest.webmanifest">
|
||||
<link rel="shortcut icon" href="../../favicon.ico" type="image/x-icon">
|
||||
<link rel="apple-touch-icon" href="../../assets/icon.png">
|
||||
<script type="module" src="browser.js"></script>
|
||||
<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: 16px; font-variant: small-caps; }
|
||||
body { margin: 0; background: black; color: white; overflow-x: hidden; width: 100vw; height: 100vh; }
|
||||
body::-webkit-scrollbar { display: none; }
|
||||
.status { position: absolute; width: 100vw; bottom: 10%; text-align: center; font-size: 3rem; font-weight: 100; text-shadow: 2px 2px #303030; }
|
||||
.log { position: absolute; bottom: 0; margin: 0.4rem 0.4rem 0 0.4rem; font-size: 0.9rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="status" class="status"></div>
|
||||
<img id="image" src="../../samples/groups/group1.jpg" style="display: none"></img>
|
||||
<div id="log" class="log"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,51 @@
|
|||
// import * as tf from '../../assets/tf.es2017.js';
|
||||
// import '../../assets/tf-backend-webgpu.es2017.js';
|
||||
import Human from '../../dist/human.esm.js';
|
||||
|
||||
const loop = 20;
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
const log = (...msg) => console.log(...msg);
|
||||
|
||||
const myConfig = {
|
||||
backend: 'humangl',
|
||||
modelBasePath: 'https://vladmandic.github.io/human/models',
|
||||
wasmPath: 'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@3.9.0/dist/',
|
||||
debug: true,
|
||||
async: true,
|
||||
cacheSensitivity: 0,
|
||||
filter: { enabled: false },
|
||||
face: {
|
||||
enabled: true,
|
||||
detector: { enabled: true, rotation: false },
|
||||
mesh: { enabled: true },
|
||||
iris: { enabled: true },
|
||||
description: { enabled: true },
|
||||
emotion: { enabled: false },
|
||||
},
|
||||
hand: { enabled: true, rotation: false },
|
||||
body: { enabled: true },
|
||||
object: { enabled: false },
|
||||
};
|
||||
|
||||
async function main() {
|
||||
const human = new Human(myConfig);
|
||||
await human.tf.ready();
|
||||
log('Human:', human.version);
|
||||
await human.load();
|
||||
const loaded = Object.keys(human.models).filter((a) => human.models[a]);
|
||||
log('Loaded:', loaded);
|
||||
log('Memory state:', human.tf.engine().memory());
|
||||
const element = document.getElementById('image');
|
||||
const processed = await human.image(element);
|
||||
const t0 = performance.now();
|
||||
await human.detect(processed.tensor, myConfig);
|
||||
const t1 = performance.now();
|
||||
log('Backend:', human.tf.getBackend());
|
||||
log('Warmup:', Math.round(t1 - t0));
|
||||
for (let i = 0; i < loop; i++) await human.detect(processed.tensor, myConfig);
|
||||
const t2 = performance.now();
|
||||
log('Average:', Math.round((t2 - t1) / loop));
|
||||
}
|
||||
|
||||
main();
|
|
@ -0,0 +1,71 @@
|
|||
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
|
||||
const tf = require('@tensorflow/tfjs-node-gpu');
|
||||
const log = require('@vladmandic/pilogger');
|
||||
const canvasJS = require('canvas');
|
||||
const Human = require('../../dist/human.node-gpu.js').default;
|
||||
|
||||
const input = 'samples/groups/group1.jpg';
|
||||
const loop = 20;
|
||||
|
||||
const myConfig = {
|
||||
backend: 'tensorflow',
|
||||
modelBasePath: 'https://vladmandic.github.io/human/models',
|
||||
wasmPath: 'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@3.9.0/dist/',
|
||||
debug: true,
|
||||
async: true,
|
||||
cacheSensitivity: 0,
|
||||
filter: { enabled: false },
|
||||
face: {
|
||||
enabled: true,
|
||||
detector: { enabled: true, rotation: false },
|
||||
mesh: { enabled: true },
|
||||
iris: { enabled: true },
|
||||
description: { enabled: true },
|
||||
emotion: { enabled: true },
|
||||
},
|
||||
hand: {
|
||||
enabled: true,
|
||||
},
|
||||
body: { enabled: true },
|
||||
object: { enabled: false },
|
||||
};
|
||||
|
||||
async function getImage(human) {
|
||||
const img = await canvasJS.loadImage(input);
|
||||
const canvas = canvasJS.createCanvas(img.width, img.height);
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0, img.width, img.height);
|
||||
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
const res = human.tf.tidy(() => {
|
||||
const tensor = human.tf.tensor(Array.from(imageData.data), [canvas.height, canvas.width, 4], 'int32'); // create rgba image tensor from flat array
|
||||
const channels = human.tf.split(tensor, 4, 2); // split rgba to channels
|
||||
const rgb = human.tf.stack([channels[0], channels[1], channels[2]], 2); // stack channels back to rgb
|
||||
const reshape = human.tf.reshape(rgb, [1, canvas.height, canvas.width, 3]); // move extra dim from the end of tensor and use it as batch number instead
|
||||
return reshape;
|
||||
});
|
||||
log.info('Image:', input, res.shape);
|
||||
return res;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
log.header();
|
||||
const human = new Human(myConfig);
|
||||
await human.tf.ready();
|
||||
log.info('Human:', human.version);
|
||||
await human.load();
|
||||
const loaded = Object.keys(human.models).filter((a) => human.models[a]);
|
||||
log.info('Loaded:', loaded);
|
||||
log.info('Memory state:', human.tf.engine().memory());
|
||||
const tensor = await getImage(human);
|
||||
log.state('Processing:', tensor['shape']);
|
||||
const t0 = performance.now();
|
||||
await human.detect(tensor, myConfig);
|
||||
const t1 = performance.now();
|
||||
log.state('Backend:', human.tf.getBackend());
|
||||
log.data('Warmup:', Math.round(t1 - t0));
|
||||
for (let i = 0; i < loop; i++) await human.detect(tensor, myConfig);
|
||||
const t2 = performance.now();
|
||||
log.data('Average:', Math.round((t2 - t1) / loop));
|
||||
}
|
||||
|
||||
main();
|
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
File diff suppressed because one or more lines are too long
|
@ -11771,7 +11771,7 @@ var version = "2.1.5";
|
|||
|
||||
// src/human.ts
|
||||
var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _lastCacheDiff, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode;
|
||||
var _Human = class {
|
||||
var Human = class {
|
||||
constructor(userConfig) {
|
||||
__privateAdd(this, _numTensors, void 0);
|
||||
__privateAdd(this, _analyzeMemoryLeaks, void 0);
|
||||
|
@ -11973,7 +11973,7 @@ var _Human = class {
|
|||
}
|
||||
return res;
|
||||
});
|
||||
_Human.version = version;
|
||||
this.version = version;
|
||||
Object.defineProperty(this, "version", { value: version });
|
||||
config.wasmPath = `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf21.version_core}/dist/`;
|
||||
this.config = mergeDeep(config, userConfig || {});
|
||||
|
@ -12028,7 +12028,7 @@ var _Human = class {
|
|||
this.config = mergeDeep(this.config, userConfig);
|
||||
if (__privateGet(this, _firstRun)) {
|
||||
if (this.config.debug)
|
||||
log(`version: ${_Human.version}`);
|
||||
log(`version: ${this.version}`);
|
||||
if (this.config.debug)
|
||||
log(`tfjs version: ${this.tf.version_core}`);
|
||||
if (this.config.debug)
|
||||
|
@ -12230,7 +12230,6 @@ var _Human = class {
|
|||
return res;
|
||||
}
|
||||
};
|
||||
var Human = _Human;
|
||||
_numTensors = new WeakMap();
|
||||
_analyzeMemoryLeaks = new WeakMap();
|
||||
_checkSanity = new WeakMap();
|
||||
|
|
|
@ -11772,7 +11772,7 @@ var version = "2.1.5";
|
|||
|
||||
// src/human.ts
|
||||
var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _lastCacheDiff, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode;
|
||||
var _Human = class {
|
||||
var Human = class {
|
||||
constructor(userConfig) {
|
||||
__privateAdd(this, _numTensors, void 0);
|
||||
__privateAdd(this, _analyzeMemoryLeaks, void 0);
|
||||
|
@ -11974,7 +11974,7 @@ var _Human = class {
|
|||
}
|
||||
return res;
|
||||
});
|
||||
_Human.version = version;
|
||||
this.version = version;
|
||||
Object.defineProperty(this, "version", { value: version });
|
||||
config.wasmPath = `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf21.version_core}/dist/`;
|
||||
this.config = mergeDeep(config, userConfig || {});
|
||||
|
@ -12029,7 +12029,7 @@ var _Human = class {
|
|||
this.config = mergeDeep(this.config, userConfig);
|
||||
if (__privateGet(this, _firstRun)) {
|
||||
if (this.config.debug)
|
||||
log(`version: ${_Human.version}`);
|
||||
log(`version: ${this.version}`);
|
||||
if (this.config.debug)
|
||||
log(`tfjs version: ${this.tf.version_core}`);
|
||||
if (this.config.debug)
|
||||
|
@ -12231,7 +12231,6 @@ var _Human = class {
|
|||
return res;
|
||||
}
|
||||
};
|
||||
var Human = _Human;
|
||||
_numTensors = new WeakMap();
|
||||
_analyzeMemoryLeaks = new WeakMap();
|
||||
_checkSanity = new WeakMap();
|
||||
|
|
|
@ -11771,7 +11771,7 @@ var version = "2.1.5";
|
|||
|
||||
// src/human.ts
|
||||
var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _lastCacheDiff, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode;
|
||||
var _Human = class {
|
||||
var Human = class {
|
||||
constructor(userConfig) {
|
||||
__privateAdd(this, _numTensors, void 0);
|
||||
__privateAdd(this, _analyzeMemoryLeaks, void 0);
|
||||
|
@ -11973,7 +11973,7 @@ var _Human = class {
|
|||
}
|
||||
return res;
|
||||
});
|
||||
_Human.version = version;
|
||||
this.version = version;
|
||||
Object.defineProperty(this, "version", { value: version });
|
||||
config.wasmPath = `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf21.version_core}/dist/`;
|
||||
this.config = mergeDeep(config, userConfig || {});
|
||||
|
@ -12028,7 +12028,7 @@ var _Human = class {
|
|||
this.config = mergeDeep(this.config, userConfig);
|
||||
if (__privateGet(this, _firstRun)) {
|
||||
if (this.config.debug)
|
||||
log(`version: ${_Human.version}`);
|
||||
log(`version: ${this.version}`);
|
||||
if (this.config.debug)
|
||||
log(`tfjs version: ${this.tf.version_core}`);
|
||||
if (this.config.debug)
|
||||
|
@ -12230,7 +12230,6 @@ var _Human = class {
|
|||
return res;
|
||||
}
|
||||
};
|
||||
var Human = _Human;
|
||||
_numTensors = new WeakMap();
|
||||
_analyzeMemoryLeaks = new WeakMap();
|
||||
_checkSanity = new WeakMap();
|
||||
|
|
|
@ -2173,9 +2173,9 @@ var require_seedrandom4 = __commonJS({
|
|||
}
|
||||
});
|
||||
|
||||
// (disabled):node_modules/.pnpm/string_decoder@1.3.0/node_modules/string_decoder/lib/string_decoder.js
|
||||
// (disabled):node_modules/.pnpm/string_decoder@1.1.1/node_modules/string_decoder/lib/string_decoder.js
|
||||
var require_string_decoder = __commonJS({
|
||||
"(disabled):node_modules/.pnpm/string_decoder@1.3.0/node_modules/string_decoder/lib/string_decoder.js"() {
|
||||
"(disabled):node_modules/.pnpm/string_decoder@1.1.1/node_modules/string_decoder/lib/string_decoder.js"() {
|
||||
}
|
||||
});
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -73,7 +73,7 @@
|
|||
"canvas": "^2.8.0",
|
||||
"chokidar": "^3.5.2",
|
||||
"dayjs": "^1.10.6",
|
||||
"esbuild": "^0.12.24",
|
||||
"esbuild": "^0.12.25",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-airbnb-base": "^14.2.1",
|
||||
"eslint-plugin-import": "^2.24.2",
|
||||
|
@ -83,7 +83,7 @@
|
|||
"node-fetch": "^3.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"seedrandom": "^3.0.5",
|
||||
"simple-git": "^2.45.0",
|
||||
"simple-git": "^2.45.1",
|
||||
"tslib": "^2.3.1",
|
||||
"typedoc": "0.21.9",
|
||||
"typescript": "4.4.2"
|
||||
|
|
|
@ -62,7 +62,7 @@ export type TensorFlow = typeof tf;
|
|||
*/
|
||||
export class Human {
|
||||
/** Current version of Human library in *semver* format */
|
||||
static version: string;
|
||||
version: string;
|
||||
/** Current configuration
|
||||
* - Details: {@link Config}
|
||||
*/
|
||||
|
@ -148,7 +148,7 @@ export class Human {
|
|||
* @param userConfig: {@link Config}
|
||||
*/
|
||||
constructor(userConfig?: Config | Record<string, unknown>) {
|
||||
Human.version = app.version; // expose version property on instance of class
|
||||
this.version = app.version; // expose version property on instance of class
|
||||
Object.defineProperty(this, 'version', { value: app.version }); // expose version property directly on class itself
|
||||
defaults.wasmPath = `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf.version_core}/dist/`;
|
||||
this.config = mergeDeep(defaults, userConfig || {});
|
||||
|
@ -270,7 +270,7 @@ export class Human {
|
|||
if (userConfig) this.config = mergeDeep(this.config, userConfig) as Config;
|
||||
|
||||
if (this.#firstRun) { // print version info on first run and check for correct backend setup
|
||||
if (this.config.debug) log(`version: ${Human.version}`);
|
||||
if (this.config.debug) log(`version: ${this.version}`);
|
||||
if (this.config.debug) log(`tfjs version: ${this.tf.version_core}`);
|
||||
if (this.config.debug) log('platform:', this.sysinfo.platform);
|
||||
if (this.config.debug) log('agent:', this.sysinfo.agent);
|
||||
|
|
2
wiki
2
wiki
|
@ -1 +1 @@
|
|||
Subproject commit 7f55fd1c8aea22f33a767da840147b15aeeed034
|
||||
Subproject commit 82ce7a69656a11fa4cd5c5bea447cd1a2797b903
|
Loading…
Reference in New Issue