mirror of https://github.com/vladmandic/human
added multi backend support
parent
9ae61216fb
commit
b4cccc3c76
58
README.md
58
README.md
|
@ -1,8 +1,10 @@
|
|||
# Human: 3D Face Detection, Body Pose, Hand & Finger Tracking, Iris Tracking, Age & Gender Prediction & Emotion Prediction
|
||||
# Human Library
|
||||
|
||||
## 3D Face Detection, Body Pose, Hand & Finger Tracking, Iris Tracking, Age & Gender Prediction & Emotion Prediction
|
||||
|
||||
- [**Documentation**](https://github.com/vladmandic/human#readme)
|
||||
- [**Code Repository**](https://github.com/vladmandic/human)
|
||||
- [**Package**](https://www.npmjs.com/package/@vladmandic/human)
|
||||
- [**NPM Package**](https://www.npmjs.com/package/@vladmandic/human)
|
||||
- [**Issues Tracker**](https://github.com/vladmandic/human/issues)
|
||||
- [**Live Demo**](https://vladmandic.github.io/human/demo/demo-esm.html)
|
||||
|
||||
|
@ -30,6 +32,25 @@ Compatible with Browser, WebWorker and NodeJS execution!
|
|||
|
||||
There are multiple ways to use `Human` library, pick one that suits you:
|
||||
|
||||
### Included
|
||||
|
||||
- `dist/human.js`: IIFE format minified bundle with TFJS for Browsers
|
||||
- `dist/human.esm.js`: ESM format minified bundle with TFJS for Browsers
|
||||
- `dist/human.esm-nobundle.js`: ESM format non-minified bundle without TFJS for Browsers
|
||||
- `dist/human.cjs`: CommonJS format minified bundle with TFJS for NodeJS
|
||||
- `dist/human-nobundle.cjs`: CommonJS format non-minified bundle without TFJS for NodeJS
|
||||
|
||||
All versions include `sourcemap`
|
||||
|
||||
Defaults:
|
||||
```json
|
||||
{
|
||||
"main": "dist/human.cjs",
|
||||
"module": "dist/human.esm.js",
|
||||
"browser": "dist/human.esm.js",
|
||||
}
|
||||
```
|
||||
|
||||
### 1. [IIFE](https://developer.mozilla.org/en-US/docs/Glossary/IIFE) script
|
||||
|
||||
*Simplest way for usage within Browser*
|
||||
|
@ -43,8 +64,6 @@ Simply download `dist/human.js`, include it in your `HTML` file & it's ready to
|
|||
IIFE script auto-registers global namespace `human` within global `Window` object
|
||||
This way you can also use `Human` library within embbedded `<script>` tag within your `html` page for all-in-one approach
|
||||
|
||||
IIFE script is distributed in minified form with attached sourcemap
|
||||
|
||||
### 2. [ESM](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) module
|
||||
|
||||
*Recommended for usage within `Browser`*
|
||||
|
@ -53,18 +72,25 @@ IIFE script is distributed in minified form with attached sourcemap
|
|||
|
||||
If you're using bundler *(such as rollup, webpack, esbuild)* to package your client application, you can import ESM version of `Human` library which supports full tree shaking
|
||||
|
||||
Install with:
|
||||
```shell
|
||||
npm install @vladmandic/human
|
||||
```
|
||||
```js
|
||||
import human from '@vladmandic/human'; // points to @vladmandic/human/dist/human.esm.js
|
||||
```
|
||||
|
||||
Or if you prefer to package your version of `tfjs`, you can use `nobundle` version
|
||||
|
||||
Install with:
|
||||
```shell
|
||||
npm install @vladmandic/human @tensorflow/tfjs-node
|
||||
```
|
||||
```js
|
||||
import tf from '@tensorflow/tfjs'
|
||||
import human from '@vladmandic/human/dist/human.nobundle.js'; // same functionality as default import, but without tfjs bundled
|
||||
import human from '@vladmandic/human/dist/human.esm-nobundle.js'; // same functionality as default import, but without tfjs bundled
|
||||
```
|
||||
|
||||
|
||||
#### 2.2 Using Script Module
|
||||
You could use same syntax within your main `JS` file if it's imported with `<script type="module">`
|
||||
|
||||
|
@ -74,11 +100,10 @@ You could use same syntax within your main `JS` file if it's imported with `<scr
|
|||
and then in your `index.js`
|
||||
|
||||
```js
|
||||
import human from 'dist/human.esm.js';
|
||||
import * as tf from `https://cdnjs.cloudflare.com/ajax/libs/tensorflow/2.6.0/tf.es2017.min.js`; // load tfjs directly from CDN link
|
||||
import human from 'dist/human.esm.js'; // for direct import must use path to module, not package name
|
||||
```
|
||||
|
||||
ESM script is distributed in minified form with attached sourcemap
|
||||
|
||||
### 3. [NPM](https://www.npmjs.com/) module
|
||||
|
||||
*Recommended for `NodeJS` projects that will execute in the backend*
|
||||
|
@ -88,13 +113,22 @@ You also need to install and include `tfjs-node` or `tfjs-node-gpu` in your proj
|
|||
|
||||
Install with:
|
||||
```shell
|
||||
npm install @tensorflow/tfjs-node @vladmandic/human
|
||||
npm install @vladmandic/human
|
||||
```
|
||||
And then use with:
|
||||
```js
|
||||
const tf = require('@tensorflow/tfjs-node');
|
||||
const human = require('@vladmandic/human'); // points to @vladmandic/human/dist/human.node.js
|
||||
const human = require('@vladmandic/human'); // points to @vladmandic/human/dist/human.cjs
|
||||
```
|
||||
or
|
||||
```shell
|
||||
npm install @vladmandic/human @tensorflow/tfjs-node
|
||||
```
|
||||
And then use with:
|
||||
```js
|
||||
const tf = require('@tensorflow/tfjs-node'); // can also use '@tensorflow/tfjs-node-gpu' if you have environment with CUDA extensions
|
||||
const human = require('@vladmandic/human/dist/human-nobundle.cjs');
|
||||
```
|
||||
|
||||
|
||||
Since NodeJS projects load `weights` from local filesystem instead of using `http` calls, you must modify default configuration to include correct paths with `file://` prefix
|
||||
For example:
|
||||
|
|
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 it is too large
Load Diff
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,5 +1,7 @@
|
|||
<head>
|
||||
<script src="https://cdn.jsdelivr.net/npm/quicksettings"></script>
|
||||
<script src="../assets/quicksettings.js"></script>
|
||||
<script src="../assets/tf.min.js"></script>
|
||||
<script src="../assets/tf-backend-wasm.min.js"></script>
|
||||
<script src="./demo-esm.js" type="module"></script>
|
||||
</head>
|
||||
<body style="margin: 0; background: black; color: white; font-family: 'Segoe UI'; font-variant: small-caps">
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/* global QuickSettings */
|
||||
/* global tf, QuickSettings */
|
||||
|
||||
import human from '../dist/human.esm.js';
|
||||
|
||||
const ui = {
|
||||
backend: 'wasm',
|
||||
baseColor: 'rgba(255, 200, 255, 0.3)',
|
||||
baseLabel: 'rgba(255, 200, 255, 0.8)',
|
||||
baseFont: 'small-caps 1.2rem "Segoe UI"',
|
||||
|
@ -34,6 +35,15 @@ function str(...msg) {
|
|||
return line;
|
||||
}
|
||||
|
||||
async function setupTF() {
|
||||
if (ui.backend === 'wasm') {
|
||||
tf.env().set('WASM_HAS_SIMD_SUPPORT', false);
|
||||
tf.env().set('WASM_HAS_MULTITHREAD_SUPPORT', true);
|
||||
}
|
||||
await human.tf.setBackend(ui.backend);
|
||||
await human.tf.ready();
|
||||
}
|
||||
|
||||
async function drawFace(result, canvas) {
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.strokeStyle = ui.baseColor;
|
||||
|
@ -217,9 +227,10 @@ async function runHumanDetect(input, canvas) {
|
|||
drawHand(result.hand, canvas);
|
||||
// update log
|
||||
const engine = await human.tf.engine();
|
||||
const memory = `Memory: ${engine.state.numBytes.toLocaleString()} bytes ${engine.state.numDataBuffers.toLocaleString()} buffers ${engine.state.numTensors.toLocaleString()} tensors`;
|
||||
const memory = `${engine.state.numBytes.toLocaleString()} bytes ${engine.state.numDataBuffers.toLocaleString()} buffers ${engine.state.numTensors.toLocaleString()} tensors`;
|
||||
const gpu = engine.backendInstance.numBytesInGPU ? `GPU: ${engine.backendInstance.numBytesInGPU.toLocaleString()} bytes` : '';
|
||||
log.innerText = `
|
||||
TFJS Version: ${human.tf.version_core} | ${memory} | GPU: ${engine.backendInstance.numBytesInGPU.toLocaleString()} bytes
|
||||
TFJS Version: ${human.tf.version_core} | Backend: ${human.tf.getBackend()} | Memory: ${memory} ${gpu}
|
||||
Performance: ${str(result.performance)} | Object size: ${(str(result)).length.toLocaleString()} bytes
|
||||
`;
|
||||
// rinse & repeate
|
||||
|
@ -255,6 +266,11 @@ function setupGUI() {
|
|||
}
|
||||
runHumanDetect(video, canvas);
|
||||
});
|
||||
settings.addDropDown('Backend', ['webgl', 'wasm', 'cpu'], (val) => {
|
||||
ui.backend = val.value;
|
||||
setupTF();
|
||||
});
|
||||
settings.addHTML('title', 'Enabled Models'); settings.hideTitle('title');
|
||||
settings.addBoolean('Face Detect', config.face.enabled, (val) => config.face.enabled = val);
|
||||
settings.addBoolean('Face Mesh', config.face.mesh.enabled, (val) => config.face.mesh.enabled = val);
|
||||
settings.addBoolean('Face Iris', config.face.iris.enabled, (val) => config.face.iris.enabled = val);
|
||||
|
@ -263,7 +279,7 @@ function setupGUI() {
|
|||
settings.addBoolean('Face Emotion', config.face.emotion.enabled, (val) => config.face.emotion.enabled = val);
|
||||
settings.addBoolean('Body Pose', config.body.enabled, (val) => config.body.enabled = val);
|
||||
settings.addBoolean('Hand Pose', config.hand.enabled, (val) => config.hand.enabled = val);
|
||||
settings.addHTML('line3', '<hr>'); settings.hideTitle('line3');
|
||||
settings.addHTML('title', 'Model Parameters'); settings.hideTitle('title');
|
||||
settings.addRange('Max Objects', 1, 20, 5, 1, (val) => {
|
||||
config.face.detector.maxFaces = parseInt(val);
|
||||
config.body.maxDetections = parseInt(val);
|
||||
|
@ -288,7 +304,7 @@ function setupGUI() {
|
|||
config.face.detector.iouThreshold = parseFloat(val);
|
||||
config.hand.iouThreshold = parseFloat(val);
|
||||
});
|
||||
settings.addHTML('line1', '<hr>'); settings.hideTitle('line1');
|
||||
settings.addHTML('title', 'UI Options'); settings.hideTitle('title');
|
||||
settings.addBoolean('Draw Boxes', true);
|
||||
settings.addBoolean('Draw Points', true);
|
||||
settings.addBoolean('Draw Polygons', true);
|
||||
|
@ -342,8 +358,7 @@ async function setupImage() {
|
|||
|
||||
async function main() {
|
||||
// initialize tensorflow
|
||||
await human.tf.setBackend('webgl');
|
||||
await human.tf.ready();
|
||||
await setupTF();
|
||||
// setup ui control panel
|
||||
await setupGUI();
|
||||
// setup webcam
|
||||
|
|
|
@ -5236,4 +5236,4 @@ exports.ssrnet = ssrnet;
|
|||
exports.posenet = posenet;
|
||||
exports.handpose = handpose;
|
||||
exports.tf = tf;
|
||||
//# sourceMappingURL=human.node.js.map
|
||||
//# sourceMappingURL=human-nobundle.cjs.map
|
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
13
package.json
13
package.json
|
@ -3,9 +3,9 @@
|
|||
"version": "0.3.1",
|
||||
"description": "human: 3D Face Detection, Iris Tracking and Age & Gender Prediction",
|
||||
"sideEffects": false,
|
||||
"main": "dist/human.node.js",
|
||||
"main": "dist/human.cjs",
|
||||
"module": "dist/human.esm.js",
|
||||
"browser": "dist/human.esmjs",
|
||||
"browser": "dist/human.esm.js",
|
||||
"author": "Vladimir Mandic <mandic00@live.com>",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vladmandic/human/issues"
|
||||
|
@ -36,11 +36,12 @@
|
|||
"scripts": {
|
||||
"start": "node --trace-warnings --trace-uncaught --no-deprecation demo/demo-node.js",
|
||||
"lint": "eslint src/*.js demo/*.js",
|
||||
"build": "rimraf dist/ && npm run build-iife && npm run build-esm && npm run build-nobundle && npm run build-node && ls -l dist/",
|
||||
"build-iife": "esbuild --bundle --platform=browser --sourcemap --target=esnext --format=iife --minify --external:fs --global-name=human --outfile=dist/human.js src/index.js",
|
||||
"build-esm": "esbuild --bundle --platform=browser --sourcemap --target=esnext --format=esm --external:fs --outfile=dist/human.esm.js src/index.js",
|
||||
"build-nobundle": "esbuild --bundle --platform=browser --sourcemap --target=esnext --format=esm --minify --external:@tensorflow --external:fs --outfile=dist/human.nobundle.js src/index.js",
|
||||
"build-node": "esbuild --bundle --platform=node --sourcemap --target=esnext --format=cjs --external:@tensorflow --outfile=dist/human.node.js src/index.js",
|
||||
"build-esm-bundle": "esbuild --bundle --platform=browser --sourcemap --target=esnext --format=esm --external:fs --outfile=dist/human.esm.js src/index.js",
|
||||
"build-esm-nobundle": "esbuild --bundle --platform=browser --sourcemap --target=esnext --format=esm --minify --external:@tensorflow --external:fs --outfile=dist/human.esm-nobundle.js src/index.js",
|
||||
"build-node-bundle": "esbuild --bundle --platform=node --sourcemap --target=esnext --format=cjs --minify --outfile=dist/human.cjs src/index.js",
|
||||
"build-node-nobundle": "esbuild --bundle --platform=node --sourcemap --target=esnext --format=cjs --external:@tensorflow --outfile=dist/human-nobundle.cjs src/index.js",
|
||||
"build": "rimraf dist/* && npm run build-iife && npm run build-esm-bundle && npm run build-esm-nobundle && npm run build-node-bundle && npm run build-node-nobundle && ls -l dist/",
|
||||
"update": "npm update --depth 20 && npm dedupe && npm prune && npm audit"
|
||||
},
|
||||
"keywords": [
|
||||
|
|
Loading…
Reference in New Issue