mirror of https://github.com/vladmandic/human
added human.env diagnostic class
parent
f6724de956
commit
7fa09937b4
|
@ -13,16 +13,23 @@ assignees: vladmandic
|
|||
|
||||
**Expected Behavior**
|
||||
|
||||
**Environment
|
||||
**Environment**
|
||||
|
||||
- Module version?
|
||||
- Human library version?
|
||||
- Built-in demo or custom code?
|
||||
- Type of module used (e.g. `js`, `esm`, `esm-nobundle`)?
|
||||
- Browser or NodeJS and version (e.g. NodeJS 14.15 or Chrome 89)?
|
||||
- OS and Hardware platform (e.g. Windows 10, Ubuntu Linux on x64, Android 10)?
|
||||
- Packager (if any) (e.g, webpack, rollup, parcel, esbuild, etc.)?
|
||||
- TensorFlow/JS version (if not using bundled module)?
|
||||
- Browser or NodeJS and version (e.g. *NodeJS 14.15* or *Chrome 89*)?
|
||||
- OS and Hardware platform (e.g. *Windows 10*, *Ubuntu Linux on x64*, *Android 10*)?
|
||||
- Packager (if any) (e.g, *webpack*, *rollup*, *parcel*, *esbuild*, etc.)?
|
||||
- Framework (if any) (e.g. *React*, *NextJS*, etc.)?
|
||||
|
||||
**Diagnostics**
|
||||
|
||||
- Check out any applicable [diagnostic steps](https://github.com/vladmandic/human/wiki/Diag)
|
||||
|
||||
**Additional**
|
||||
|
||||
- For installation or startup issues include your `package.json`
|
||||
- For usage issues, it is recommended to post your code as [gist](https://gist.github.com/)
|
||||
- For general questions, create a [discussion topic](https://github.com/vladmandic/human/discussions)
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
### **HEAD -> main** 2021/09/12 mandic00@live.com
|
||||
|
||||
- release candidate
|
||||
- parametrize face config
|
||||
- mark all config items as optional
|
||||
- redefine config and result interfaces
|
||||
- fix usge of string enums
|
||||
|
|
|
@ -72,6 +72,7 @@ Check out [**Live Demo**](https://vladmandic.github.io/human/demo/index.html) ap
|
|||
- [**Performance Notes**](https://github.com/vladmandic/human/wiki/Performance)
|
||||
- [**Performance Profiling**](https://github.com/vladmandic/human/wiki/Profiling)
|
||||
- [**Platform Support**](https://github.com/vladmandic/human/wiki/Platforms)
|
||||
- [**Diagnostic and Performance trace information**](https://github.com/vladmandic/human/wiki/Diag)
|
||||
- [**List of Models & Credits**](https://github.com/vladmandic/human/wiki/Models)
|
||||
- [**Security & Privacy Policy**](https://github.com/vladmandic/human/blob/main/SECURITY.md)
|
||||
- [**License & Usage Restrictions**](https://github.com/vladmandic/human/blob/main/LICENSE)
|
||||
|
@ -309,6 +310,12 @@ For more info, see [**Configuration Details**](https://github.com/vladmandic/hum
|
|||
|
||||
<br><hr><br>
|
||||
|
||||
## Diagnostics
|
||||
|
||||
- [How to get diagnostic information or performance trace information](https://github.com/vladmandic/human/wiki/Diag)
|
||||
|
||||
<br><hr><br>
|
||||
|
||||
`Human` library is written in `TypeScript` [4.3](https://www.typescriptlang.org/docs/handbook/intro.html)
|
||||
Conforming to `JavaScript` [ECMAScript version 2020](https://www.ecma-international.org/ecma-262/11.0/index.html) standard
|
||||
Build target is `JavaScript` [EMCAScript version 2018](https://262.ecma-international.org/9.0/)
|
||||
|
|
|
@ -953,8 +953,7 @@ async function main() {
|
|||
|
||||
// create instance of human
|
||||
human = new Human(userConfig);
|
||||
log('human version:', Human.version);
|
||||
log('tfjs version:', human.tf.version.tfjs);
|
||||
log('human version:', human.version);
|
||||
userConfig = { ...human.config, ...userConfig };
|
||||
if (typeof tf !== 'undefined') {
|
||||
// eslint-disable-next-line no-undef
|
||||
|
@ -962,6 +961,7 @@ async function main() {
|
|||
// eslint-disable-next-line no-undef
|
||||
human.tf = tf; // use externally loaded version of tfjs
|
||||
}
|
||||
log('tfjs version:', human.tf.version.tfjs);
|
||||
|
||||
// setup main menu
|
||||
await setupMenu();
|
||||
|
@ -1013,6 +1013,8 @@ async function main() {
|
|||
log('overriding images list:', JSON.parse(params.get('images')));
|
||||
await detectSampleImages();
|
||||
}
|
||||
|
||||
if (human.config.debug) log('environment:', human.env);
|
||||
}
|
||||
|
||||
window.onload = main;
|
||||
|
|
|
@ -246,9 +246,11 @@ export interface Config {
|
|||
*
|
||||
*/
|
||||
const config: Config = {
|
||||
backend: 'humangl', // select tfjs backend to use, leave empty to use default backend
|
||||
backend: '', // select tfjs backend to use, leave empty to use default backend
|
||||
// can be 'webgl', 'wasm', 'cpu', or 'humangl' which is a custom version of webgl
|
||||
modelBasePath: '../models/', // base path for all models
|
||||
// default set to `humangl` for browsers and `tensorflow` for nodejs
|
||||
modelBasePath: '', // base path for all models
|
||||
// default set to `../models/` for browsers and `file://models/` for nodejs
|
||||
wasmPath: '', // path for wasm binaries, only used for backend: wasm
|
||||
// default set to download from jsdeliv during Human class instantiation
|
||||
debug: true, // print additional status messages to console
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
import * as tf from '../dist/tfjs.esm.js';
|
||||
|
||||
export interface Env {
|
||||
browser: undefined | boolean,
|
||||
node: undefined | boolean,
|
||||
worker: undefined | boolean,
|
||||
platform: undefined | string,
|
||||
agent: undefined | string,
|
||||
backends: string[],
|
||||
tfjs: {
|
||||
version: undefined | string,
|
||||
external: undefined | boolean,
|
||||
},
|
||||
wasm: {
|
||||
supported: undefined | boolean,
|
||||
simd: undefined | boolean,
|
||||
multithread: undefined | boolean,
|
||||
},
|
||||
webgl: {
|
||||
supported: undefined | boolean,
|
||||
version: undefined | string,
|
||||
renderer: undefined | string,
|
||||
},
|
||||
webgpu: {
|
||||
supported: undefined | boolean,
|
||||
adapter: undefined | string,
|
||||
},
|
||||
kernels: string[],
|
||||
}
|
||||
|
||||
export const env: Env = {
|
||||
browser: undefined,
|
||||
node: undefined,
|
||||
worker: undefined,
|
||||
platform: undefined,
|
||||
agent: undefined,
|
||||
backends: [],
|
||||
tfjs: {
|
||||
version: undefined,
|
||||
external: undefined,
|
||||
},
|
||||
wasm: {
|
||||
supported: undefined,
|
||||
simd: undefined,
|
||||
multithread: undefined,
|
||||
},
|
||||
webgl: {
|
||||
supported: undefined,
|
||||
version: undefined,
|
||||
renderer: undefined,
|
||||
},
|
||||
webgpu: {
|
||||
supported: undefined,
|
||||
adapter: undefined,
|
||||
},
|
||||
kernels: [],
|
||||
};
|
||||
|
||||
export function cpuinfo() {
|
||||
const cpu = { model: '', flags: [] };
|
||||
if (env.node && env.platform?.startsWith('linux')) {
|
||||
// eslint-disable-next-line global-require
|
||||
const fs = require('fs');
|
||||
try {
|
||||
const data = fs.readFileSync('/proc/cpuinfo').toString();
|
||||
for (const line of data.split('\n')) {
|
||||
if (line.startsWith('model name')) {
|
||||
cpu.model = line.match(/:(.*)/g)[0].replace(':', '').trim();
|
||||
}
|
||||
if (line.startsWith('flags')) {
|
||||
cpu.flags = line.match(/:(.*)/g)[0].replace(':', '').trim().split(' ').sort();
|
||||
}
|
||||
}
|
||||
} catch { /**/ }
|
||||
}
|
||||
if (!env['cpu']) Object.defineProperty(env, 'cpu', { value: cpu });
|
||||
else env['cpu'] = cpu;
|
||||
}
|
||||
|
||||
export async function get() {
|
||||
env.browser = typeof navigator !== 'undefined';
|
||||
env.node = typeof process !== 'undefined';
|
||||
// @ts-ignore WorkerGlobalScope evaluated in browser only
|
||||
env.worker = env.browser ? (typeof WorkerGlobalScope !== 'undefined') : undefined;
|
||||
env.tfjs.version = tf.version_core;
|
||||
|
||||
// get platform and agent
|
||||
if (typeof navigator !== 'undefined') {
|
||||
const raw = navigator.userAgent.match(/\(([^()]+)\)/g);
|
||||
if (raw && raw[0]) {
|
||||
const platformMatch = raw[0].match(/\(([^()]+)\)/g);
|
||||
env.platform = (platformMatch && platformMatch[0]) ? platformMatch[0].replace(/\(|\)/g, '') : '';
|
||||
env.agent = navigator.userAgent.replace(raw[0], '');
|
||||
if (env.platform[1]) env.agent = env.agent.replace(raw[1], '');
|
||||
env.agent = env.agent.replace(/ /g, ' ');
|
||||
}
|
||||
} else if (typeof process !== 'undefined') {
|
||||
env.platform = `${process.platform} ${process.arch}`;
|
||||
env.agent = `NodeJS ${process.version}`;
|
||||
}
|
||||
|
||||
// analyze backends
|
||||
env.backends = Object.keys(tf.engine().registryFactory);
|
||||
env.wasm.supported = env.backends.includes('wasm');
|
||||
if (env.wasm.supported) {
|
||||
env.wasm.simd = await tf.env().getAsync('WASM_HAS_SIMD_SUPPORT');
|
||||
env.wasm.multithread = await tf.env().getAsync('WASM_HAS_MULTITHREAD_SUPPORT');
|
||||
}
|
||||
|
||||
env.webgl.supported = typeof tf.backend().gpgpu !== 'undefined';
|
||||
if (env.webgl.supported) {
|
||||
// @ts-ignore getGPGPUContext only exists on WebGL backend
|
||||
const gl = await tf.backend().getGPGPUContext().gl;
|
||||
if (gl) {
|
||||
env.webgl.version = gl.getParameter(gl.VERSION);
|
||||
env.webgl.renderer = gl.getParameter(gl.RENDERER);
|
||||
}
|
||||
}
|
||||
|
||||
env.webgpu.supported = env.browser && typeof navigator['gpu'] !== 'undefined';
|
||||
if (env.webgpu.supported) env.webgpu.adapter = (await navigator['gpu'].requestAdapter())?.name;
|
||||
|
||||
// enumerate kernels
|
||||
env.kernels = tf.getKernelsForBackend(tf.getBackend()).map((kernel) => kernel.kernelName);
|
||||
|
||||
// get cpu info
|
||||
// cpuinfo();
|
||||
}
|
30
src/human.ts
30
src/human.ts
|
@ -5,7 +5,6 @@
|
|||
import { log, now, mergeDeep } from './helpers';
|
||||
import { Config, defaults } from './config';
|
||||
import { Result, FaceResult, HandResult, BodyResult, ObjectResult, GestureResult } from './result';
|
||||
import * as sysinfo from './sysinfo';
|
||||
import * as tf from '../dist/tfjs.esm.js';
|
||||
import * as backend from './tfjs/backend';
|
||||
import * as models from './models';
|
||||
|
@ -26,6 +25,7 @@ import * as draw from './draw/draw';
|
|||
import * as persons from './persons';
|
||||
import * as interpolate from './interpolate';
|
||||
import * as sample from './sample';
|
||||
import * as env from './env';
|
||||
import * as app from '../package.json';
|
||||
import { Tensor, GraphModel } from './tfjs/types';
|
||||
|
||||
|
@ -33,6 +33,7 @@ import { Tensor, GraphModel } from './tfjs/types';
|
|||
export * from './config';
|
||||
export * from './result';
|
||||
export type { DrawOptions } from './draw/draw';
|
||||
export { env } from './env';
|
||||
|
||||
/** Defines all possible input types for **Human** detection
|
||||
* @typedef Input Type
|
||||
|
@ -93,6 +94,10 @@ export class Human {
|
|||
* - Can be embedded or externally provided
|
||||
*/
|
||||
tf: TensorFlow;
|
||||
/**
|
||||
* Object containing environment information used for diagnostics
|
||||
*/
|
||||
env: env.Env;
|
||||
/** Draw helper classes that can draw detected objects on canvas using specified draw
|
||||
* - options: {@link DrawOptions} global settings for all draw operations, can be overriden for each draw method
|
||||
* - face: draw detected faces
|
||||
|
@ -141,8 +146,6 @@ export class Human {
|
|||
faceTriangulation: typeof facemesh.triangulation;
|
||||
/** Refernce UV map of 468 values, used for 3D mapping of the face mesh */
|
||||
faceUVMap: typeof facemesh.uvmap;
|
||||
/** Platform and agent information detected by Human */
|
||||
sysinfo: { platform: string, agent: string };
|
||||
/** Performance object that contains values for all recently performed operations */
|
||||
performance: Record<string, number>; // perf members are dynamically defined as needed
|
||||
#numTensors: number;
|
||||
|
@ -159,9 +162,13 @@ export class Human {
|
|||
* @param userConfig: {@link Config}
|
||||
*/
|
||||
constructor(userConfig?: Partial<Config>) {
|
||||
env.get();
|
||||
this.env = env.env;
|
||||
defaults.wasmPath = `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf.version_core}/dist/`;
|
||||
defaults.modelBasePath = this.env.browser ? '../models/' : 'file://models/';
|
||||
defaults.backend = this.env.browser ? 'humangl' : 'tensorflow';
|
||||
this.version = app.version; // expose version property on instance of class
|
||||
Object.defineProperty(this, 'version', { value: app.version }); // expose version property directly on class itself
|
||||
defaults.wasmPath = `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${tf.version_core}/dist/`;
|
||||
this.config = mergeDeep(defaults, userConfig || {});
|
||||
this.tf = tf;
|
||||
this.draw = draw;
|
||||
|
@ -199,7 +206,6 @@ export class Human {
|
|||
this.faceTriangulation = facemesh.triangulation;
|
||||
this.faceUVMap = facemesh.uvmap;
|
||||
// include platform info
|
||||
this.sysinfo = sysinfo.info();
|
||||
this.#lastInputSum = 1;
|
||||
this.#emit('create');
|
||||
}
|
||||
|
@ -287,10 +293,9 @@ export class Human {
|
|||
if (this.#firstRun) { // 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(`tfjs version: ${this.tf.version_core}`);
|
||||
if (this.config.debug) log('platform:', this.sysinfo.platform);
|
||||
if (this.config.debug) log('agent:', this.sysinfo.agent);
|
||||
if (this.config.debug) log('environment:', env.env);
|
||||
|
||||
await this.#checkBackend(true);
|
||||
await this.#checkBackend();
|
||||
if (this.tf.ENV.flags.IS_BROWSER) {
|
||||
if (this.config.debug) log('configuration:', this.config);
|
||||
if (this.config.debug) log('tf flags:', this.tf.ENV.flags);
|
||||
|
@ -316,8 +321,8 @@ export class Human {
|
|||
|
||||
// check if backend needs initialization if it changed
|
||||
/** @hidden */
|
||||
#checkBackend = async (force = false) => {
|
||||
if (this.config.backend && (this.config.backend.length > 0) && force || (this.tf.getBackend() !== this.config.backend)) {
|
||||
#checkBackend = async () => {
|
||||
if (this.#firstRun || (this.config.backend && (this.config.backend.length > 0) || (this.tf.getBackend() !== this.config.backend))) {
|
||||
const timeStamp = now();
|
||||
this.state = 'backend';
|
||||
/* force backend reload
|
||||
|
@ -343,7 +348,7 @@ export class Human {
|
|||
this.config.backend = 'humangl';
|
||||
}
|
||||
if (this.tf.ENV.flags.IS_NODE && (this.config.backend === 'webgl' || this.config.backend === 'humangl')) {
|
||||
log('override: backend set to webgl while running in nodejs');
|
||||
log(`override: backend set to ${this.config.backend} while running in nodejs`);
|
||||
this.config.backend = 'tensorflow';
|
||||
}
|
||||
|
||||
|
@ -410,6 +415,9 @@ export class Human {
|
|||
this.tf.enableProdMode();
|
||||
await this.tf.ready();
|
||||
this.performance.backend = Math.trunc(now() - timeStamp);
|
||||
|
||||
env.get(); // update env on backend init
|
||||
this.env = env.env;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
wiki
2
wiki
|
@ -1 +1 @@
|
|||
Subproject commit ec49beb9f19c0abde3e62b24ba2c7749ef54c9aa
|
||||
Subproject commit ee12bda3113d3d893c898a9827f9c174d4058fb8
|
Loading…
Reference in New Issue