reorganize demos

pull/134/head
Vladimir Mandic 2021-06-14 08:16:10 -04:00
parent a68eec18f3
commit 1bb15e5096
15 changed files with 62 additions and 55 deletions

View File

@ -9,7 +9,7 @@ Repository: **<git+https://github.com/vladmandic/human.git>**
## Changelog ## Changelog
### **HEAD -> main** 2021/06/09 mandic00@live.com ### **HEAD -> main** 2021/06/11 mandic00@live.com
- add body segmentation sample - add body segmentation sample

View File

@ -41,8 +41,8 @@ Check out [**Live Demo**](https://vladmandic.github.io/human/demo/index.html) ap
## Demos ## Demos
- [**Main Application**](https://vladmandic.github.io/human/demo/index.html) - [**Main Application**](https://vladmandic.github.io/human/demo/index.html)
- [**Face Extraction, Description, Identification and Matching**](https://vladmandic.github.io/human/demo/facematch.html) - [**Face Extraction, Description, Identification and Matching**](https://vladmandic.github.io/human/demo/facematch/index.html)
- [**Face Extraction and 3D Rendering**](https://vladmandic.github.io/human/demo/face3d.html) - [**Face Extraction and 3D Rendering**](https://vladmandic.github.io/human/demo/face3d/index.html)
- [**Details on Demo Applications**](https://github.com/vladmandic/human/wiki/Demos) - [**Details on Demo Applications**](https://github.com/vladmandic/human/wiki/Demos)
## Project pages ## Project pages
@ -134,14 +134,14 @@ All options as presented in the demo application...
Extracts all faces from provided input images, Extracts all faces from provided input images,
sorts them by similarity to selected face sorts them by similarity to selected face
and optionally matches detected face with database of known people to guess their names and optionally matches detected face with database of known people to guess their names
> [demo/facematch.html](demo/facematch.html) > [demo/facematch](demo/facematch/index.html)
![Face Matching](assets/screenshot-facematch.jpg) ![Face Matching](assets/screenshot-facematch.jpg)
<br> <br>
**Face3D OpenGL Rendering:** **Face3D OpenGL Rendering:**
> [demo/face3d.html](demo/face3d.html) > [demo/face3d](demo/face3d/index.html)
![Face Matching](assets/screenshot-face3d.jpg) ![Face Matching](assets/screenshot-face3d.jpg)

View File

@ -6,15 +6,17 @@
* Demo for face mesh detection and projection as 3D object using Three.js * Demo for face mesh detection and projection as 3D object using Three.js
*/ */
import { DoubleSide, Mesh, MeshBasicMaterial, OrthographicCamera, Scene, sRGBEncoding, VideoTexture, WebGLRenderer, BufferGeometry, BufferAttribute } from './helpers/three.js'; import { DoubleSide, Mesh, MeshBasicMaterial, OrthographicCamera, Scene, sRGBEncoding, VideoTexture, WebGLRenderer, BufferGeometry, BufferAttribute } from '../helpers/three.js';
import { OrbitControls } from './helpers/three-orbitControls.js'; import { OrbitControls } from '../helpers/three-orbitControls.js';
import Human from '../dist/human.esm.js'; // equivalent of @vladmandic/human import Human from '../../dist/human.esm.js'; // equivalent of @vladmandic/human
const userConfig = { const userConfig = {
backend: 'wasm', backend: 'wasm',
async: false, async: false,
profile: false, profile: false,
warmup: 'full', warmup: 'full',
modelBasePath: '../../models/',
wasmPath: 'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@3.7.0/dist/',
filter: { enabled: false }, filter: { enabled: false },
face: { enabled: true, face: { enabled: true,
detector: { rotation: false, maxDetected: 1 }, detector: { rotation: false, maxDetected: 1 },

View File

@ -9,12 +9,12 @@
<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="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="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"> <meta name="theme-color" content="#000000">
<link rel="manifest" href="./manifest.webmanifest"> <link rel="manifest" href="../manifest.webmanifest">
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon"> <link rel="shortcut icon" href="../../favicon.ico" type="image/x-icon">
<link rel="apple-touch-icon" href="../assets/icon.png"> <link rel="apple-touch-icon" href="../../assets/icon.png">
<script src="./face3d.js" type="module"></script> <script src="face3d/face3d.js" type="module"></script>
<style> <style>
@font-face { font-family: 'Lato'; font-display: swap; font-style: normal; font-weight: 100; src: local('Lato'), url('../assets/lato-light.woff2') } @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; } html { font-family: 'Lato', 'Segoe UI'; font-size: 16px; font-variant: small-caps; }
body { margin: 0; background: black; color: white; overflow-x: hidden; } body { margin: 0; background: black; color: white; overflow-x: hidden; }
body::-webkit-scrollbar { display: none; } body::-webkit-scrollbar { display: none; }

View File

@ -6,13 +6,15 @@
* Demo for face descriptor analysis and face simmilarity analysis * Demo for face descriptor analysis and face simmilarity analysis
*/ */
import Human from '../dist/human.esm.js'; import Human from '../../dist/human.esm.js';
const userConfig = { const userConfig = {
backend: 'wasm', backend: 'wasm',
async: false, async: false,
warmup: 'none', warmup: 'none',
debug: true, debug: true,
modelBasePath: '../../models/',
wasmPath: 'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@3.7.0/dist/',
face: { face: {
enabled: true, enabled: true,
detector: { rotation: true, return: true }, detector: { rotation: true, return: true },
@ -49,8 +51,8 @@ function log(...msg) {
async function getFaceDB() { async function getFaceDB() {
// download db with known faces // download db with known faces
try { try {
let res = await fetch('/demo/facematch-faces.json'); let res = await fetch('/demo/facematch/faces.json');
if (!res || !res.ok) res = await fetch('/human/demo/facematch-faces.json'); if (!res || !res.ok) res = await fetch('/human/demo/facematch/faces.json');
db = (res && res.ok) ? await res.json() : []; db = (res && res.ok) ? await res.json() : [];
for (const rec of db) { for (const rec of db) {
rec.embedding = rec.embedding.map((a) => parseFloat(a.toFixed(4))); rec.embedding = rec.embedding.map((a) => parseFloat(a.toFixed(4)));
@ -147,7 +149,7 @@ async function process(index, image) {
return new Promise((resolve) => { return new Promise((resolve) => {
const img = new Image(128, 128); const img = new Image(128, 128);
img.onload = () => { // must wait until image is loaded img.onload = () => { // must wait until image is loaded
human.detect(img).then(async (res) => { human.detect(img, userConfig).then(async (res) => {
await faces(index, res, image); // then wait until image is analyzed await faces(index, res, image); // then wait until image is analyzed
log('Add image:', index + 1, image, 'faces:', res.face.length); log('Add image:', index + 1, image, 'faces:', res.face.length);
document.getElementById('images').appendChild(img); // and finally we can add it document.getElementById('images').appendChild(img); // and finally we can add it

View File

@ -9,12 +9,12 @@
<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="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="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"> <meta name="theme-color" content="#000000">
<link rel="manifest" href="./manifest.webmanifest"> <link rel="manifest" href="../manifest.webmanifest">
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon"> <link rel="shortcut icon" href="../../favicon.ico" type="image/x-icon">
<link rel="apple-touch-icon" href="../assets/icon.png"> <link rel="apple-touch-icon" href="../../assets/icon.png">
<script src="./facematch.js" type="module"></script> <script src="facematch/facematch.js" type="module"></script>
<style> <style>
@font-face { font-family: 'Lato'; font-display: swap; font-style: normal; font-weight: 100; src: local('Lato'), url('../assets/lato-light.woff2') } @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: 24px; font-variant: small-caps; } html { font-family: 'Lato', 'Segoe UI'; font-size: 24px; font-variant: small-caps; }
body { margin: 0; background: black; color: white; overflow-x: hidden; } body { margin: 0; background: black; color: white; overflow-x: hidden; }
img { object-fit: contain; } img { object-fit: contain; }

View File

@ -11,7 +11,7 @@ const log = require('@vladmandic/pilogger');
// workers actual import tfjs and faceapi modules // workers actual import tfjs and faceapi modules
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
const tf = require('@tensorflow/tfjs-node'); const tf = require('@tensorflow/tfjs-node');
const Human = require('../dist/human.node.js').default; // or const Human = require('../dist/human.node-gpu.js').default; const Human = require('../../dist/human.node.js').default; // or const Human = require('../dist/human.node-gpu.js').default;
let human = null; let human = null;

View File

@ -13,6 +13,7 @@ const log = require('@vladmandic/pilogger'); // this is my simple logger with fe
const child_process = require('child_process'); const child_process = require('child_process');
// note that main process import faceapi or tfjs at all // note that main process import faceapi or tfjs at all
const workerFile = 'demo/nodejs/node-multiprocess-worker.js';
const imgPathRoot = './assets'; // modify to include your sample images const imgPathRoot = './assets'; // modify to include your sample images
const numWorkers = 4; // how many workers will be started const numWorkers = 4; // how many workers will be started
const workers = []; // this holds worker processes const workers = []; // this holds worker processes
@ -68,10 +69,12 @@ async function main() {
log.state('Enumerated images:', imgPathRoot, numImages); log.state('Enumerated images:', imgPathRoot, numImages);
t[0] = process.hrtime.bigint(); t[0] = process.hrtime.bigint();
t[1] = process.hrtime.bigint();
t[2] = process.hrtime.bigint();
// manage worker processes // manage worker processes
for (let i = 0; i < numWorkers; i++) { for (let i = 0; i < numWorkers; i++) {
// create worker process // create worker process
workers[i] = await child_process.fork('demo/node-multiprocess-worker.js', ['special']); workers[i] = await child_process.fork(workerFile, ['special']);
// parse message that worker process sends back to main // parse message that worker process sends back to main
// if message is ready, dispatch next image in queue // if message is ready, dispatch next image in queue
// if message is processing result, just print how many faces were detected // if message is processing result, just print how many faces were detected

View File

@ -19,7 +19,7 @@ const Pipe2Jpeg = require('pipe2jpeg');
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
const tf = require('@tensorflow/tfjs-node'); // or const tf = require('@tensorflow/tfjs-node-gpu'); const tf = require('@tensorflow/tfjs-node'); // or const tf = require('@tensorflow/tfjs-node-gpu');
// load specific version of Human library that matches TensorFlow mode // load specific version of Human library that matches TensorFlow mode
const Human = require('../dist/human.node.js').default; // or const Human = require('../dist/human.node-gpu.js').default; const Human = require('../../dist/human.node.js').default; // or const Human = require('../dist/human.node-gpu.js').default;
let count = 0; // counter let count = 0; // counter
let busy = false; // busy flag let busy = false; // busy flag
@ -27,7 +27,7 @@ const inputFile = './test.mp4';
const humanConfig = { const humanConfig = {
backend: 'tensorflow', backend: 'tensorflow',
modelBasePath: 'file://node_modules/@vladmandic/human/models/', modelBasePath: 'file://models/',
debug: false, debug: false,
async: true, async: true,
filter: { enabled: false }, filter: { enabled: false },

View File

@ -14,7 +14,7 @@ const nodeWebCam = require('node-webcam');
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
const tf = require('@tensorflow/tfjs-node'); // or const tf = require('@tensorflow/tfjs-node-gpu'); const tf = require('@tensorflow/tfjs-node'); // or const tf = require('@tensorflow/tfjs-node-gpu');
// load specific version of Human library that matches TensorFlow mode // load specific version of Human library that matches TensorFlow mode
const Human = require('../dist/human.node.js').default; // or const Human = require('../dist/human.node-gpu.js').default; const Human = require('../../dist/human.node.js').default; // or const Human = require('../dist/human.node-gpu.js').default;
// options for node-webcam // options for node-webcam
const optionsCamera = { const optionsCamera = {
@ -25,7 +25,7 @@ const optionsCamera = {
// options for human // options for human
const optionsHuman = { const optionsHuman = {
backend: 'tensorflow', backend: 'tensorflow',
modelBasePath: 'file://node_modules/@vladmandic/human/models/', modelBasePath: 'file://models/',
}; };
const camera = nodeWebCam.create(optionsCamera); const camera = nodeWebCam.create(optionsCamera);

View File

@ -13,7 +13,7 @@ const fetch = require('node-fetch').default;
const tf = require('@tensorflow/tfjs-node'); // or const tf = require('@tensorflow/tfjs-node-gpu'); const tf = require('@tensorflow/tfjs-node'); // or const tf = require('@tensorflow/tfjs-node-gpu');
// load specific version of Human library that matches TensorFlow mode // load specific version of Human library that matches TensorFlow mode
const Human = require('../dist/human.node.js').default; // or const Human = require('../dist/human.node-gpu.js').default; const Human = require('../../dist/human.node.js').default; // or const Human = require('../dist/human.node-gpu.js').default;
let human = null; let human = null;

View File

@ -21,7 +21,7 @@
"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 demo/node.js", "start": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught demo/nodejs/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": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught server/build.js", "build": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught server/build.js",
"lint": "eslint src server demo test", "lint": "eslint src server demo test",
@ -82,8 +82,8 @@
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"seedrandom": "^3.0.5", "seedrandom": "^3.0.5",
"simple-git": "^2.39.1", "simple-git": "^2.40.0",
"tslib": "^2.2.0", "tslib": "^2.3.0",
"typedoc": "^0.21.0-beta.2", "typedoc": "^0.21.0-beta.2",
"typescript": "4.3.2" "typescript": "4.3.2"
} }

View File

@ -1,22 +1,22 @@
2021-06-11 16:10:58 INFO:  @vladmandic/human version 2.0.1 2021-06-14 08:14:47 INFO:  @vladmandic/human version 2.0.1
2021-06-11 16:10:58 INFO:  User: vlado Platform: linux Arch: x64 Node: v16.0.0 2021-06-14 08:14:47 INFO:  User: vlado Platform: linux Arch: x64 Node: v16.0.0
2021-06-11 16:10:58 INFO:  Toolchain: tfjs: 3.7.0 esbuild 0.12.8; typescript 4.3.2; typedoc: 0.21.0-beta.2 eslint: 7.28.0 2021-06-14 08:14:47 INFO:  Toolchain: tfjs: 3.7.0 esbuild 0.12.8; typescript 4.3.2; typedoc: 0.21.0-beta.2 eslint: 7.28.0
2021-06-11 16:10:58 INFO:  Clean: ["dist/*","types/*","typedoc/*"] 2021-06-14 08:14:47 INFO:  Clean: ["dist/*","types/*","typedoc/*"]
2021-06-11 16:10:58 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true} 2021-06-14 08:14:47 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true}
2021-06-11 16:10:58 STATE: target: node type: tfjs: {"imports":1,"importBytes":102,"outputBytes":1303,"outputFiles":"dist/tfjs.esm.js"} 2021-06-14 08:14:47 STATE: target: node type: tfjs: {"imports":1,"importBytes":102,"outputBytes":1303,"outputFiles":"dist/tfjs.esm.js"}
2021-06-11 16:10:58 STATE: target: node type: node: {"imports":41,"importBytes":430797,"outputBytes":376591,"outputFiles":"dist/human.node.js"} 2021-06-14 08:14:47 STATE: target: node type: node: {"imports":41,"importBytes":430804,"outputBytes":376591,"outputFiles":"dist/human.node.js"}
2021-06-11 16:10:58 STATE: target: nodeGPU type: tfjs: {"imports":1,"importBytes":110,"outputBytes":1311,"outputFiles":"dist/tfjs.esm.js"} 2021-06-14 08:14:47 STATE: target: nodeGPU type: tfjs: {"imports":1,"importBytes":110,"outputBytes":1311,"outputFiles":"dist/tfjs.esm.js"}
2021-06-11 16:10:58 STATE: target: nodeGPU type: node: {"imports":41,"importBytes":430805,"outputBytes":376595,"outputFiles":"dist/human.node-gpu.js"} 2021-06-14 08:14:47 STATE: target: nodeGPU type: node: {"imports":41,"importBytes":430812,"outputBytes":376595,"outputFiles":"dist/human.node-gpu.js"}
2021-06-11 16:10:58 STATE: target: nodeWASM type: tfjs: {"imports":1,"importBytes":149,"outputBytes":1378,"outputFiles":"dist/tfjs.esm.js"} 2021-06-14 08:14:47 STATE: target: nodeWASM type: tfjs: {"imports":1,"importBytes":149,"outputBytes":1378,"outputFiles":"dist/tfjs.esm.js"}
2021-06-11 16:10:58 STATE: target: nodeWASM type: node: {"imports":41,"importBytes":430872,"outputBytes":376667,"outputFiles":"dist/human.node-wasm.js"} 2021-06-14 08:14:47 STATE: target: nodeWASM type: node: {"imports":41,"importBytes":430879,"outputBytes":376667,"outputFiles":"dist/human.node-wasm.js"}
2021-06-11 16:10:58 STATE: target: browserNoBundle type: tfjs: {"imports":1,"importBytes":2817,"outputBytes":1214,"outputFiles":"dist/tfjs.esm.js"} 2021-06-14 08:14:47 STATE: target: browserNoBundle type: tfjs: {"imports":1,"importBytes":2817,"outputBytes":1214,"outputFiles":"dist/tfjs.esm.js"}
2021-06-11 16:10:58 STATE: target: browserNoBundle type: esm: {"imports":41,"importBytes":430708,"outputBytes":247861,"outputFiles":"dist/human.esm-nobundle.js"} 2021-06-14 08:14:47 STATE: target: browserNoBundle type: esm: {"imports":41,"importBytes":430715,"outputBytes":247861,"outputFiles":"dist/human.esm-nobundle.js"}
2021-06-11 16:10:59 STATE: target: browserBundle type: tfjs: {"modules":1684,"moduleBytes":5720339,"imports":7,"importBytes":2817,"outputBytes":2817783,"outputFiles":"dist/tfjs.esm.js"} 2021-06-14 08:14:48 STATE: target: browserBundle type: tfjs: {"modules":1684,"moduleBytes":5720339,"imports":7,"importBytes":2817,"outputBytes":2817783,"outputFiles":"dist/tfjs.esm.js"}
2021-06-11 16:10:59 STATE: target: browserBundle type: iife: {"imports":41,"importBytes":3247277,"outputBytes":1588248,"outputFiles":"dist/human.js"} 2021-06-14 08:14:48 STATE: target: browserBundle type: iife: {"imports":41,"importBytes":3247284,"outputBytes":1588248,"outputFiles":"dist/human.js"}
2021-06-11 16:11:00 STATE: target: browserBundle type: esm: {"imports":41,"importBytes":3247277,"outputBytes":1588240,"outputFiles":"dist/human.esm.js"} 2021-06-14 08:14:49 STATE: target: browserBundle type: esm: {"imports":41,"importBytes":3247284,"outputBytes":1588240,"outputFiles":"dist/human.esm.js"}
2021-06-11 16:11:00 INFO:  Running Linter: ["server/","src/","tfjs/","test/","demo/"] 2021-06-14 08:14:49 INFO:  Running Linter: ["server/","src/","tfjs/","test/","demo/"]
2021-06-11 16:11:26 INFO:  Linter complete: files: 71 errors: 0 warnings: 0 2021-06-14 08:15:14 INFO:  Linter complete: files: 71 errors: 0 warnings: 0
2021-06-11 16:11:26 INFO:  Generate ChangeLog: ["/home/vlado/dev/human/CHANGELOG.md"] 2021-06-14 08:15:14 INFO:  Generate ChangeLog: ["/home/vlado/dev/human/CHANGELOG.md"]
2021-06-11 16:11:26 INFO:  Generate Typings: ["src/human.ts"] outDir: ["types"] 2021-06-14 08:15:14 INFO:  Generate Typings: ["src/human.ts"] outDir: ["types"]
2021-06-11 16:11:42 INFO:  Generate TypeDocs: ["src/human.ts"] outDir: ["typedoc"] 2021-06-14 08:15:30 INFO:  Generate TypeDocs: ["src/human.ts"] outDir: ["typedoc"]
2021-06-11 16:11:55 INFO:  Documentation generated at /home/vlado/dev/human/typedoc 1 2021-06-14 08:15:43 INFO:  Documentation generated at /home/vlado/dev/human/typedoc 1

2
wiki

@ -1 +1 @@
Subproject commit 9e92e5eec1e60b5ea58dbf1c4bbc67c828bcf673 Subproject commit d270e2eb172e90acefb4e3be22260e3ad6a03ab1