caching improvements

pull/134/head
Vladimir Mandic 2021-05-20 19:14:07 -04:00
parent 6c36883751
commit bb69645f54
22 changed files with 4474 additions and 225958 deletions

View File

@ -9,11 +9,15 @@ Repository: **<git+https://github.com/vladmandic/human.git>**
## Changelog ## Changelog
### **human 1.9.0 beta with breaking changes regarding caching** 2021/05/18 mandic00@live.com ### **HEAD -> main** 2021/05/19 mandic00@live.com
### **origin/main** 2021/05/18 mandic00@live.com
- sanitize server input
- remove nanodet weights from default distribution
- add experimental mb3-centernet object detection
- individual model skipframes values still max high threshold for caching
- config.videooptimized has been removed and config.cachesensitivity has been added instead
- caching determination is now dynamic based on detection of input change and not based on input types
- human 1.9.0 beta with breaking changes regarding caching
### **1.8.5** 2021/05/18 mandic00@live.com ### **1.8.5** 2021/05/18 mandic00@live.com

View File

@ -6,7 +6,7 @@ N/A
## Exploring Features ## Exploring Features
N/A - Output interpolation for draw
## Explore Models ## Explore Models

View File

@ -9,7 +9,7 @@ import webRTC from './helpers/webrtc.js';
let human; let human;
const userConfig = { const userConfig = {
warmup: 'full', warmup: 'none',
/* /*
backend: 'webgl', backend: 'webgl',
async: false, async: false,
@ -54,7 +54,7 @@ const ui = {
camera: {}, // internal, holds details of webcam details camera: {}, // internal, holds details of webcam details
detectFPS: [], // internal, holds fps values for detection performance detectFPS: [], // internal, holds fps values for detection performance
drawFPS: [], // internal, holds fps values for draw performance drawFPS: [], // internal, holds fps values for draw performance
buffered: true, // should output be buffered between frames buffered: false, // should output be buffered between frames
drawWarmup: false, // debug only, should warmup image processing be displayed on startup drawWarmup: false, // debug only, should warmup image processing be displayed on startup
drawThread: null, // internl, perform draw operations in a separate thread drawThread: null, // internl, perform draw operations in a separate thread
detectThread: null, // internl, perform detect operations in a separate thread detectThread: null, // internl, perform detect operations in a separate thread

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

75891
dist/human.esm.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

75897
dist/human.js vendored

File diff suppressed because one or more lines are too long

View File

@ -127,7 +127,7 @@ var config = {
debug: true, debug: true,
async: true, async: true,
warmup: "full", warmup: "full",
cacheSensitivity: 5e-3, cacheSensitivity: 0.01,
filter: { filter: {
enabled: true, enabled: true,
width: 0, width: 0,
@ -19598,7 +19598,7 @@ lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/
var version = "1.9.0"; var version = "1.9.0";
// src/human.ts // src/human.ts
var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode; var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _lastCacheDiff, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode;
var Human = class { var Human = class {
constructor(userConfig = {}) { constructor(userConfig = {}) {
__privateAdd(this, _numTensors, void 0); __privateAdd(this, _numTensors, void 0);
@ -19606,6 +19606,7 @@ var Human = class {
__privateAdd(this, _checkSanity, void 0); __privateAdd(this, _checkSanity, void 0);
__privateAdd(this, _firstRun, void 0); __privateAdd(this, _firstRun, void 0);
__privateAdd(this, _lastInputSum, void 0); __privateAdd(this, _lastInputSum, void 0);
__privateAdd(this, _lastCacheDiff, void 0);
this.analyze = (...msg) => { this.analyze = (...msg) => {
if (!__privateGet(this, _analyzeMemoryLeaks)) if (!__privateGet(this, _analyzeMemoryLeaks))
return; return;
@ -19669,6 +19670,8 @@ var Human = class {
this.tf.enableProdMode(); this.tf.enableProdMode();
if (this.tf.getBackend() === "webgl" || this.tf.getBackend() === "humangl") { if (this.tf.getBackend() === "webgl" || this.tf.getBackend() === "humangl") {
this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS", false); this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS", false);
this.tf.ENV.set("WEBGL_CPU_FORWARD", true);
tf17.ENV.set("WEBGL_FORCE_F16_TEXTURES", true);
this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV", true); this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV", true);
if (typeof this.config["deallocate"] !== "undefined") { if (typeof this.config["deallocate"] !== "undefined") {
log("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:", true); log("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:", true);
@ -19685,15 +19688,17 @@ var Human = class {
__privateAdd(this, _skipFrame, async (input) => { __privateAdd(this, _skipFrame, async (input) => {
if (this.config.cacheSensitivity === 0) if (this.config.cacheSensitivity === 0)
return false; return false;
const resizeFact = 50; const resizeFact = 40;
const reduced = input.resizeBilinear([Math.trunc(input.shape[1] / resizeFact), Math.trunc(input.shape[2] / resizeFact)]); const reduced = input.resizeBilinear([Math.trunc(input.shape[1] / resizeFact), Math.trunc(input.shape[2] / resizeFact)]);
const sumT = this.tf.sum(reduced); const sumT = this.tf.sum(reduced);
reduced.dispose();
const sum = sumT.dataSync()[0]; const sum = sumT.dataSync()[0];
sumT.dispose(); sumT.dispose();
reduced.dispose();
const diff = Math.max(sum, __privateGet(this, _lastInputSum)) / Math.min(sum, __privateGet(this, _lastInputSum)) - 1; const diff = Math.max(sum, __privateGet(this, _lastInputSum)) / Math.min(sum, __privateGet(this, _lastInputSum)) - 1;
__privateSet(this, _lastInputSum, sum); __privateSet(this, _lastInputSum, sum);
return diff < this.config.cacheSensitivity; const skipFrame = diff < Math.max(this.config.cacheSensitivity, __privateGet(this, _lastCacheDiff));
__privateSet(this, _lastCacheDiff, diff > 4 * this.config.cacheSensitivity ? 0 : diff);
return skipFrame;
}); });
__privateAdd(this, _warmupBitmap, async () => { __privateAdd(this, _warmupBitmap, async () => {
const b64toBlob = (base64, type = "application/octet-stream") => fetch(`data:${type};base64,${base64}`).then((res2) => res2.blob()); const b64toBlob = (base64, type = "application/octet-stream") => fetch(`data:${type};base64,${base64}`).then((res2) => res2.blob());
@ -19778,6 +19783,7 @@ var Human = class {
__privateSet(this, _analyzeMemoryLeaks, false); __privateSet(this, _analyzeMemoryLeaks, false);
__privateSet(this, _checkSanity, false); __privateSet(this, _checkSanity, false);
__privateSet(this, _firstRun, true); __privateSet(this, _firstRun, true);
__privateSet(this, _lastCacheDiff, 0);
this.perf = {}; this.perf = {};
this.models = { this.models = {
face: null, face: null,
@ -20043,6 +20049,7 @@ _analyzeMemoryLeaks = new WeakMap();
_checkSanity = new WeakMap(); _checkSanity = new WeakMap();
_firstRun = new WeakMap(); _firstRun = new WeakMap();
_lastInputSum = new WeakMap(); _lastInputSum = new WeakMap();
_lastCacheDiff = new WeakMap();
_sanity = new WeakMap(); _sanity = new WeakMap();
_checkBackend = new WeakMap(); _checkBackend = new WeakMap();
_skipFrame = new WeakMap(); _skipFrame = new WeakMap();

View File

@ -128,7 +128,7 @@ var config = {
debug: true, debug: true,
async: true, async: true,
warmup: "full", warmup: "full",
cacheSensitivity: 5e-3, cacheSensitivity: 0.01,
filter: { filter: {
enabled: true, enabled: true,
width: 0, width: 0,
@ -19599,7 +19599,7 @@ lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/
var version = "1.9.0"; var version = "1.9.0";
// src/human.ts // src/human.ts
var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode; var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _lastCacheDiff, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode;
var Human = class { var Human = class {
constructor(userConfig = {}) { constructor(userConfig = {}) {
__privateAdd(this, _numTensors, void 0); __privateAdd(this, _numTensors, void 0);
@ -19607,6 +19607,7 @@ var Human = class {
__privateAdd(this, _checkSanity, void 0); __privateAdd(this, _checkSanity, void 0);
__privateAdd(this, _firstRun, void 0); __privateAdd(this, _firstRun, void 0);
__privateAdd(this, _lastInputSum, void 0); __privateAdd(this, _lastInputSum, void 0);
__privateAdd(this, _lastCacheDiff, void 0);
this.analyze = (...msg) => { this.analyze = (...msg) => {
if (!__privateGet(this, _analyzeMemoryLeaks)) if (!__privateGet(this, _analyzeMemoryLeaks))
return; return;
@ -19670,6 +19671,8 @@ var Human = class {
this.tf.enableProdMode(); this.tf.enableProdMode();
if (this.tf.getBackend() === "webgl" || this.tf.getBackend() === "humangl") { if (this.tf.getBackend() === "webgl" || this.tf.getBackend() === "humangl") {
this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS", false); this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS", false);
this.tf.ENV.set("WEBGL_CPU_FORWARD", true);
tf17.ENV.set("WEBGL_FORCE_F16_TEXTURES", true);
this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV", true); this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV", true);
if (typeof this.config["deallocate"] !== "undefined") { if (typeof this.config["deallocate"] !== "undefined") {
log("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:", true); log("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:", true);
@ -19686,15 +19689,17 @@ var Human = class {
__privateAdd(this, _skipFrame, async (input) => { __privateAdd(this, _skipFrame, async (input) => {
if (this.config.cacheSensitivity === 0) if (this.config.cacheSensitivity === 0)
return false; return false;
const resizeFact = 50; const resizeFact = 40;
const reduced = input.resizeBilinear([Math.trunc(input.shape[1] / resizeFact), Math.trunc(input.shape[2] / resizeFact)]); const reduced = input.resizeBilinear([Math.trunc(input.shape[1] / resizeFact), Math.trunc(input.shape[2] / resizeFact)]);
const sumT = this.tf.sum(reduced); const sumT = this.tf.sum(reduced);
reduced.dispose();
const sum = sumT.dataSync()[0]; const sum = sumT.dataSync()[0];
sumT.dispose(); sumT.dispose();
reduced.dispose();
const diff = Math.max(sum, __privateGet(this, _lastInputSum)) / Math.min(sum, __privateGet(this, _lastInputSum)) - 1; const diff = Math.max(sum, __privateGet(this, _lastInputSum)) / Math.min(sum, __privateGet(this, _lastInputSum)) - 1;
__privateSet(this, _lastInputSum, sum); __privateSet(this, _lastInputSum, sum);
return diff < this.config.cacheSensitivity; const skipFrame = diff < Math.max(this.config.cacheSensitivity, __privateGet(this, _lastCacheDiff));
__privateSet(this, _lastCacheDiff, diff > 4 * this.config.cacheSensitivity ? 0 : diff);
return skipFrame;
}); });
__privateAdd(this, _warmupBitmap, async () => { __privateAdd(this, _warmupBitmap, async () => {
const b64toBlob = (base64, type = "application/octet-stream") => fetch(`data:${type};base64,${base64}`).then((res2) => res2.blob()); const b64toBlob = (base64, type = "application/octet-stream") => fetch(`data:${type};base64,${base64}`).then((res2) => res2.blob());
@ -19779,6 +19784,7 @@ var Human = class {
__privateSet(this, _analyzeMemoryLeaks, false); __privateSet(this, _analyzeMemoryLeaks, false);
__privateSet(this, _checkSanity, false); __privateSet(this, _checkSanity, false);
__privateSet(this, _firstRun, true); __privateSet(this, _firstRun, true);
__privateSet(this, _lastCacheDiff, 0);
this.perf = {}; this.perf = {};
this.models = { this.models = {
face: null, face: null,
@ -20044,6 +20050,7 @@ _analyzeMemoryLeaks = new WeakMap();
_checkSanity = new WeakMap(); _checkSanity = new WeakMap();
_firstRun = new WeakMap(); _firstRun = new WeakMap();
_lastInputSum = new WeakMap(); _lastInputSum = new WeakMap();
_lastCacheDiff = new WeakMap();
_sanity = new WeakMap(); _sanity = new WeakMap();
_checkBackend = new WeakMap(); _checkBackend = new WeakMap();
_skipFrame = new WeakMap(); _skipFrame = new WeakMap();

17
dist/human.node.js vendored
View File

@ -127,7 +127,7 @@ var config = {
debug: true, debug: true,
async: true, async: true,
warmup: "full", warmup: "full",
cacheSensitivity: 5e-3, cacheSensitivity: 0.01,
filter: { filter: {
enabled: true, enabled: true,
width: 0, width: 0,
@ -19598,7 +19598,7 @@ lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/
var version = "1.9.0"; var version = "1.9.0";
// src/human.ts // src/human.ts
var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode; var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _lastCacheDiff, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode;
var Human = class { var Human = class {
constructor(userConfig = {}) { constructor(userConfig = {}) {
__privateAdd(this, _numTensors, void 0); __privateAdd(this, _numTensors, void 0);
@ -19606,6 +19606,7 @@ var Human = class {
__privateAdd(this, _checkSanity, void 0); __privateAdd(this, _checkSanity, void 0);
__privateAdd(this, _firstRun, void 0); __privateAdd(this, _firstRun, void 0);
__privateAdd(this, _lastInputSum, void 0); __privateAdd(this, _lastInputSum, void 0);
__privateAdd(this, _lastCacheDiff, void 0);
this.analyze = (...msg) => { this.analyze = (...msg) => {
if (!__privateGet(this, _analyzeMemoryLeaks)) if (!__privateGet(this, _analyzeMemoryLeaks))
return; return;
@ -19669,6 +19670,8 @@ var Human = class {
this.tf.enableProdMode(); this.tf.enableProdMode();
if (this.tf.getBackend() === "webgl" || this.tf.getBackend() === "humangl") { if (this.tf.getBackend() === "webgl" || this.tf.getBackend() === "humangl") {
this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS", false); this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS", false);
this.tf.ENV.set("WEBGL_CPU_FORWARD", true);
tf17.ENV.set("WEBGL_FORCE_F16_TEXTURES", true);
this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV", true); this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV", true);
if (typeof this.config["deallocate"] !== "undefined") { if (typeof this.config["deallocate"] !== "undefined") {
log("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:", true); log("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:", true);
@ -19685,15 +19688,17 @@ var Human = class {
__privateAdd(this, _skipFrame, async (input) => { __privateAdd(this, _skipFrame, async (input) => {
if (this.config.cacheSensitivity === 0) if (this.config.cacheSensitivity === 0)
return false; return false;
const resizeFact = 50; const resizeFact = 40;
const reduced = input.resizeBilinear([Math.trunc(input.shape[1] / resizeFact), Math.trunc(input.shape[2] / resizeFact)]); const reduced = input.resizeBilinear([Math.trunc(input.shape[1] / resizeFact), Math.trunc(input.shape[2] / resizeFact)]);
const sumT = this.tf.sum(reduced); const sumT = this.tf.sum(reduced);
reduced.dispose();
const sum = sumT.dataSync()[0]; const sum = sumT.dataSync()[0];
sumT.dispose(); sumT.dispose();
reduced.dispose();
const diff = Math.max(sum, __privateGet(this, _lastInputSum)) / Math.min(sum, __privateGet(this, _lastInputSum)) - 1; const diff = Math.max(sum, __privateGet(this, _lastInputSum)) / Math.min(sum, __privateGet(this, _lastInputSum)) - 1;
__privateSet(this, _lastInputSum, sum); __privateSet(this, _lastInputSum, sum);
return diff < this.config.cacheSensitivity; const skipFrame = diff < Math.max(this.config.cacheSensitivity, __privateGet(this, _lastCacheDiff));
__privateSet(this, _lastCacheDiff, diff > 4 * this.config.cacheSensitivity ? 0 : diff);
return skipFrame;
}); });
__privateAdd(this, _warmupBitmap, async () => { __privateAdd(this, _warmupBitmap, async () => {
const b64toBlob = (base64, type = "application/octet-stream") => fetch(`data:${type};base64,${base64}`).then((res2) => res2.blob()); const b64toBlob = (base64, type = "application/octet-stream") => fetch(`data:${type};base64,${base64}`).then((res2) => res2.blob());
@ -19778,6 +19783,7 @@ var Human = class {
__privateSet(this, _analyzeMemoryLeaks, false); __privateSet(this, _analyzeMemoryLeaks, false);
__privateSet(this, _checkSanity, false); __privateSet(this, _checkSanity, false);
__privateSet(this, _firstRun, true); __privateSet(this, _firstRun, true);
__privateSet(this, _lastCacheDiff, 0);
this.perf = {}; this.perf = {};
this.models = { this.models = {
face: null, face: null,
@ -20043,6 +20049,7 @@ _analyzeMemoryLeaks = new WeakMap();
_checkSanity = new WeakMap(); _checkSanity = new WeakMap();
_firstRun = new WeakMap(); _firstRun = new WeakMap();
_lastInputSum = new WeakMap(); _lastInputSum = new WeakMap();
_lastCacheDiff = new WeakMap();
_sanity = new WeakMap(); _sanity = new WeakMap();
_checkBackend = new WeakMap(); _checkBackend = new WeakMap();
_skipFrame = new WeakMap(); _skipFrame = new WeakMap();

59189
dist/tfjs.esm.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -49,3 +49,20 @@
2021-05-18 11:35:33 INFO:  Generate types: ["src/human.ts"] 2021-05-18 11:35:33 INFO:  Generate types: ["src/human.ts"]
2021-05-18 11:35:37 INFO:  Update Change log: ["/home/vlado/dev/human/CHANGELOG.md"] 2021-05-18 11:35:37 INFO:  Update Change log: ["/home/vlado/dev/human/CHANGELOG.md"]
2021-05-18 11:35:37 INFO:  Generate TypeDocs: ["src/human.ts"] 2021-05-18 11:35:37 INFO:  Generate TypeDocs: ["src/human.ts"]
2021-05-20 19:13:20 INFO:  @vladmandic/human version 1.9.0
2021-05-20 19:13:20 INFO:  User: vlado Platform: linux Arch: x64 Node: v16.0.0
2021-05-20 19:13:20 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true}
2021-05-20 19:13:21 STATE: Build for: node type: tfjs: {"imports":1,"importBytes":39,"outputBytes":1292,"outputFiles":"dist/tfjs.esm.js"}
2021-05-20 19:13:21 STATE: Build for: node type: node: {"imports":36,"importBytes":418558,"outputBytes":377904,"outputFiles":"dist/human.node.js"}
2021-05-20 19:13:21 STATE: Build for: nodeGPU type: tfjs: {"imports":1,"importBytes":43,"outputBytes":1300,"outputFiles":"dist/tfjs.esm.js"}
2021-05-20 19:13:21 STATE: Build for: nodeGPU type: node: {"imports":36,"importBytes":418566,"outputBytes":377908,"outputFiles":"dist/human.node-gpu.js"}
2021-05-20 19:13:21 STATE: Build for: nodeWASM type: tfjs: {"imports":1,"importBytes":81,"outputBytes":1367,"outputFiles":"dist/tfjs.esm.js"}
2021-05-20 19:13:21 STATE: Build for: nodeWASM type: node: {"imports":36,"importBytes":418633,"outputBytes":377980,"outputFiles":"dist/human.node-wasm.js"}
2021-05-20 19:13:21 STATE: Build for: browserNoBundle type: tfjs: {"imports":1,"importBytes":2488,"outputBytes":1394,"outputFiles":"dist/tfjs.esm.js"}
2021-05-20 19:13:21 STATE: Build for: browserNoBundle type: esm: {"imports":36,"importBytes":418660,"outputBytes":232241,"outputFiles":"dist/human.esm-nobundle.js"}
2021-05-20 19:13:22 STATE: Build for: browserBundle type: tfjs: {"modules":1274,"moduleBytes":4114813,"imports":7,"importBytes":2488,"outputBytes":1111414,"outputFiles":"dist/tfjs.esm.js"}
2021-05-20 19:13:22 STATE: Build for: browserBundle type: iife: {"imports":36,"importBytes":1528680,"outputBytes":1340102,"outputFiles":"dist/human.js"}
2021-05-20 19:13:23 STATE: Build for: browserBundle type: esm: {"imports":36,"importBytes":1528680,"outputBytes":1340094,"outputFiles":"dist/human.esm.js"}
2021-05-20 19:13:23 INFO:  Generate types: ["src/human.ts"]
2021-05-20 19:13:28 INFO:  Update Change log: ["/home/vlado/dev/human/CHANGELOG.md"]
2021-05-20 19:13:28 INFO:  Generate TypeDocs: ["src/human.ts"]

View File

@ -201,7 +201,7 @@ const config: Config = {
// warmup pre-initializes all models for faster inference but can take // warmup pre-initializes all models for faster inference but can take
// significant time on startup // significant time on startup
// only used for `webgl` and `humangl` backends // only used for `webgl` and `humangl` backends
cacheSensitivity: 0.005, // cache sensitivity cacheSensitivity: 0.01, // cache sensitivity
// values 0..1 where 0.01 means reset cache if input changed more than 1% // values 0..1 where 0.01 means reset cache if input changed more than 1%
// set to 0 to disable caching // set to 0 to disable caching
filter: { // run input through image filters before inference filter: { // run input through image filters before inference

View File

@ -119,7 +119,8 @@ export class Human {
#analyzeMemoryLeaks: boolean; #analyzeMemoryLeaks: boolean;
#checkSanity: boolean; #checkSanity: boolean;
#firstRun: boolean; #firstRun: boolean;
#lastInputSum: number #lastInputSum: number;
#lastCacheDiff: number;
// definition end // definition end
@ -137,6 +138,7 @@ export class Human {
this.#analyzeMemoryLeaks = false; this.#analyzeMemoryLeaks = false;
this.#checkSanity = false; this.#checkSanity = false;
this.#firstRun = true; this.#firstRun = true;
this.#lastCacheDiff = 0;
this.perf = {}; this.perf = {};
// object that contains all initialized models // object that contains all initialized models
this.models = { this.models = {
@ -335,6 +337,8 @@ export class Human {
// this.tf.enableDebugMode(); // this.tf.enableDebugMode();
if (this.tf.getBackend() === 'webgl' || this.tf.getBackend() === 'humangl') { if (this.tf.getBackend() === 'webgl' || this.tf.getBackend() === 'humangl') {
this.tf.ENV.set('CHECK_COMPUTATION_FOR_ERRORS', false); this.tf.ENV.set('CHECK_COMPUTATION_FOR_ERRORS', false);
this.tf.ENV.set('WEBGL_CPU_FORWARD', true);
tf.ENV.set('WEBGL_FORCE_F16_TEXTURES', true);
this.tf.ENV.set('WEBGL_PACK_DEPTHWISECONV', true); this.tf.ENV.set('WEBGL_PACK_DEPTHWISECONV', true);
if (typeof this.config['deallocate'] !== 'undefined') { if (typeof this.config['deallocate'] !== 'undefined') {
log('changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:', true); log('changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:', true);
@ -352,15 +356,27 @@ export class Human {
/** @hidden */ /** @hidden */
#skipFrame = async (input) => { #skipFrame = async (input) => {
if (this.config.cacheSensitivity === 0) return false; if (this.config.cacheSensitivity === 0) return false;
const resizeFact = 50; const resizeFact = 40;
const reduced = input.resizeBilinear([Math.trunc(input.shape[1] / resizeFact), Math.trunc(input.shape[2] / resizeFact)]); const reduced = input.resizeBilinear([Math.trunc(input.shape[1] / resizeFact), Math.trunc(input.shape[2] / resizeFact)]);
// use tensor sum
const sumT = this.tf.sum(reduced); const sumT = this.tf.sum(reduced);
reduced.dispose();
const sum = sumT.dataSync()[0] as number; const sum = sumT.dataSync()[0] as number;
sumT.dispose(); sumT.dispose();
// use js loop sum
/*
const reducedData = reduced.dataSync();
let sum = 0;
for (let i = 0; i < reducedData.length; i++) sum += reducedData[i];
*/
reduced.dispose();
const diff = Math.max(sum, this.#lastInputSum) / Math.min(sum, this.#lastInputSum) - 1; const diff = Math.max(sum, this.#lastInputSum) / Math.min(sum, this.#lastInputSum) - 1;
this.#lastInputSum = sum; this.#lastInputSum = sum;
return diff < this.config.cacheSensitivity; // if previous frame was skipped, skip this frame if changed more than cacheSensitivity
// if previous frame was not skipped, then look for cacheSensitivity or difference larger than one in previous frame to avoid resetting cache in subsequent frames unnecessarily
const skipFrame = diff < Math.max(this.config.cacheSensitivity, this.#lastCacheDiff);
// if difference is above 4x threshold, don't use last value to force reset cache for significant change of scenes or images
this.#lastCacheDiff = diff > 4 * this.config.cacheSensitivity ? 0 : diff;
return skipFrame;
} }
/** Main detection method /** Main detection method

File diff suppressed because one or more lines are too long

View File

@ -161,7 +161,7 @@
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class"> <section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class">
<a name="classes" class="tsd-anchor"></a> <a name="classes" class="tsd-anchor"></a>
<h3>classes</h3> <h3>classes</h3>
<div class="tsd-signature tsd-kind-icon">classes<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">{ </span>body<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol">; </span>emotion<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol">; </span>facemesh<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol">; </span>faceres<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol">; </span>hand<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol">; </span>nanodet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol"> }</span></div> <div class="tsd-signature tsd-kind-icon">classes<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">{ </span>body<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol">; </span>centernet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol">; </span>emotion<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol">; </span>facemesh<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol">; </span>faceres<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol">; </span>hand<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol">; </span>nanodet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol"> }</span></div>
<aside class="tsd-sources"> <aside class="tsd-sources">
</aside> </aside>
<div class="tsd-comment tsd-typography"> <div class="tsd-comment tsd-typography">
@ -175,6 +175,9 @@
<li class="tsd-parameter"> <li class="tsd-parameter">
<h5>body<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">__module</span></h5> <h5>body<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">__module</span></h5>
</li> </li>
<li class="tsd-parameter">
<h5>centernet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span></h5>
</li>
<li class="tsd-parameter"> <li class="tsd-parameter">
<h5>emotion<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span></h5> <h5>emotion<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">__module</span></h5>
</li> </li>
@ -445,7 +448,7 @@
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class"> <section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class">
<a name="models" class="tsd-anchor"></a> <a name="models" class="tsd-anchor"></a>
<h3>models</h3> <h3>models</h3>
<div class="tsd-signature tsd-kind-icon">models<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">{ </span>age<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>blazepose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>efficientpose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>embedding<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>emotion<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>face<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">[</span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">]</span><span class="tsd-signature-symbol">; </span>faceres<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>gender<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>handpose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">[</span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">]</span><span class="tsd-signature-symbol">; </span>iris<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>nanodet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>posenet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol"> }</span></div> <div class="tsd-signature tsd-kind-icon">models<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">{ </span>age<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>blazepose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>centernet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>efficientpose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>embedding<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>emotion<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>face<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">[</span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">]</span><span class="tsd-signature-symbol">; </span>faceres<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>gender<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>handpose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">[</span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">]</span><span class="tsd-signature-symbol">; </span>iris<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>nanodet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>posenet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol"> }</span></div>
<aside class="tsd-sources"> <aside class="tsd-sources">
</aside> </aside>
<div class="tsd-comment tsd-typography"> <div class="tsd-comment tsd-typography">
@ -462,6 +465,9 @@
<li class="tsd-parameter"> <li class="tsd-parameter">
<h5>blazepose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5> <h5>blazepose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5>
</li> </li>
<li class="tsd-parameter">
<h5>centernet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5>
</li>
<li class="tsd-parameter"> <li class="tsd-parameter">
<h5>efficientpose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5> <h5>efficientpose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5>
</li> </li>

5
types/human.d.ts vendored
View File

@ -7,7 +7,8 @@ import * as emotion from './emotion/emotion';
import * as posenet from './posenet/posenet'; import * as posenet from './posenet/posenet';
import * as handpose from './handpose/handpose'; import * as handpose from './handpose/handpose';
import * as blazepose from './blazepose/blazepose'; import * as blazepose from './blazepose/blazepose';
import * as nanodet from './nanodet/nanodet'; import * as nanodet from './object/nanodet';
import * as centernet from './object/centernet';
import * as draw from './draw/draw'; import * as draw from './draw/draw';
/** Generic Tensor object type */ /** Generic Tensor object type */
export declare type Tensor = typeof tf.Tensor; export declare type Tensor = typeof tf.Tensor;
@ -84,6 +85,7 @@ export declare class Human {
emotion: Model | null; emotion: Model | null;
embedding: Model | null; embedding: Model | null;
nanodet: Model | null; nanodet: Model | null;
centernet: Model | null;
faceres: Model | null; faceres: Model | null;
}; };
/** Internal: Currently loaded classes */ /** Internal: Currently loaded classes */
@ -93,6 +95,7 @@ export declare class Human {
body: typeof posenet | typeof blazepose; body: typeof posenet | typeof blazepose;
hand: typeof handpose; hand: typeof handpose;
nanodet: typeof nanodet; nanodet: typeof nanodet;
centernet: typeof centernet;
faceres: typeof faceres; faceres: typeof faceres;
}; };
/** Face triangualtion array of 468 points, used for triangle references between points */ /** Face triangualtion array of 468 points, used for triangle references between points */

2
types/object/nanodet.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
export declare function load(config: any): Promise<any>;
export declare function predict(image: any, config: any): Promise<unknown>;