mirror of https://github.com/vladmandic/human
new build process
parent
fd1217c4b3
commit
c3a5e1f802
14
.build.json
14
.build.json
|
@ -91,8 +91,7 @@
|
||||||
"platform": "browser",
|
"platform": "browser",
|
||||||
"format": "esm",
|
"format": "esm",
|
||||||
"input": "tfjs/tf-version.ts",
|
"input": "tfjs/tf-version.ts",
|
||||||
"output": "dist/tfjs.version.js",
|
"output": "dist/tfjs.version.js"
|
||||||
"external": ["fs", "os", "buffer", "util"]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "tfjs/browser/esm/nobundle",
|
"name": "tfjs/browser/esm/nobundle",
|
||||||
|
@ -100,7 +99,7 @@
|
||||||
"format": "esm",
|
"format": "esm",
|
||||||
"input": "tfjs/tf-browser.ts",
|
"input": "tfjs/tf-browser.ts",
|
||||||
"output": "dist/tfjs.esm.js",
|
"output": "dist/tfjs.esm.js",
|
||||||
"external": ["@tensorflow", "fs", "os", "buffer", "util"]
|
"external": ["@tensorflow"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "human/browser/esm/nobundle",
|
"name": "human/browser/esm/nobundle",
|
||||||
|
@ -109,7 +108,7 @@
|
||||||
"input": "src/human.ts",
|
"input": "src/human.ts",
|
||||||
"output": "dist/human.esm-nobundle.js",
|
"output": "dist/human.esm-nobundle.js",
|
||||||
"sourcemap": true,
|
"sourcemap": true,
|
||||||
"external": ["@tensorflow", "fs", "os", "buffer", "util"]
|
"external": ["@tensorflow"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "tfjs/browser/esm/custom",
|
"name": "tfjs/browser/esm/custom",
|
||||||
|
@ -117,8 +116,7 @@
|
||||||
"format": "esm",
|
"format": "esm",
|
||||||
"input": "tfjs/tf-custom.ts",
|
"input": "tfjs/tf-custom.ts",
|
||||||
"output": "dist/tfjs.esm.js",
|
"output": "dist/tfjs.esm.js",
|
||||||
"sourcemap": false,
|
"sourcemap": false
|
||||||
"external": ["fs", "os", "buffer", "util"]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "human/browser/iife/bundle",
|
"name": "human/browser/iife/bundle",
|
||||||
|
@ -128,7 +126,7 @@
|
||||||
"output": "dist/human.js",
|
"output": "dist/human.js",
|
||||||
"minify": true,
|
"minify": true,
|
||||||
"globalName": "Human",
|
"globalName": "Human",
|
||||||
"external": ["fs", "os", "buffer", "util"]
|
"external": ["@tensorflow"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "human/browser/esm/bundle",
|
"name": "human/browser/esm/bundle",
|
||||||
|
@ -138,7 +136,7 @@
|
||||||
"output": "dist/human.esm.js",
|
"output": "dist/human.esm.js",
|
||||||
"sourcemap": true,
|
"sourcemap": true,
|
||||||
"minify": false,
|
"minify": false,
|
||||||
"external": ["fs", "os", "buffer", "util"],
|
"external": ["@tensorflow"],
|
||||||
"typings": "types/lib",
|
"typings": "types/lib",
|
||||||
"typedoc": "typedoc"
|
"typedoc": "typedoc"
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,8 +9,12 @@
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
### **HEAD -> main** 2021/11/17 mandic00@live.com
|
### **2.5.3** 2021/11/18 mandic00@live.com
|
||||||
|
|
||||||
|
|
||||||
|
### **origin/main** 2021/11/17 mandic00@live.com
|
||||||
|
|
||||||
|
- create typedef rollup
|
||||||
- optimize centernet
|
- optimize centernet
|
||||||
- cache frequent tf constants
|
- cache frequent tf constants
|
||||||
- add extra face rotation prior to mesh
|
- add extra face rotation prior to mesh
|
||||||
|
|
14
TODO.md
14
TODO.md
|
@ -43,21 +43,21 @@ MoveNet MultiPose model does not work with WASM backend due to missing F32 broad
|
||||||
## Pending Release Notes
|
## Pending Release Notes
|
||||||
|
|
||||||
New:
|
New:
|
||||||
- New type definitions rollup
|
- Demo `demos/faceid` that utilizes multiple algorithm to validate input before triggering face recognition
|
||||||
- New demo `demos/faceid` that utilizes multiple algorithm to validate input before triggering face recognition
|
- Type definitions rollup for `Human` and `TFJS`
|
||||||
- New optional model `liveness`
|
- Optional module `liveness`
|
||||||
checks if input appears to be a real-world live image or a recording
|
checks if input appears to be a real-world live image or a recording
|
||||||
best used together with `antispoofing` that checks if input appears to have a realistic face
|
best used together with module `antispoofing` that checks if input appears to have a realistic face
|
||||||
- New face masking option in `face.config.detector.mask`
|
- Face masking option in `face.config.detector.mask`
|
||||||
result is shading of face image outside of face area which is useful for increased sensitivity of other modules that rely on detected face as input
|
result is shading of face image outside of face area which is useful for increased sensitivity of other modules that rely on detected face as input
|
||||||
- New face crop option in `face.config.detector.cropFactor`
|
- Face crop option in `face.config.detector.cropFactor`
|
||||||
result is user-definable fine-tuning for other modules that rely on detected face as input
|
result is user-definable fine-tuning for other modules that rely on detected face as input
|
||||||
|
|
||||||
Other:
|
Other:
|
||||||
|
- Documentation overhaul
|
||||||
- Improved **Safari** compatibility
|
- Improved **Safari** compatibility
|
||||||
- Improved `similarity` and `match` score range normalization
|
- Improved `similarity` and `match` score range normalization
|
||||||
- Improved error handling
|
- Improved error handling
|
||||||
- Improved VSCode out-of-the-box experience
|
- Improved VSCode out-of-the-box experience
|
||||||
- Documentation overhaul
|
|
||||||
- Fix for optional `gear`, `ssrnet`, `mobilefacenet` modules
|
- Fix for optional `gear`, `ssrnet`, `mobilefacenet` modules
|
||||||
- Fix for Firefox WebGPU compatibility issue
|
- Fix for Firefox WebGPU compatibility issue
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
||||||
"mainEntryPointFilePath": "types/lib/src/human.d.ts",
|
"mainEntryPointFilePath": "types/lib/src/human.d.ts",
|
||||||
"bundledPackages": ["@tensorflow/tfjs-core", "@tensorflow/tfjs-converter", "long", "@types/offscreencanvas"],
|
"bundledPackages": ["@tensorflow/tfjs-core", "@tensorflow/tfjs-converter"],
|
||||||
"compiler": {
|
"compiler": {
|
||||||
"skipLibCheck": false
|
"skipLibCheck": false
|
||||||
},
|
},
|
||||||
|
|
|
@ -313,7 +313,7 @@ async function main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function init() {
|
async function init() {
|
||||||
log2("human version:", human.version, "| tfjs version:", human.tf.version_core);
|
log2("human version:", human.version, "| tfjs version:", human.tf.version["tfjs-core"]);
|
||||||
log2("options:", JSON.stringify(options).replace(/{|}|"|\[|\]/g, "").replace(/,/g, " "));
|
log2("options:", JSON.stringify(options).replace(/{|}|"|\[|\]/g, "").replace(/,/g, " "));
|
||||||
printFPS("loading...");
|
printFPS("loading...");
|
||||||
log2("known face records:", await count());
|
log2("known face records:", await count());
|
||||||
|
|
|
@ -257,7 +257,7 @@ async function main() { // main entry point
|
||||||
}
|
}
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
log('human version:', human.version, '| tfjs version:', human.tf.version_core);
|
log('human version:', human.version, '| tfjs version:', human.tf.version['tfjs-core']);
|
||||||
log('options:', JSON.stringify(options).replace(/{|}|"|\[|\]/g, '').replace(/,/g, ' '));
|
log('options:', JSON.stringify(options).replace(/{|}|"|\[|\]/g, '').replace(/,/g, ' '));
|
||||||
printFPS('loading...');
|
printFPS('loading...');
|
||||||
log('known face records:', await indexDb.count());
|
log('known face records:', await indexDb.count());
|
||||||
|
|
|
@ -16,7 +16,7 @@ const Human = require('../../dist/human.node.js').default; // or const Human = r
|
||||||
let human = null;
|
let human = null;
|
||||||
|
|
||||||
const myConfig = {
|
const myConfig = {
|
||||||
backend: 'tensorflow',
|
// backend: 'tensorflow',
|
||||||
modelBasePath: 'file://models/',
|
modelBasePath: 'file://models/',
|
||||||
debug: false,
|
debug: false,
|
||||||
async: true,
|
async: true,
|
||||||
|
@ -78,7 +78,7 @@ async function main() {
|
||||||
// wait until tf is ready
|
// wait until tf is ready
|
||||||
await human.tf.ready();
|
await human.tf.ready();
|
||||||
// pre-load models
|
// pre-load models
|
||||||
log.state('Worker: PID:', process.pid, `TensorFlow/JS ${human.tf.version_core} Human ${human.version} Backend: ${human.tf.getBackend()}`);
|
log.state('Worker: PID:', process.pid, `TensorFlow/JS ${human.tf.version['tfjs-core']} Human ${human.version} Backend: ${human.tf.getBackend()}`);
|
||||||
await human.load();
|
await human.load();
|
||||||
|
|
||||||
// now we're ready, so send message back to main that it knows it can use this worker
|
// now we're ready, so send message back to main that it knows it can use this worker
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
const Human = require('../../dist/human.node.js').default; // this is same as `@vladmandic/human` but using relative paths
|
||||||
|
|
||||||
|
async function main(inputFile) {
|
||||||
|
const human = new Human(); // create instance of human using default configuration
|
||||||
|
const buffer = fs.readFileSync(inputFile); // read file data into buffer
|
||||||
|
const tensor = human.tf.node.decodeImage(buffer); // decode jpg data
|
||||||
|
const result = await human.detect(tensor); // run detection; will initialize backend and on-demand load models
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
main('samples/in/ai-body.jpg');
|
|
@ -19,7 +19,7 @@ const Human = require('../../dist/human.node.js').default; // or const Human = r
|
||||||
let human = null;
|
let human = null;
|
||||||
|
|
||||||
const myConfig = {
|
const myConfig = {
|
||||||
backend: 'tensorflow',
|
// backend: 'tensorflow',
|
||||||
modelBasePath: 'file://models/',
|
modelBasePath: 'file://models/',
|
||||||
debug: true,
|
debug: true,
|
||||||
async: false,
|
async: false,
|
||||||
|
|
|
@ -8,7 +8,12 @@
|
||||||
import { Human } from "../../dist/human.esm.js";
|
import { Human } from "../../dist/human.esm.js";
|
||||||
var humanConfig = {
|
var humanConfig = {
|
||||||
modelBasePath: "../../models",
|
modelBasePath: "../../models",
|
||||||
filter: { equalization: true }
|
filter: { enabled: true, equalization: false },
|
||||||
|
face: { enabled: true, detector: { rotation: false }, mesh: { enabled: true }, iris: { enabled: true }, description: { enabled: true }, emotion: { enabled: true } },
|
||||||
|
body: { enabled: true },
|
||||||
|
hand: { enabled: true },
|
||||||
|
object: { enabled: false },
|
||||||
|
gesture: { enabled: true }
|
||||||
};
|
};
|
||||||
var human = new Human(humanConfig);
|
var human = new Human(humanConfig);
|
||||||
human.env["perfadd"] = false;
|
human.env["perfadd"] = false;
|
||||||
|
@ -80,7 +85,7 @@ async function drawLoop() {
|
||||||
setTimeout(drawLoop, 30);
|
setTimeout(drawLoop, 30);
|
||||||
}
|
}
|
||||||
async function main() {
|
async function main() {
|
||||||
log("human version:", human.version, "| tfjs version:", human.tf.version_core);
|
log("human version:", human.version, "| tfjs version:", human.tf.version["tfjs-core"]);
|
||||||
log("platform:", human.env.platform, "| agent:", human.env.agent);
|
log("platform:", human.env.platform, "| agent:", human.env.agent);
|
||||||
status("loading...");
|
status("loading...");
|
||||||
await human.load();
|
await human.load();
|
||||||
|
|
|
@ -10,15 +10,15 @@
|
||||||
import { Human } from '../../dist/human.esm.js'; // equivalent of @vladmandic/Human
|
import { Human } from '../../dist/human.esm.js'; // equivalent of @vladmandic/Human
|
||||||
|
|
||||||
const humanConfig = { // user configuration for human, used to fine-tune behavior
|
const humanConfig = { // user configuration for human, used to fine-tune behavior
|
||||||
modelBasePath: '../../models',
|
|
||||||
filter: { equalization: true },
|
|
||||||
// backend: 'webgpu' as 'webgpu,
|
// backend: 'webgpu' as 'webgpu,
|
||||||
// async: true,
|
// async: true,
|
||||||
// face: { enabled: false, detector: { rotation: true }, iris: { enabled: false }, description: { enabled: false }, emotion: { enabled: false } },
|
modelBasePath: '../../models',
|
||||||
// body: { enabled: false },
|
filter: { enabled: true, equalization: false },
|
||||||
// hand: { enabled: false },
|
face: { enabled: true, detector: { rotation: false }, mesh: { enabled: true }, iris: { enabled: true }, description: { enabled: true }, emotion: { enabled: true } },
|
||||||
// object: { enabled: true },
|
body: { enabled: true },
|
||||||
// gesture: { enabled: true },
|
hand: { enabled: true },
|
||||||
|
object: { enabled: false },
|
||||||
|
gesture: { enabled: true },
|
||||||
};
|
};
|
||||||
|
|
||||||
const human = new Human(humanConfig); // create instance of human with overrides from user configuration
|
const human = new Human(humanConfig); // create instance of human with overrides from user configuration
|
||||||
|
@ -97,7 +97,7 @@ async function drawLoop() { // main screen refresh loop
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() { // main entry point
|
async function main() { // main entry point
|
||||||
log('human version:', human.version, '| tfjs version:', human.tf.version_core);
|
log('human version:', human.version, '| tfjs version:', human.tf.version['tfjs-core']);
|
||||||
log('platform:', human.env.platform, '| agent:', human.env.agent);
|
log('platform:', human.env.platform, '| agent:', human.env.agent);
|
||||||
status('loading...');
|
status('loading...');
|
||||||
await human.load(); // preload all models
|
await human.load(); // preload all models
|
||||||
|
|
|
@ -124,7 +124,7 @@ export class Human {
|
||||||
*/
|
*/
|
||||||
constructor(userConfig?: Partial<Config>) {
|
constructor(userConfig?: Partial<Config>) {
|
||||||
this.env = env;
|
this.env = env;
|
||||||
defaults.wasmPath = tf.version_core.includes('-') // custom build or official build
|
defaults.wasmPath = tf.version['tfjs-core'].includes('-') // custom build or official build
|
||||||
? 'https://vladmandic.github.io/tfjs/dist/'
|
? 'https://vladmandic.github.io/tfjs/dist/'
|
||||||
: `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf.version_core}/dist/`;
|
: `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf.version_core}/dist/`;
|
||||||
defaults.modelBasePath = env.browser ? '../models/' : 'file://models/';
|
defaults.modelBasePath = env.browser ? '../models/' : 'file://models/';
|
||||||
|
@ -283,7 +283,7 @@ export class Human {
|
||||||
|
|
||||||
if (this.env.initial) { // print version info on first run and check for correct backend setup
|
if (this.env.initial) { // print version info on first run and check for correct backend setup
|
||||||
if (this.config.debug) log(`version: ${this.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(`tfjs version: ${this.tf.version['tfjs-core']}`);
|
||||||
if (!await backend.check(this)) log('error: backend check failed');
|
if (!await backend.check(this)) log('error: backend check failed');
|
||||||
await tf.ready();
|
await tf.ready();
|
||||||
if (this.env.browser) {
|
if (this.env.browser) {
|
||||||
|
|
|
@ -16,4 +16,4 @@ export type { GraphModel } from '@tensorflow/tfjs-converter/dist/index';
|
||||||
* @external long
|
* @external long
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line node/no-missing-import
|
// eslint-disable-next-line node/no-missing-import
|
||||||
export type { Long } from 'long';
|
// export type { Long } from 'long';
|
||||||
|
|
|
@ -81,7 +81,7 @@ export class Env {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.browser = typeof navigator !== 'undefined';
|
this.browser = typeof navigator !== 'undefined';
|
||||||
this.node = typeof process !== 'undefined';
|
this.node = typeof process !== 'undefined';
|
||||||
this.tfjs = { version: tf.version_core };
|
this.tfjs = { version: tf.version['tfjs-core'] };
|
||||||
this.offscreen = typeof OffscreenCanvas !== 'undefined';
|
this.offscreen = typeof OffscreenCanvas !== 'undefined';
|
||||||
this.initial = true;
|
this.initial = true;
|
||||||
// @ts-ignore WorkerGlobalScope evaluated in browser only
|
// @ts-ignore WorkerGlobalScope evaluated in browser only
|
||||||
|
@ -148,8 +148,8 @@ export class Env {
|
||||||
async updateCPU() {
|
async updateCPU() {
|
||||||
const cpu = { model: '', flags: [] };
|
const cpu = { model: '', flags: [] };
|
||||||
if (this.node && this.platform.startsWith('linux')) {
|
if (this.node && this.platform.startsWith('linux')) {
|
||||||
// eslint-disable-next-line global-require
|
|
||||||
/*
|
/*
|
||||||
|
// eslint-disable-next-line global-require
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
try {
|
try {
|
||||||
const data = fs.readFileSync('/proc/cpuinfo').toString();
|
const data = fs.readFileSync('/proc/cpuinfo').toString();
|
||||||
|
|
|
@ -266,7 +266,7 @@ async function test(Human, inputConfig) {
|
||||||
config.cacheSensitivity = 0;
|
config.cacheSensitivity = 0;
|
||||||
config.warmup = 'none';
|
config.warmup = 'none';
|
||||||
res = await testWarmup(human, 'default');
|
res = await testWarmup(human, 'default');
|
||||||
if (res.error !== 'null') log('error', 'failed: warmup none result mismatch');
|
if (res.error !== null) log('error', 'failed: warmup none result mismatch');
|
||||||
else log('state', 'passed: warmup none result match');
|
else log('state', 'passed: warmup none result match');
|
||||||
config.warmup = 'face';
|
config.warmup = 'face';
|
||||||
res = await testWarmup(human, 'default');
|
res = await testWarmup(human, 'default');
|
||||||
|
|
Loading…
Reference in New Issue