mirror of https://github.com/vladmandic/human
enforce types
parent
d7571891e7
commit
de0fffbfdc
|
@ -27,8 +27,8 @@
|
||||||
"ignorePatterns": [ "dist", "assets", "media", "models", "node_modules" ],
|
"ignorePatterns": [ "dist", "assets", "media", "models", "node_modules" ],
|
||||||
"rules": {
|
"rules": {
|
||||||
"@typescript-eslint/ban-ts-comment": "off",
|
"@typescript-eslint/ban-ts-comment": "off",
|
||||||
"@typescript-eslint/ban-types": "off",
|
|
||||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||||
|
"@typescript-eslint/ban-types": "off",
|
||||||
"@typescript-eslint/no-explicit-any": "off",
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
"@typescript-eslint/no-var-requires": "off",
|
"@typescript-eslint/no-var-requires": "off",
|
||||||
"camelcase": "off",
|
"camelcase": "off",
|
||||||
|
@ -36,7 +36,6 @@
|
||||||
"func-names": "off",
|
"func-names": "off",
|
||||||
"guard-for-in": "off",
|
"guard-for-in": "off",
|
||||||
"import/extensions": "off",
|
"import/extensions": "off",
|
||||||
"import/no-absolute-path": "off",
|
|
||||||
"import/no-extraneous-dependencies": "off",
|
"import/no-extraneous-dependencies": "off",
|
||||||
"import/no-named-as-default": "off",
|
"import/no-named-as-default": "off",
|
||||||
"import/no-unresolved": "off",
|
"import/no-unresolved": "off",
|
||||||
|
|
|
@ -11,6 +11,7 @@ Repository: **<git+https://github.com/vladmandic/human.git>**
|
||||||
|
|
||||||
### **HEAD -> main** 2021/03/17 mandic00@live.com
|
### **HEAD -> main** 2021/03/17 mandic00@live.com
|
||||||
|
|
||||||
|
- switch to single jumbo dts
|
||||||
- type definitions
|
- type definitions
|
||||||
|
|
||||||
### **1.1.9** 2021/03/17 mandic00@live.com
|
### **1.1.9** 2021/03/17 mandic00@live.com
|
||||||
|
|
152
src/config.ts
152
src/config.ts
|
@ -7,111 +7,111 @@
|
||||||
* Contains all configurable parameters
|
* Contains all configurable parameters
|
||||||
*/
|
*/
|
||||||
export interface Config {
|
export interface Config {
|
||||||
backend: String,
|
backend: string,
|
||||||
wasmPath: String,
|
wasmPath: string,
|
||||||
debug: Boolean,
|
debug: boolean,
|
||||||
async: Boolean,
|
async: boolean,
|
||||||
profile: Boolean,
|
profile: boolean,
|
||||||
deallocate: Boolean,
|
deallocate: boolean,
|
||||||
scoped: Boolean,
|
scoped: boolean,
|
||||||
videoOptimized: Boolean,
|
videoOptimized: boolean,
|
||||||
warmup: String,
|
warmup: string,
|
||||||
filter: {
|
filter: {
|
||||||
enabled: Boolean,
|
enabled: boolean,
|
||||||
width: Number,
|
width: number,
|
||||||
height: Number,
|
height: number,
|
||||||
return: Boolean,
|
return: boolean,
|
||||||
brightness: Number,
|
brightness: number,
|
||||||
contrast: Number,
|
contrast: number,
|
||||||
sharpness: Number,
|
sharpness: number,
|
||||||
blur: Number
|
blur: number
|
||||||
saturation: Number,
|
saturation: number,
|
||||||
hue: Number,
|
hue: number,
|
||||||
negative: Boolean,
|
negative: boolean,
|
||||||
sepia: Boolean,
|
sepia: boolean,
|
||||||
vintage: Boolean,
|
vintage: boolean,
|
||||||
kodachrome: Boolean,
|
kodachrome: boolean,
|
||||||
technicolor: Boolean,
|
technicolor: boolean,
|
||||||
polaroid: Boolean,
|
polaroid: boolean,
|
||||||
pixelate: Number,
|
pixelate: number,
|
||||||
},
|
},
|
||||||
gesture: {
|
gesture: {
|
||||||
enabled: Boolean,
|
enabled: boolean,
|
||||||
},
|
},
|
||||||
face: {
|
face: {
|
||||||
enabled: Boolean,
|
enabled: boolean,
|
||||||
detector: {
|
detector: {
|
||||||
modelPath: String,
|
modelPath: string,
|
||||||
rotation: Boolean,
|
rotation: boolean,
|
||||||
maxFaces: Number,
|
maxFaces: number,
|
||||||
skipFrames: Number,
|
skipFrames: number,
|
||||||
skipInitial: Boolean,
|
skipInitial: boolean,
|
||||||
minConfidence: Number,
|
minConfidence: number,
|
||||||
iouThreshold: Number,
|
iouThreshold: number,
|
||||||
scoreThreshold: Number,
|
scoreThreshold: number,
|
||||||
return: Boolean,
|
return: boolean,
|
||||||
},
|
},
|
||||||
mesh: {
|
mesh: {
|
||||||
enabled: Boolean,
|
enabled: boolean,
|
||||||
modelPath: String,
|
modelPath: string,
|
||||||
},
|
},
|
||||||
iris: {
|
iris: {
|
||||||
enabled: Boolean,
|
enabled: boolean,
|
||||||
modelPath: String,
|
modelPath: string,
|
||||||
},
|
},
|
||||||
age: {
|
age: {
|
||||||
enabled: Boolean,
|
enabled: boolean,
|
||||||
modelPath: String,
|
modelPath: string,
|
||||||
skipFrames: Number,
|
skipFrames: number,
|
||||||
},
|
},
|
||||||
gender: {
|
gender: {
|
||||||
enabled: Boolean,
|
enabled: boolean,
|
||||||
minConfidence: Number,
|
minConfidence: number,
|
||||||
modelPath: String,
|
modelPath: string,
|
||||||
skipFrames: Number,
|
skipFrames: number,
|
||||||
},
|
},
|
||||||
emotion: {
|
emotion: {
|
||||||
enabled: Boolean,
|
enabled: boolean,
|
||||||
minConfidence: Number,
|
minConfidence: number,
|
||||||
skipFrames: Number,
|
skipFrames: number,
|
||||||
modelPath: String,
|
modelPath: string,
|
||||||
},
|
},
|
||||||
embedding: {
|
embedding: {
|
||||||
enabled: Boolean,
|
enabled: boolean,
|
||||||
modelPath: String,
|
modelPath: string,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
body: {
|
body: {
|
||||||
enabled: Boolean,
|
enabled: boolean,
|
||||||
modelPath: String,
|
modelPath: string,
|
||||||
maxDetections: Number,
|
maxDetections: number,
|
||||||
scoreThreshold: Number,
|
scoreThreshold: number,
|
||||||
nmsRadius: Number,
|
nmsRadius: number,
|
||||||
},
|
},
|
||||||
hand: {
|
hand: {
|
||||||
enabled: Boolean,
|
enabled: boolean,
|
||||||
rotation: Boolean,
|
rotation: boolean,
|
||||||
skipFrames: Number,
|
skipFrames: number,
|
||||||
skipInitial: Boolean,
|
skipInitial: boolean,
|
||||||
minConfidence: Number,
|
minConfidence: number,
|
||||||
iouThreshold: Number,
|
iouThreshold: number,
|
||||||
scoreThreshold: Number,
|
scoreThreshold: number,
|
||||||
maxHands: Number,
|
maxHands: number,
|
||||||
landmarks: Boolean,
|
landmarks: boolean,
|
||||||
detector: {
|
detector: {
|
||||||
modelPath: String,
|
modelPath: string,
|
||||||
},
|
},
|
||||||
skeleton: {
|
skeleton: {
|
||||||
modelPath: String,
|
modelPath: string,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
object: {
|
object: {
|
||||||
enabled: Boolean,
|
enabled: boolean,
|
||||||
modelPath: String,
|
modelPath: string,
|
||||||
minConfidence: Number,
|
minConfidence: number,
|
||||||
iouThreshold: Number,
|
iouThreshold: number,
|
||||||
maxResults: Number,
|
maxResults: number,
|
||||||
skipFrames: Number,
|
skipFrames: number,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
58
src/human.ts
58
src/human.ts
|
@ -20,8 +20,8 @@ import { Result } from './result';
|
||||||
import * as sample from './sample';
|
import * as sample from './sample';
|
||||||
import * as app from '../package.json';
|
import * as app from '../package.json';
|
||||||
|
|
||||||
type Tensor = {};
|
type Tensor = Object;
|
||||||
type Model = {};
|
type Model = Object;
|
||||||
|
|
||||||
export type { Config } from './config';
|
export type { Config } from './config';
|
||||||
export type { Result } from './result';
|
export type { Result } from './result';
|
||||||
|
@ -29,7 +29,7 @@ export type { Result } from './result';
|
||||||
/** Defines all possible input types for **Human** detection */
|
/** Defines all possible input types for **Human** detection */
|
||||||
export type Input = Tensor | ImageData | ImageBitmap | HTMLVideoElement | HTMLCanvasElement | OffscreenCanvas;
|
export type Input = Tensor | ImageData | ImageBitmap | HTMLVideoElement | HTMLCanvasElement | OffscreenCanvas;
|
||||||
/** Error message */
|
/** Error message */
|
||||||
export type Error = { error: String };
|
export type Error = { error: string };
|
||||||
export type TensorFlow = typeof tf;
|
export type TensorFlow = typeof tf;
|
||||||
|
|
||||||
// helper function: gets elapsed time on both browser and nodejs
|
// helper function: gets elapsed time on both browser and nodejs
|
||||||
|
@ -62,9 +62,9 @@ function mergeDeep(...objects) {
|
||||||
* - Possible inputs: {@link Input}
|
* - Possible inputs: {@link Input}
|
||||||
*/
|
*/
|
||||||
export class Human {
|
export class Human {
|
||||||
version: String;
|
version: string;
|
||||||
config: Config;
|
config: Config;
|
||||||
state: String;
|
state: string;
|
||||||
image: { tensor: Tensor, canvas: OffscreenCanvas | HTMLCanvasElement };
|
image: { tensor: Tensor, canvas: OffscreenCanvas | HTMLCanvasElement };
|
||||||
// classes
|
// classes
|
||||||
tf: TensorFlow;
|
tf: TensorFlow;
|
||||||
|
@ -99,19 +99,17 @@ export class Human {
|
||||||
hand: typeof handpose;
|
hand: typeof handpose;
|
||||||
nanodet: typeof nanodet;
|
nanodet: typeof nanodet;
|
||||||
};
|
};
|
||||||
sysinfo: { platform: String, agent: String };
|
sysinfo: { platform: string, agent: string };
|
||||||
#package: any;
|
|
||||||
#perf: any;
|
#perf: any;
|
||||||
#numTensors: number;
|
#numTensors: number;
|
||||||
#analyzeMemoryLeaks: Boolean;
|
#analyzeMemoryLeaks: boolean;
|
||||||
#checkSanity: Boolean;
|
#checkSanity: boolean;
|
||||||
#firstRun: Boolean;
|
#firstRun: boolean;
|
||||||
// definition end
|
// definition end
|
||||||
|
|
||||||
constructor(userConfig: Config | Object = {}) {
|
constructor(userConfig: Config | Object = {}) {
|
||||||
this.tf = tf;
|
this.tf = tf;
|
||||||
this.draw = draw;
|
this.draw = draw;
|
||||||
this.#package = app;
|
|
||||||
this.version = app.version;
|
this.version = app.version;
|
||||||
this.config = mergeDeep(defaults, userConfig);
|
this.config = mergeDeep(defaults, userConfig);
|
||||||
this.state = 'idle';
|
this.state = 'idle';
|
||||||
|
@ -168,7 +166,7 @@ export class Human {
|
||||||
|
|
||||||
// quick sanity check on inputs
|
// quick sanity check on inputs
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
#sanity = (input): null | String => {
|
#sanity = (input): null | string => {
|
||||||
if (!this.#checkSanity) return null;
|
if (!this.#checkSanity) return null;
|
||||||
if (!input) return 'input is not defined';
|
if (!input) return 'input is not defined';
|
||||||
if (this.tf.ENV.flags.IS_NODE && !(input instanceof tf.Tensor)) return 'input must be a tensor';
|
if (this.tf.ENV.flags.IS_NODE && !(input instanceof tf.Tensor)) return 'input must be a tensor';
|
||||||
|
@ -180,7 +178,7 @@ export class Human {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
simmilarity(embedding1: Array<Number>, embedding2: Array<Number>): Number {
|
simmilarity(embedding1: Array<number>, embedding2: Array<number>): number {
|
||||||
if (this.config.face.embedding.enabled) return embedding.simmilarity(embedding1, embedding2);
|
if (this.config.face.embedding.enabled) return embedding.simmilarity(embedding1, embedding2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -191,7 +189,7 @@ export class Human {
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
match(faceEmbedding: Array<Number>, db: Array<{ name: String, source: String | undefined, embedding: Array<Number> }>, threshold = 0): { name: String, source: String | undefined, simmilarity: Number, embedding: Array<Number> } {
|
match(faceEmbedding: Array<number>, db: Array<{ name: string, source: string, embedding: number[] }>, threshold = 0): { name: string, source: string, simmilarity: number, embedding: number[] } {
|
||||||
return embedding.match(faceEmbedding, db, threshold);
|
return embedding.match(faceEmbedding, db, threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +309,7 @@ export class Human {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
#calculateFaceAngle = (mesh): { roll: Number | null, yaw: Number | null, pitch: Number | null } => {
|
#calculateFaceAngle = (mesh): { roll: number | null, yaw: number | null, pitch: number | null } => {
|
||||||
if (!mesh || mesh.length < 300) return { roll: null, yaw: null, pitch: null };
|
if (!mesh || mesh.length < 300) return { roll: null, yaw: null, pitch: null };
|
||||||
const radians = (a1, a2, b1, b2) => Math.atan2(b2 - a2, b1 - a1);
|
const radians = (a1, a2, b1, b2) => Math.atan2(b2 - a2, b1 - a1);
|
||||||
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
|
||||||
|
@ -339,21 +337,21 @@ export class Human {
|
||||||
let emotionRes;
|
let emotionRes;
|
||||||
let embeddingRes;
|
let embeddingRes;
|
||||||
const faceRes: Array<{
|
const faceRes: Array<{
|
||||||
confidence: Number,
|
confidence: number,
|
||||||
boxConfidence: Number,
|
boxConfidence: number,
|
||||||
faceConfidence: Number,
|
faceConfidence: number,
|
||||||
box: [Number, Number, Number, Number],
|
box: [number, number, number, number],
|
||||||
mesh: Array<[Number, Number, Number]>
|
mesh: Array<[number, number, number]>
|
||||||
meshRaw: Array<[Number, Number, Number]>
|
meshRaw: Array<[number, number, number]>
|
||||||
boxRaw: [Number, Number, Number, Number],
|
boxRaw: [number, number, number, number],
|
||||||
annotations: any,
|
annotations: Array<{ part: string, points: Array<[number, number, number]>[] }>,
|
||||||
age: Number,
|
age: number,
|
||||||
gender: String,
|
gender: string,
|
||||||
genderConfidence: Number,
|
genderConfidence: number,
|
||||||
emotion: String,
|
emotion: string,
|
||||||
embedding: any,
|
embedding: number[],
|
||||||
iris: Number,
|
iris: number,
|
||||||
angle: { roll: Number | null, yaw: Number | null, pitch: Number | null },
|
angle: { roll: number | null, yaw: number | null, pitch: number | null },
|
||||||
tensor: Tensor,
|
tensor: Tensor,
|
||||||
}> = [];
|
}> = [];
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ export async function load(config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function process(res, inputSize, outputShape, config) {
|
async function process(res, inputSize, outputShape, config) {
|
||||||
let results: Array<{ score: Number, strideSize: Number, class: Number, label: String, center: Number[], centerRaw: Number[], box: Number[], boxRaw: Number[] }> = [];
|
let results: Array<{ score: number, strideSize: number, class: number, label: string, center: number[], centerRaw: number[], box: number[], boxRaw: number[] }> = [];
|
||||||
for (const strideSize of [1, 2, 4]) { // try each stride size as it detects large/medium/small objects
|
for (const strideSize of [1, 2, 4]) { // try each stride size as it detects large/medium/small objects
|
||||||
// find scores, boxes, classes
|
// find scores, boxes, classes
|
||||||
tf.tidy(() => { // wrap in tidy to automatically deallocate temp tensors
|
tf.tidy(() => { // wrap in tidy to automatically deallocate temp tensors
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { log } from './log';
|
||||||
|
|
||||||
export const data = {};
|
export const data = {};
|
||||||
|
|
||||||
export function run(name: string, raw: any) {
|
export function run(name: string, raw: any): void {
|
||||||
if (!raw || !raw.kernels) return;
|
if (!raw || !raw.kernels) return;
|
||||||
const maxResults = 5;
|
const maxResults = 5;
|
||||||
const time = raw.kernels
|
const time = raw.kernels
|
||||||
|
|
|
@ -26,21 +26,21 @@ export interface Result {
|
||||||
* - angle as object with values for roll, yaw and pitch angles
|
* - angle as object with values for roll, yaw and pitch angles
|
||||||
*/
|
*/
|
||||||
face: Array<{
|
face: Array<{
|
||||||
confidence: Number,
|
confidence: number,
|
||||||
boxConfidence: Number,
|
boxConfidence: number,
|
||||||
faceConfidence: Number,
|
faceConfidence: number,
|
||||||
box: [Number, Number, Number, Number],
|
box: [number, number, number, number],
|
||||||
boxRaw: [Number, Number, Number, Number],
|
boxRaw: [number, number, number, number],
|
||||||
mesh: Array<[Number, Number, Number]>
|
mesh: Array<[number, number, number]>
|
||||||
meshRaw: Array<[Number, Number, Number]>
|
meshRaw: Array<[number, number, number]>
|
||||||
annotations: Array<{ part: String, points: Array<[Number, Number, Number]>[] }>,
|
annotations: Array<{ part: string, points: Array<[number, number, number]>[] }>,
|
||||||
age: Number,
|
age: number,
|
||||||
gender: String,
|
gender: string,
|
||||||
genderConfidence: Number,
|
genderConfidence: number,
|
||||||
emotion: Array<{ score: Number, emotion: String }>,
|
emotion: Array<{ score: number, emotion: string }>,
|
||||||
embedding: Array<Number>,
|
embedding: Array<number>,
|
||||||
iris: Number,
|
iris: number,
|
||||||
angle: { roll: Number, yaw: Number, pitch: Number },
|
angle: { roll: number, yaw: number, pitch: number },
|
||||||
}>,
|
}>,
|
||||||
/** Body results
|
/** Body results
|
||||||
*
|
*
|
||||||
|
@ -53,11 +53,11 @@ export interface Result {
|
||||||
* - body part presence value
|
* - body part presence value
|
||||||
*/
|
*/
|
||||||
body: Array<{
|
body: Array<{
|
||||||
id: Number,
|
id: number,
|
||||||
part: String,
|
part: string,
|
||||||
position: { x: Number, y: Number, z: Number },
|
position: { x: number, y: number, z: number },
|
||||||
score: Number,
|
score: number,
|
||||||
presence: Number }>,
|
presence: number }>,
|
||||||
/** Hand results
|
/** Hand results
|
||||||
*
|
*
|
||||||
* Array of individual results with one object per detected hand
|
* Array of individual results with one object per detected hand
|
||||||
|
@ -69,11 +69,11 @@ export interface Result {
|
||||||
* - annotations as array of annotated face landmark points
|
* - annotations as array of annotated face landmark points
|
||||||
*/
|
*/
|
||||||
hand: Array<{
|
hand: Array<{
|
||||||
confidence: Number,
|
confidence: number,
|
||||||
box: [Number, Number, Number, Number],
|
box: [number, number, number, number],
|
||||||
boxRaw: [Number, Number, Number, Number],
|
boxRaw: [number, number, number, number],
|
||||||
landmarks: Array<[Number, Number, Number]>,
|
landmarks: Array<[number, number, number]>,
|
||||||
annotations: Array<{ part: String, points: Array<[Number, Number, Number]>[] }>,
|
annotations: Array<{ part: string, points: Array<[number, number, number]>[] }>,
|
||||||
}>,
|
}>,
|
||||||
/** Gesture results
|
/** Gesture results
|
||||||
*
|
*
|
||||||
|
@ -83,8 +83,8 @@ export interface Result {
|
||||||
* - gesture detected
|
* - gesture detected
|
||||||
*/
|
*/
|
||||||
gesture: Array<{
|
gesture: Array<{
|
||||||
part: String,
|
part: string,
|
||||||
gesture: String,
|
gesture: string,
|
||||||
}>,
|
}>,
|
||||||
/** Object results
|
/** Object results
|
||||||
*
|
*
|
||||||
|
@ -98,14 +98,14 @@ export interface Result {
|
||||||
* - boxRaw as array of [x, y, width, height], normalized to range 0..1
|
* - boxRaw as array of [x, y, width, height], normalized to range 0..1
|
||||||
*/
|
*/
|
||||||
object: Array<{
|
object: Array<{
|
||||||
score: Number,
|
score: number,
|
||||||
strideSize: Number,
|
strideSize: number,
|
||||||
class: Number,
|
class: number,
|
||||||
label: String,
|
label: string,
|
||||||
center: Number[],
|
center: number[],
|
||||||
centerRaw: Number[],
|
centerRaw: number[],
|
||||||
box: Number[],
|
box: number[],
|
||||||
boxRaw: Number[],
|
boxRaw: number[],
|
||||||
}>,
|
}>,
|
||||||
performance: { any },
|
performance: { any },
|
||||||
canvas: OffscreenCanvas | HTMLCanvasElement,
|
canvas: OffscreenCanvas | HTMLCanvasElement,
|
||||||
|
|
|
@ -20,7 +20,7 @@ export const config = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function register() {
|
export function register(): void {
|
||||||
if (!tf.findBackend(config.name)) {
|
if (!tf.findBackend(config.name)) {
|
||||||
log('backend registration:', config.name);
|
log('backend registration:', config.name);
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in New Issue