diff --git a/CHANGELOG.md b/CHANGELOG.md
index 259afcdb..ced5570c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,8 +9,9 @@
## Changelog
-### **HEAD -> main** 2022/07/16 mandic00@live.com
+### **HEAD -> main** 2022/07/17 mandic00@live.com
+- swtich to release version of tfjs
- placeholder for face contours
- improve face compare in main demo
- add webview support
diff --git a/TODO.md b/TODO.md
index 9a0c255a..fff49463 100644
--- a/TODO.md
+++ b/TODO.md
@@ -47,3 +47,17 @@ Feature is automatically disabled in **NodeJS** without user impact
## Pending Release Changes
+
+- install production-only dependencies by default
+ results in a must faster and smaller `human` installation
+ to install all dependencies use `npm install @vladmandic/human --production=false`
+- switch to production `@tensorflow/tfjs` for browsers
+ `tfjs` has stabilized in recent versions so its not necessary to run a custom bundle anymore
+- add **webview** support
+- add `getModelStats` method
+- extract model stats in build process
+- typedoc fixes
+- add face contours to results
+- improve face compare in demo app
+- update dependencies
+- gear model fixes
diff --git a/demo/multithread/README.md b/demo/multithread/README.md
index e46f0c6b..7b47e6b4 100644
--- a/demo/multithread/README.md
+++ b/demo/multithread/README.md
@@ -19,7 +19,7 @@ node demo/nodejs/node-multiprocess.js
```json
2021-06-01 08:54:19 INFO: @vladmandic/human version 2.0.0
2021-06-01 08:54:19 INFO: User: vlado Platform: linux Arch: x64 Node: v16.0.0
-2021-06-01 08:54:19 INFO: FaceAPI multi-process test
+2021-06-01 08:54:19 INFO: Human multi-process test
2021-06-01 08:54:19 STATE: Enumerated images: ./assets 15
2021-06-01 08:54:19 STATE: Main: started worker: 130362
2021-06-01 08:54:19 STATE: Main: started worker: 130363
diff --git a/demo/multithread/node-multiprocess-worker.js b/demo/multithread/node-multiprocess-worker.js
index c8f16a99..8c6cc3d8 100644
--- a/demo/multithread/node-multiprocess-worker.js
+++ b/demo/multithread/node-multiprocess-worker.js
@@ -8,7 +8,7 @@
const fs = require('fs');
const log = require('@vladmandic/pilogger');
-// workers actual import tfjs and faceapi modules
+// workers actual import tfjs and human modules
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
const tf = require('@tensorflow/tfjs-node');
const Human = require('../../dist/human.node.js').default; // or const Human = require('../dist/human.node-gpu.js').default;
@@ -36,7 +36,7 @@ const myConfig = {
object: { enabled: true },
};
-// read image from a file and create tensor to be used by faceapi
+// read image from a file and create tensor to be used by human
// this way we don't need any monkey patches
// you can add any pre-proocessing here such as resizing, etc.
async function image(img) {
@@ -45,7 +45,7 @@ async function image(img) {
return tensor;
}
-// actual faceapi detection
+// actual human detection
async function detect(img) {
const tensor = await image(img);
const result = await human.detect(tensor);
diff --git a/demo/multithread/node-multiprocess.js b/demo/multithread/node-multiprocess.js
index 46b82706..3dc6cdea 100644
--- a/demo/multithread/node-multiprocess.js
+++ b/demo/multithread/node-multiprocess.js
@@ -58,7 +58,7 @@ async function main() {
});
log.header();
- log.info('FaceAPI multi-process test');
+ log.info('Human multi-process test');
// enumerate all images into queue
const dir = fs.readdirSync(imgPathRoot);
diff --git a/demo/nodejs/node-canvas.js b/demo/nodejs/node-canvas.js
index c1359199..184ffe0d 100644
--- a/demo/nodejs/node-canvas.js
+++ b/demo/nodejs/node-canvas.js
@@ -9,7 +9,7 @@ const canvas = require('canvas');
// eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars, @typescript-eslint/no-unused-vars
const tf = require('@tensorflow/tfjs-node'); // in nodejs environments tfjs-node is required to be loaded before human
-// const faceapi = require('@vladmandic/face-api'); // use this when human is installed as module (majority of use cases)
+// const human = require('@vladmandic/human'); // use this when human is installed as module (majority of use cases)
const Human = require('../../dist/human.node.js'); // use this when using human in dev mode
const config = { // just enable all and leave default settings
diff --git a/demo/nodejs/node-event.js b/demo/nodejs/node-event.js
index 7d9485f2..90cd823d 100644
--- a/demo/nodejs/node-event.js
+++ b/demo/nodejs/node-event.js
@@ -10,7 +10,7 @@ let fetch; // fetch is dynamically imported later
// eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars, @typescript-eslint/no-unused-vars
const tf = require('@tensorflow/tfjs-node'); // in nodejs environments tfjs-node is required to be loaded before human
-// const faceapi = require('@vladmandic/face-api'); // use this when human is installed as module (majority of use cases)
+// const human = require('@vladmandic/human'); // use this when human is installed as module (majority of use cases)
const Human = require('../../dist/human.node.js'); // use this when using human in dev mode
let human = null;
diff --git a/demo/nodejs/node-fetch.js b/demo/nodejs/node-fetch.js
index 9c78d92f..ab642fb5 100644
--- a/demo/nodejs/node-fetch.js
+++ b/demo/nodejs/node-fetch.js
@@ -2,7 +2,7 @@ const fs = require('fs');
// eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars, @typescript-eslint/no-unused-vars
const tf = require('@tensorflow/tfjs-node'); // in nodejs environments tfjs-node is required to be loaded before human
-// const faceapi = require('@vladmandic/face-api'); // use this when human is installed as module (majority of use cases)
+// const human = require('@vladmandic/human'); // use this when human is installed as module (majority of use cases)
const Human = require('../../dist/human.node.js'); // use this when using human in dev mode
const humanConfig = {
diff --git a/demo/nodejs/node-similarity.js b/demo/nodejs/node-similarity.js
index df607bd8..a9402860 100644
--- a/demo/nodejs/node-similarity.js
+++ b/demo/nodejs/node-similarity.js
@@ -8,7 +8,7 @@ const process = require('process');
// eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars, @typescript-eslint/no-unused-vars
const tf = require('@tensorflow/tfjs-node'); // in nodejs environments tfjs-node is required to be loaded before human
-// const faceapi = require('@vladmandic/face-api'); // use this when human is installed as module (majority of use cases)
+// const human = require('@vladmandic/human'); // use this when human is installed as module (majority of use cases)
const Human = require('../../dist/human.node.js'); // use this when using human in dev mode
let human = null;
diff --git a/demo/nodejs/node-simple.js b/demo/nodejs/node-simple.js
index 2c34802c..0bd893ff 100644
--- a/demo/nodejs/node-simple.js
+++ b/demo/nodejs/node-simple.js
@@ -3,7 +3,7 @@ const process = require('process');
// eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars, @typescript-eslint/no-unused-vars
const tf = require('@tensorflow/tfjs-node'); // in nodejs environments tfjs-node is required to be loaded before human
-// const faceapi = require('@vladmandic/face-api'); // use this when human is installed as module (majority of use cases)
+// const human = require('@vladmandic/human'); // use this when human is installed as module (majority of use cases)
const Human = require('../../dist/human.node.js'); // use this when using human in dev mode
const humanConfig = {
diff --git a/demo/nodejs/node-video.js b/demo/nodejs/node-video.js
index f66fb4a1..be890880 100644
--- a/demo/nodejs/node-video.js
+++ b/demo/nodejs/node-video.js
@@ -19,7 +19,7 @@ const Pipe2Jpeg = require('pipe2jpeg');
// eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars, @typescript-eslint/no-unused-vars
const tf = require('@tensorflow/tfjs-node'); // in nodejs environments tfjs-node is required to be loaded before human
-// const faceapi = require('@vladmandic/face-api'); // use this when human is installed as module (majority of use cases)
+// const human = require('@vladmandic/human'); // use this when human is installed as module (majority of use cases)
const Human = require('../../dist/human.node.js'); // use this when using human in dev mode
let count = 0; // counter
diff --git a/demo/nodejs/node-webcam.js b/demo/nodejs/node-webcam.js
index 53d409d1..2e17f778 100644
--- a/demo/nodejs/node-webcam.js
+++ b/demo/nodejs/node-webcam.js
@@ -14,7 +14,7 @@ const nodeWebCam = require('node-webcam');
// eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars, @typescript-eslint/no-unused-vars
const tf = require('@tensorflow/tfjs-node'); // in nodejs environments tfjs-node is required to be loaded before human
-// const faceapi = require('@vladmandic/face-api'); // use this when human is installed as module (majority of use cases)
+// const human = require('@vladmandic/human'); // use this when human is installed as module (majority of use cases)
const Human = require('../../dist/human.node.js'); // use this when using human in dev mode
// options for node-webcam
diff --git a/demo/nodejs/node.js b/demo/nodejs/node.js
index db282a12..27f8909f 100644
--- a/demo/nodejs/node.js
+++ b/demo/nodejs/node.js
@@ -11,7 +11,7 @@ let fetch; // fetch is dynamically imported later
// eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars, @typescript-eslint/no-unused-vars
const tf = require('@tensorflow/tfjs-node'); // in nodejs environments tfjs-node is required to be loaded before human
-// const faceapi = require('@vladmandic/face-api'); // use this when human is installed as module (majority of use cases)
+// const human = require('@vladmandic/human'); // use this when human is installed as module (majority of use cases)
const Human = require('../../dist/human.node.js'); // use this when using human in dev mode
let human = null;
diff --git a/src/models.ts b/src/models.ts
index 4e6fa0c8..ca81b07e 100644
--- a/src/models.ts
+++ b/src/models.ts
@@ -63,6 +63,7 @@ export type ModelStats = {
numLoadedModels: number,
numEnabledModels: undefined,
numDefinedModels: number,
+ percentageLoaded: number,
totalSizeFromManifest: number,
totalSizeWeights: number,
totalSizeLoading: number,
@@ -79,10 +80,12 @@ export const getModelStats = (instance: Human): ModelStats => {
totalSizeWeights += m.sizeLoadedWeights;
totalSizeLoading += m.sizeDesired;
}
+ const percentageLoaded = totalSizeLoading > 0 ? totalSizeWeights / totalSizeLoading : 0;
return {
numLoadedModels: Object.values(modelStats).length,
numEnabledModels: undefined,
numDefinedModels: Object.keys(instance.models).length,
+ percentageLoaded,
totalSizeFromManifest,
totalSizeWeights,
totalSizeLoading,
diff --git a/test/build.log b/test/build.log
index 92b20de4..2b5e86d9 100644
--- a/test/build.log
+++ b/test/build.log
@@ -1,24 +1,24 @@
-2022-07-17 21:29:42 [36mINFO: [39m Application: {"name":"@vladmandic/human","version":"2.9.0"}
-2022-07-17 21:29:42 [36mINFO: [39m Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
-2022-07-17 21:29:42 [36mINFO: [39m Toolchain: {"build":"0.7.7","esbuild":"0.14.49","typescript":"4.7.4","typedoc":"0.23.8","eslint":"8.20.0"}
-2022-07-17 21:29:42 [36mINFO: [39m Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
-2022-07-17 21:29:42 [35mSTATE:[39m Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]}
-2022-07-17 21:29:42 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":102,"outputBytes":608}
-2022-07-17 21:29:42 [35mSTATE:[39m Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":74,"inputBytes":647707,"outputBytes":303979}
-2022-07-17 21:29:42 [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":110,"outputBytes":612}
-2022-07-17 21:29:42 [35mSTATE:[39m Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":74,"inputBytes":647711,"outputBytes":303983}
-2022-07-17 21:29:42 [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":149,"outputBytes":664}
-2022-07-17 21:29:42 [35mSTATE:[39m Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":74,"inputBytes":647763,"outputBytes":304033}
-2022-07-17 21:29:42 [35mSTATE:[39m Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1069,"outputBytes":358}
-2022-07-17 21:29:42 [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":1032,"outputBytes":583}
-2022-07-17 21:29:42 [35mSTATE:[39m Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":74,"inputBytes":647682,"outputBytes":302858}
-2022-07-17 21:29:43 [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":1140,"outputBytes":2799617}
-2022-07-17 21:29:43 [35mSTATE:[39m Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":74,"inputBytes":3446716,"outputBytes":1678559}
-2022-07-17 21:29:43 [35mSTATE:[39m Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":74,"inputBytes":3446716,"outputBytes":3078304}
-2022-07-17 21:29:49 [35mSTATE:[39m Typings: {"input":"src/human.ts","output":"types/lib","files":30}
-2022-07-17 21:29:52 [35mSTATE:[39m TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":76,"generated":true}
-2022-07-17 21:29:52 [35mSTATE:[39m Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":6371,"outputBytes":3094}
-2022-07-17 21:29:52 [35mSTATE:[39m Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15174,"outputBytes":7820}
-2022-07-17 21:30:02 [35mSTATE:[39m Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":106,"errors":0,"warnings":0}
-2022-07-17 21:30:02 [35mSTATE:[39m ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
-2022-07-17 21:30:02 [36mINFO: [39m Done...
+2022-07-18 08:21:08 [36mINFO: [39m Application: {"name":"@vladmandic/human","version":"2.9.0"}
+2022-07-18 08:21:08 [36mINFO: [39m Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
+2022-07-18 08:21:08 [36mINFO: [39m Toolchain: {"build":"0.7.7","esbuild":"0.14.49","typescript":"4.7.4","typedoc":"0.23.8","eslint":"8.20.0"}
+2022-07-18 08:21:08 [36mINFO: [39m Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
+2022-07-18 08:21:08 [35mSTATE:[39m Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]}
+2022-07-18 08:21: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":102,"outputBytes":608}
+2022-07-18 08:21:08 [35mSTATE:[39m Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":74,"inputBytes":647848,"outputBytes":304014}
+2022-07-18 08:21: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":110,"outputBytes":612}
+2022-07-18 08:21:08 [35mSTATE:[39m Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":74,"inputBytes":647852,"outputBytes":304018}
+2022-07-18 08:21: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":149,"outputBytes":664}
+2022-07-18 08:21:08 [35mSTATE:[39m Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":74,"inputBytes":647904,"outputBytes":304068}
+2022-07-18 08:21:09 [35mSTATE:[39m Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1069,"outputBytes":358}
+2022-07-18 08:21:09 [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":1032,"outputBytes":583}
+2022-07-18 08:21:09 [35mSTATE:[39m Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":74,"inputBytes":647823,"outputBytes":302893}
+2022-07-18 08:21: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":1140,"outputBytes":2799617}
+2022-07-18 08:21:09 [35mSTATE:[39m Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":74,"inputBytes":3446857,"outputBytes":1678594}
+2022-07-18 08:21:09 [35mSTATE:[39m Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":74,"inputBytes":3446857,"outputBytes":3078417}
+2022-07-18 08:21:16 [35mSTATE:[39m Typings: {"input":"src/human.ts","output":"types/lib","files":30}
+2022-07-18 08:21:18 [35mSTATE:[39m TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":76,"generated":true}
+2022-07-18 08:21:18 [35mSTATE:[39m Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":6371,"outputBytes":3094}
+2022-07-18 08:21:18 [35mSTATE:[39m Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15174,"outputBytes":7820}
+2022-07-18 08:21:28 [35mSTATE:[39m Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":107,"errors":0,"warnings":0}
+2022-07-18 08:21:28 [35mSTATE:[39m ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
+2022-07-18 08:21:28 [36mINFO: [39m Done...