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