default empty result

pull/356/head
Vladimir Mandic 2022-11-17 14:53:48 -05:00
parent 8d9190a773
commit f278424664
8 changed files with 72 additions and 76 deletions

View File

@ -11,9 +11,8 @@
### **HEAD -> main** 2022/11/17 mandic00@live.com
### **origin/main** 2022/11/16 mandic00@live.com
- refactor distance
- add basic anthropometry
- added webcam id specification
- include external typedefs
- prepare external typedefs

12
TODO.md
View File

@ -59,6 +59,10 @@ Optimizations:
- If `config.backend` is not set, Human will auto-select best backend
based on device capabilities
- Enhanced support for `webgpu`
- Reduce build dependencies
`Human` is now 30% smaller :)
As usual, `Human` has **zero** runtime dependencies,
all *devDependencies* are only to rebuild `Human` itself
Features:
- Add [draw label templates](https://github.com/vladmandic/human/wiki/Draw)
@ -73,15 +77,15 @@ Features:
See `human.result.face[n].distance`
Architecture:
- Reduce build dependencies
`Human` is now 30% smaller :)
As usual, `Human` has **zero** runtime dependencies,
all *devDependencies* are only to rebuild `Human` itself
- Upgrade to **TFJS 4.0** with **strong typing**
see [notes](https://github.com/vladmandic/human#typedefs) on how to use
- `TypeDef` refactoring
- Re-architect `human.models` namespace for better dynamic model handling
Added additional methods `load`, `list`, `loaded`, `reset`
- Repack external typedefs
Removes all external typedef dependencies
- Refactor namespace exports
Better [TypeDoc specs](https://vladmandic.github.io/human/typedoc/index.html)
- Add named export for improved bundler support when using non-default imports
- Support for **NodeJS v19**
- Upgrade to **TypeScript 4.9**

View File

@ -54,7 +54,7 @@ export function similarity(descriptor1: Descriptor, descriptor2: Descriptor, opt
* - `distance` calculated `distance` of given descriptor to the best match
* - `similarity` calculated normalized `similarity` of given descriptor to the best match
*/
export function match(descriptor: Descriptor, descriptors: Descriptor[], options: MatchOptions = { order: 2, multiplier: 25, threshold: 0, min: 0.2, max: 0.8 }) {
export function find(descriptor: Descriptor, descriptors: Descriptor[], options: MatchOptions = { order: 2, multiplier: 25, threshold: 0, min: 0.2, max: 0.8 }) {
if (!Array.isArray(descriptor) || !Array.isArray(descriptors) || descriptor.length < 64 || descriptors.length === 0) { // validate input
return { index: -1, distance: Number.POSITIVE_INFINITY, similarity: 0 };
}

View File

@ -39,7 +39,7 @@ import * as selfie from './segmentation/selfie';
import * as warmups from './warmup';
// type definitions
import { Input, DrawOptions, Config, Result, FaceResult, HandResult, BodyResult, ObjectResult, GestureResult, AnyCanvas, emptyResult } from './exports';
import { Input, Config, Result, FaceResult, HandResult, BodyResult, ObjectResult, GestureResult, AnyCanvas, empty } from './exports';
import type { Tensor, Tensor4D } from './tfjs/types';
// type exports
export * from './exports';
@ -85,7 +85,7 @@ export class Human {
tf;
/** Object containing environment information used for diagnostics */
env: Env;
env: Env = env;
/** Draw helper classes that can draw detected objects on canvas using specified draw
* - canvas: draws input to canvas
@ -133,7 +133,6 @@ export class Human {
* @param userConfig - user configuration object {@link Config}
*/
constructor(userConfig?: Partial<Config>) {
this.env = env;
/*
defaults.wasmPath = tf.version['tfjs-core'].includes('-') // custom build or official build
? 'https://vladmandic.github.io/tfjs/dist/'
@ -160,7 +159,7 @@ export class Human {
this.models = new models.Models(this);
// reexport draw methods
draw.init();
this.result = emptyResult();
this.result = empty();
// export access to image processing
this.process = { tensor: null, canvas: null };
// export raw access to underlying models
@ -394,7 +393,7 @@ export class Human {
if (error) {
log(error, input);
this.emit('error');
resolve(emptyResult(error));
resolve(empty(error));
}
const timeStart = now();
@ -412,7 +411,7 @@ export class Human {
if (!img.tensor) {
if (this.config.debug) log('could not convert input to tensor');
this.emit('error');
resolve(emptyResult('could not convert input to tensor'));
resolve(empty('could not convert input to tensor'));
return;
}
this.emit('image');

View File

@ -231,4 +231,4 @@ export interface Result {
height: number,
}
export const emptyResult = (error: string | null = null): Result => ({ face: [], body: [], hand: [], gesture: [], object: [], persons: [], performance: {}, timestamp: 0, width: 0, height: 0, error });
export const empty = (error: string | null = null): Result => ({ face: [], body: [], hand: [], gesture: [], object: [], persons: [], performance: {}, timestamp: 0, width: 0, height: 0, error });

View File

@ -2,7 +2,7 @@
* Results interpolation for smoothening of video detection results inbetween detected frames
*/
import { Result, FaceResult, BodyResult, HandResult, ObjectResult, PersonResult, Box, Point, BodyLandmark, BodyAnnotation, emptyResult } from '../result';
import { Result, FaceResult, BodyResult, HandResult, ObjectResult, PersonResult, Box, Point, BodyLandmark, BodyAnnotation, empty } from '../result';
import type { Config } from '../config';
import * as moveNetCoords from '../body/movenetcoords';
@ -11,12 +11,12 @@ import * as efficientPoseCoords from '../body/efficientposecoords';
import { now } from './util';
import { env } from './env';
const bufferedResult: Result = emptyResult();
const bufferedResult: Result = empty();
let interpolateTime = 0;
export function calc(newResult: Result, config: Config): Result {
const t0 = now();
if (!newResult) return emptyResult();
if (!newResult) return empty();
// each record is only updated using deep clone when number of detected record changes, otherwise it will converge by itself
// otherwise bufferedResult is a shallow clone of result plus updated local calculated values
// thus mixing by-reference and by-value assignments to minimize memory operations

View File

@ -8,7 +8,7 @@ import * as sample from './sample';
import * as image from './image/image';
import * as backend from './tfjs/backend';
import { env } from './util/env';
import { emptyResult, Result } from './result';
import { empty, Result } from './result';
import type { Config } from './config';
import type { Human } from './human';
import type { Tensor, DataType } from './tfjs/types';
@ -158,7 +158,7 @@ export async function warmup(instance: Human, userConfig?: Partial<Config>): Pro
instance.state = 'warmup';
if (userConfig) instance.config = mergeDeep(instance.config, userConfig) as Config;
if (!instance.config.warmup || instance.config.warmup.length === 0 || instance.config.warmup === 'none') {
return emptyResult();
return empty();
}
return new Promise(async (resolve) => {
await instance.models.load();

View File

@ -1,56 +1,50 @@
2022-11-17 14:37:08 DATA:  Build {"name":"@vladmandic/human","version":"3.0.0"}
2022-11-17 14:37:08 INFO:  Application: {"name":"@vladmandic/human","version":"3.0.0"}
2022-11-17 14:37:08 INFO:  Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
2022-11-17 14:37:08 INFO:  Toolchain: {"build":"0.7.14","esbuild":"0.15.14","typescript":"4.9.3","typedoc":"0.23.21","eslint":"8.27.0"}
2022-11-17 14:37:08 INFO:  Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
2022-11-17 14:37:08 STATE: Clean: {"locations":["dist/*","types/*","typedoc/*"]}
2022-11-17 14:37:08 STATE: Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1289,"outputBytes":361}
2022-11-17 14:37:08 STATE: Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":569,"outputBytes":924}
2022-11-17 14:37:08 STATE: Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":80,"inputBytes":670179,"outputBytes":317460}
2022-11-17 14:37:08 STATE: Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":577,"outputBytes":928}
2022-11-17 14:37:08 STATE: Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":80,"inputBytes":670183,"outputBytes":317464}
2022-11-17 14:37:08 STATE: Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":665,"outputBytes":1876}
2022-11-17 14:37:08 STATE: Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":80,"inputBytes":671131,"outputBytes":317575}
2022-11-17 14:37:08 STATE: Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":1375,"outputBytes":670}
2022-11-17 14:37:08 STATE: Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":80,"inputBytes":669925,"outputBytes":316039}
2022-11-17 14:37:08 STATE: Compile: {"name":"tfjs/browser/esm/bundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":10,"inputBytes":1375,"outputBytes":1144900}
2022-11-17 14:37:08 STATE: Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":80,"inputBytes":1814155,"outputBytes":1457353}
2022-11-17 14:37:09 STATE: Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":80,"inputBytes":1814155,"outputBytes":1914737}
2022-11-17 14:37:12 STATE: Typings: {"input":"src/human.ts","output":"types/lib","files":15}
2022-11-17 14:37:14 STATE: TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":77,"generated":true}
2022-11-17 14:37:14 STATE: Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":6135,"outputBytes":2913}
2022-11-17 14:37:14 STATE: Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":17572,"outputBytes":9456}
2022-11-17 14:37:22 STATE: Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":114,"errors":0,"warnings":1}
2022-11-17 14:37:22 WARN: 
/home/vlado/dev/human/src/human.ts
42:17 warning 'DrawOptions' is defined but never used @typescript-eslint/no-unused-vars
✖ 1 problem (0 errors, 1 warning)
2022-11-17 14:37:22 STATE: ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
2022-11-17 14:37:22 STATE: Copy: {"input":"node_modules/@vladmandic/tfjs/types/tfjs-core.d.ts","output":"types/tfjs-core.d.ts"}
2022-11-17 14:37:22 INFO:  Done...
2022-11-17 14:37:22 STATE: Copy: {"input":"node_modules/@vladmandic/tfjs/types/tfjs.d.ts","output":"types/tfjs.esm.d.ts"}
2022-11-17 14:37:22 STATE: Copy: {"input":"src/types/tsconfig.json","output":"types/tsconfig.json"}
2022-11-17 14:37:22 STATE: Copy: {"input":"src/types/eslint.json","output":"types/.eslintrc.json"}
2022-11-17 14:37:22 STATE: Copy: {"input":"src/types/tfjs.esm.d.ts","output":"dist/tfjs.esm.d.ts"}
2022-11-17 14:37:22 STATE: Filter: {"input":"types/tfjs-core.d.ts"}
2022-11-17 14:37:23 STATE: API-Extractor: {"succeeeded":true,"errors":0,"warnings":195}
2022-11-17 14:37:23 STATE: Filter: {"input":"types/human.d.ts"}
2022-11-17 14:37:23 STATE: Write: {"output":"dist/human.esm-nobundle.d.ts"}
2022-11-17 14:37:23 STATE: Write: {"output":"dist/human.esm.d.ts"}
2022-11-17 14:37:23 STATE: Write: {"output":"dist/human.d.ts"}
2022-11-17 14:37:23 STATE: Write: {"output":"dist/human.node-gpu.d.ts"}
2022-11-17 14:37:23 STATE: Write: {"output":"dist/human.node.d.ts"}
2022-11-17 14:37:23 STATE: Write: {"output":"dist/human.node-wasm.d.ts"}
2022-11-17 14:37:23 INFO:  Analyze models: {"folders":8,"result":"models/models.json"}
2022-11-17 14:37:23 STATE: Models {"folder":"./models","models":12}
2022-11-17 14:37:23 STATE: Models {"folder":"../human-models/models","models":43}
2022-11-17 14:37:23 STATE: Models {"folder":"../blazepose/model/","models":4}
2022-11-17 14:37:23 STATE: Models {"folder":"../anti-spoofing/model","models":1}
2022-11-17 14:37:23 STATE: Models {"folder":"../efficientpose/models","models":3}
2022-11-17 14:37:23 STATE: Models {"folder":"../insightface/models","models":5}
2022-11-17 14:37:23 STATE: Models {"folder":"../movenet/models","models":3}
2022-11-17 14:37:23 STATE: Models {"folder":"../nanodet/models","models":4}
2022-11-17 14:37:24 STATE: Models: {"count":58,"totalSize":386543911}
2022-11-17 14:37:24 INFO:  Human Build complete... {"logFile":"test/build.log"}
2022-11-17 14:50:24 DATA:  Build {"name":"@vladmandic/human","version":"3.0.0"}
2022-11-17 14:50:24 INFO:  Application: {"name":"@vladmandic/human","version":"3.0.0"}
2022-11-17 14:50:24 INFO:  Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
2022-11-17 14:50:24 INFO:  Toolchain: {"build":"0.7.14","esbuild":"0.15.14","typescript":"4.9.3","typedoc":"0.23.21","eslint":"8.27.0"}
2022-11-17 14:50:24 INFO:  Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
2022-11-17 14:50:24 STATE: Clean: {"locations":["dist/*","types/*","typedoc/*"]}
2022-11-17 14:50:24 STATE: Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1289,"outputBytes":361}
2022-11-17 14:50:24 STATE: Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":569,"outputBytes":924}
2022-11-17 14:50:24 STATE: Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":80,"inputBytes":670091,"outputBytes":317438}
2022-11-17 14:50:24 STATE: Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":577,"outputBytes":928}
2022-11-17 14:50:24 STATE: Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":80,"inputBytes":670095,"outputBytes":317442}
2022-11-17 14:50:24 STATE: Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":665,"outputBytes":1876}
2022-11-17 14:50:24 STATE: Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":80,"inputBytes":671043,"outputBytes":317553}
2022-11-17 14:50:24 STATE: Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":1375,"outputBytes":670}
2022-11-17 14:50:24 STATE: Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":80,"inputBytes":669837,"outputBytes":316023}
2022-11-17 14:50:24 STATE: Compile: {"name":"tfjs/browser/esm/bundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":10,"inputBytes":1375,"outputBytes":1144900}
2022-11-17 14:50:25 STATE: Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":80,"inputBytes":1814067,"outputBytes":1457337}
2022-11-17 14:50:25 STATE: Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":80,"inputBytes":1814067,"outputBytes":1914669}
2022-11-17 14:50:28 STATE: Typings: {"input":"src/human.ts","output":"types/lib","files":15}
2022-11-17 14:50:30 STATE: TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":77,"generated":true}
2022-11-17 14:50:30 STATE: Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":6135,"outputBytes":2913}
2022-11-17 14:50:30 STATE: Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":17572,"outputBytes":9456}
2022-11-17 14:50:38 STATE: Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":114,"errors":0,"warnings":0}
2022-11-17 14:50:38 STATE: ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
2022-11-17 14:50:38 STATE: Copy: {"input":"node_modules/@vladmandic/tfjs/types/tfjs-core.d.ts","output":"types/tfjs-core.d.ts"}
2022-11-17 14:50:38 INFO:  Done...
2022-11-17 14:50:38 STATE: Copy: {"input":"node_modules/@vladmandic/tfjs/types/tfjs.d.ts","output":"types/tfjs.esm.d.ts"}
2022-11-17 14:50:38 STATE: Copy: {"input":"src/types/tsconfig.json","output":"types/tsconfig.json"}
2022-11-17 14:50:38 STATE: Copy: {"input":"src/types/eslint.json","output":"types/.eslintrc.json"}
2022-11-17 14:50:38 STATE: Copy: {"input":"src/types/tfjs.esm.d.ts","output":"dist/tfjs.esm.d.ts"}
2022-11-17 14:50:38 STATE: Filter: {"input":"types/tfjs-core.d.ts"}
2022-11-17 14:50:39 STATE: API-Extractor: {"succeeeded":true,"errors":0,"warnings":195}
2022-11-17 14:50:39 STATE: Filter: {"input":"types/human.d.ts"}
2022-11-17 14:50:39 STATE: Write: {"output":"dist/human.esm-nobundle.d.ts"}
2022-11-17 14:50:39 STATE: Write: {"output":"dist/human.esm.d.ts"}
2022-11-17 14:50:39 STATE: Write: {"output":"dist/human.d.ts"}
2022-11-17 14:50:39 STATE: Write: {"output":"dist/human.node-gpu.d.ts"}
2022-11-17 14:50:39 STATE: Write: {"output":"dist/human.node.d.ts"}
2022-11-17 14:50:39 STATE: Write: {"output":"dist/human.node-wasm.d.ts"}
2022-11-17 14:50:39 INFO:  Analyze models: {"folders":8,"result":"models/models.json"}
2022-11-17 14:50:39 STATE: Models {"folder":"./models","models":12}
2022-11-17 14:50:39 STATE: Models {"folder":"../human-models/models","models":43}
2022-11-17 14:50:39 STATE: Models {"folder":"../blazepose/model/","models":4}
2022-11-17 14:50:39 STATE: Models {"folder":"../anti-spoofing/model","models":1}
2022-11-17 14:50:39 STATE: Models {"folder":"../efficientpose/models","models":3}
2022-11-17 14:50:39 STATE: Models {"folder":"../insightface/models","models":5}
2022-11-17 14:50:39 STATE: Models {"folder":"../movenet/models","models":3}
2022-11-17 14:50:39 STATE: Models {"folder":"../nanodet/models","models":4}
2022-11-17 14:50:40 STATE: Models: {"count":58,"totalSize":386543911}
2022-11-17 14:50:40 INFO:  Human Build complete... {"logFile":"test/build.log"}