Compare commits
24 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
a6fd9a41c1 | |
![]() |
7e7c6d2ea2 | |
![]() |
5208b9ec2d | |
![]() |
f515b9c20d | |
![]() |
5a51889edb | |
![]() |
745fd626a3 | |
![]() |
c1dc719a67 | |
![]() |
2b0a2fecc2 | |
![]() |
38922fe92d | |
![]() |
c80540a934 | |
![]() |
49b25830b4 | |
![]() |
df73c8247f | |
![]() |
dd186ab065 | |
![]() |
a2acfc433e | |
![]() |
644235433d | |
![]() |
42dfe18736 | |
![]() |
c5b7b43fca | |
![]() |
715210db51 | |
![]() |
9e2c612c1f | |
![]() |
862de3e6c8 | |
![]() |
1114014bfd | |
![]() |
001a3d58ea | |
![]() |
d7e66afe1f | |
![]() |
a2fedaba40 |
|
@ -1,9 +1,8 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
||||
"mainEntryPointFilePath": "types/lib/src/human.d.ts",
|
||||
"bundledPackages": ["@tensorflow/tfjs-core", "@tensorflow/tfjs-data", "@tensorflow/tfjs-layers", "@tensorflow/tfjs-converter"],
|
||||
"compiler": {
|
||||
"skipLibCheck": false
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"newlineKind": "lf",
|
||||
"dtsRollup": {
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
{
|
||||
"globals": {},
|
||||
"globals": {
|
||||
},
|
||||
"rules": {
|
||||
"@typescript-eslint/no-require-imports":"off"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["**/*.ts"],
|
||||
|
@ -34,6 +38,8 @@
|
|||
"@typescript-eslint/no-unsafe-call":"off",
|
||||
"@typescript-eslint/no-unsafe-member-access":"off",
|
||||
"@typescript-eslint/no-unsafe-return":"off",
|
||||
"@typescript-eslint/no-require-imports":"off",
|
||||
"@typescript-eslint/no-empty-object-type":"off",
|
||||
"@typescript-eslint/non-nullable-type-assertion-style":"off",
|
||||
"@typescript-eslint/prefer-for-of":"off",
|
||||
"@typescript-eslint/prefer-nullish-coalescing":"off",
|
||||
|
@ -155,9 +161,7 @@
|
|||
"node": false,
|
||||
"es2021": false
|
||||
},
|
||||
"extends": [
|
||||
"plugin:json/recommended"
|
||||
]
|
||||
"extends": []
|
||||
},
|
||||
{
|
||||
"files": ["**/*.html"],
|
||||
|
@ -173,6 +177,7 @@
|
|||
"extends": ["plugin:@html-eslint/recommended"],
|
||||
"rules": {
|
||||
"@html-eslint/element-newline":"off",
|
||||
"@html-eslint/attrs-newline":"off",
|
||||
"@html-eslint/indent": ["error", 2]
|
||||
}
|
||||
},
|
||||
|
|
|
@ -5,3 +5,5 @@ package-lock.json
|
|||
*.swp
|
||||
samples/**/*.mp4
|
||||
samples/**/*.webm
|
||||
temp
|
||||
tmp
|
||||
|
|
1
.npmrc
|
@ -2,3 +2,4 @@ force=true
|
|||
omit=dev
|
||||
legacy-peer-deps=true
|
||||
strict-peer-dependencies=false
|
||||
node-options='--no-deprecation'
|
||||
|
|
38
CHANGELOG.md
|
@ -1,6 +1,6 @@
|
|||
# @vladmandic/human
|
||||
|
||||
Version: **3.2.1**
|
||||
Version: **3.3.5**
|
||||
Description: **Human: AI-powered 3D Face Detection & Rotation Tracking, Face Description & Recognition, Body Pose Tracking, 3D Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction, Gesture Recognition**
|
||||
|
||||
Author: **Vladimir Mandic <mandic00@live.com>**
|
||||
|
@ -9,12 +9,42 @@
|
|||
|
||||
## Changelog
|
||||
|
||||
### **3.3.5** 2025/02/05 mandic00@live.com
|
||||
|
||||
|
||||
### **origin/main** 2024/10/24 mandic00@live.com
|
||||
|
||||
- add human.draw.tensor method
|
||||
|
||||
### **3.3.4** 2024/10/24 mandic00@live.com
|
||||
|
||||
|
||||
### **3.3.3** 2024/10/14 mandic00@live.com
|
||||
|
||||
- add loaded property to model stats and mark models not loaded correctly.
|
||||
- release build
|
||||
|
||||
### **3.3.2** 2024/09/11 mandic00@live.com
|
||||
|
||||
- full rebuild
|
||||
|
||||
### **3.3.1** 2024/09/11 mandic00@live.com
|
||||
|
||||
- add config.face.detector.square option
|
||||
- human 3.3 alpha test run
|
||||
- human 3.3 alpha with new build environment
|
||||
- release rebuild
|
||||
- fix flazeface tensor scale and update build platform
|
||||
|
||||
### **3.2.2** 2024/04/17 mandic00@live.com
|
||||
|
||||
|
||||
### **release: 3.2.1** 2024/02/15 mandic00@live.com
|
||||
|
||||
|
||||
### **3.2.1** 2024/02/15 mandic00@live.com
|
||||
|
||||
|
||||
### **origin/main** 2023/12/06 mandic00@live.com
|
||||
|
||||
|
||||
### **3.2.0** 2023/12/06 mandic00@live.com
|
||||
|
||||
- set browser false when navigator object is empty
|
||||
|
|
24
README.md
|
@ -4,7 +4,6 @@
|
|||

|
||||

|
||||

|
||||

|
||||
|
||||
# Human Library
|
||||
|
||||
|
@ -31,15 +30,20 @@
|
|||
|
||||
## Compatibility
|
||||
|
||||
- **Browser**:
|
||||
Compatible with both desktop and mobile platforms
|
||||
Compatible with *CPU*, *WebGL*, *WASM* backends
|
||||
Compatible with *WebWorker* execution
|
||||
Compatible with *WebView*
|
||||
- **NodeJS**:
|
||||
Compatibile with *WASM* backend for executions on architectures where *tensorflow* binaries are not available
|
||||
Compatible with *tfjs-node* using software execution via *tensorflow* shared libraries
|
||||
Compatible with *tfjs-node* using GPU-accelerated execution via *tensorflow* shared libraries and nVidia CUDA
|
||||
**Browser**:
|
||||
- Compatible with both desktop and mobile platforms
|
||||
- Compatible with *WebGPU*, *WebGL*, *WASM*, *CPU* backends
|
||||
- Compatible with *WebWorker* execution
|
||||
- Compatible with *WebView*
|
||||
- Primary platform: *Chromium*-based browsers
|
||||
- Secondary platform: *Firefox*, *Safari*
|
||||
|
||||
**NodeJS**:
|
||||
- Compatibile with *WASM* backend for executions on architectures where *tensorflow* binaries are not available
|
||||
- Compatible with *tfjs-node* using software execution via *tensorflow* shared libraries
|
||||
- Compatible with *tfjs-node* using GPU-accelerated execution via *tensorflow* shared libraries and nVidia CUDA
|
||||
- Supported versions are from **14.x** to **22.x**
|
||||
- NodeJS version **23.x** is not supported due to breaking changes and issues with `@tensorflow/tfjs`
|
||||
|
||||
<br>
|
||||
|
||||
|
|
|
@ -10,12 +10,13 @@ import { Human } from '../../dist/human.esm.js';
|
|||
let loader;
|
||||
|
||||
const humanConfig = { // user configuration for human, used to fine-tune behavior
|
||||
cacheSensitivity: 0,
|
||||
debug: true,
|
||||
modelBasePath: 'https://vladmandic.github.io/human-models/models/',
|
||||
filter: { enabled: true, equalization: false, flip: false },
|
||||
face: {
|
||||
enabled: true,
|
||||
detector: { rotation: false, maxDetected: 100, minConfidence: 0.2, return: true },
|
||||
detector: { rotation: false, maxDetected: 100, minConfidence: 0.2, return: true, square: false },
|
||||
iris: { enabled: true },
|
||||
description: { enabled: true },
|
||||
emotion: { enabled: true },
|
||||
|
@ -93,7 +94,7 @@ function addFace(face, source) {
|
|||
e.preventDefault();
|
||||
document.getElementById('description').innerHTML = canvas.title;
|
||||
};
|
||||
human.tf.browser.draw(face.tensor, canvas);
|
||||
human.draw.tensor(face.tensor, canvas);
|
||||
human.tf.dispose(face.tensor);
|
||||
return canvas;
|
||||
}
|
||||
|
@ -149,7 +150,7 @@ async function main() {
|
|||
showLoader('compiling models');
|
||||
await human.warmup();
|
||||
showLoader('loading images');
|
||||
const images = ['group-1.jpg', 'group-2.jpg', 'group-3.jpg', 'group-4.jpg', 'group-5.jpg', 'group-6.jpg', 'group-7.jpg', 'solvay1927.jpg', 'stock-group-1.jpg', 'stock-group-2.jpg'];
|
||||
const images = ['group-1.jpg', 'group-2.jpg', 'group-3.jpg', 'group-4.jpg', 'group-5.jpg', 'group-6.jpg', 'group-7.jpg', 'solvay1927.jpg', 'stock-group-1.jpg', 'stock-group-2.jpg', 'stock-models-6.jpg', 'stock-models-7.jpg'];
|
||||
const imageUris = images.map((a) => `../../samples/in/${a}`);
|
||||
for (let i = 0; i < imageUris.length; i++) addImage(imageUris[i]);
|
||||
initDragAndDrop();
|
||||
|
|
|
@ -11,7 +11,7 @@ import * as H from '../../dist/human.esm.js'; // equivalent of @vladmandic/Human
|
|||
import * as indexDb from './indexdb'; // methods to deal with indexdb
|
||||
|
||||
const humanConfig = { // user configuration for human, used to fine-tune behavior
|
||||
cacheSensitivity: 0,
|
||||
cacheSensitivity: 0.01,
|
||||
modelBasePath: '../../models',
|
||||
filter: { enabled: true, equalization: true }, // lets run with histogram equilizer
|
||||
debug: true,
|
||||
|
@ -240,7 +240,7 @@ async function detectFace() {
|
|||
if (!current?.face?.tensor || !current?.face?.embedding) return false;
|
||||
console.log('face record:', current.face); // eslint-disable-line no-console
|
||||
log(`detected face: ${current.face.gender} ${current.face.age || 0}y distance ${100 * (current.face.distance || 0)}cm/${Math.round(100 * (current.face.distance || 0) / 2.54)}in`);
|
||||
await human.tf.browser.draw(current.face.tensor, dom.canvas);
|
||||
await human.draw.tensor(current.face.tensor, dom.canvas);
|
||||
if (await indexDb.count() === 0) {
|
||||
log('face database is empty: nothing to compare face with');
|
||||
document.body.style.background = 'black';
|
||||
|
|
|
@ -11,7 +11,7 @@ const userConfig = {
|
|||
backend: 'humangl',
|
||||
async: true,
|
||||
warmup: 'none',
|
||||
cacheSensitivity: 0,
|
||||
cacheSensitivity: 0.01,
|
||||
debug: true,
|
||||
modelBasePath: '../../models/',
|
||||
deallocate: true,
|
||||
|
@ -70,7 +70,7 @@ async function selectFaceCanvas(face) {
|
|||
if (face.tensor) {
|
||||
title('Sorting Faces by Similarity');
|
||||
const c = document.getElementById('orig');
|
||||
await human.tf.browser.draw(face.tensor, c);
|
||||
await human.draw.tensor(face.tensor, c);
|
||||
const arr = db.map((rec) => rec.embedding);
|
||||
const res = await human.match.find(face.embedding, arr);
|
||||
log('Match:', db[res.index].name);
|
||||
|
@ -97,7 +97,7 @@ async function selectFaceCanvas(face) {
|
|||
canvas.tag.similarity = similarity;
|
||||
// get best match
|
||||
// draw the canvas
|
||||
await human.tf.browser.draw(current.tensor, canvas);
|
||||
await human.draw.tensor(current.tensor, canvas);
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.font = 'small-caps 1rem "Lato"';
|
||||
ctx.fillStyle = 'rgba(0, 0, 0, 1)';
|
||||
|
@ -144,7 +144,7 @@ async function addFaceCanvas(index, res, fileName) {
|
|||
gender: ${Math.round(100 * res.face[i].genderScore)}% ${res.face[i].gender}
|
||||
emotion: ${emotion}
|
||||
`.replace(/ /g, ' ');
|
||||
await human.tf.browser.draw(res.face[i].tensor, canvas);
|
||||
await human.draw.tensor(res.face[i].tensor, canvas);
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (!ctx) return;
|
||||
ctx.font = 'small-caps 0.8rem "Lato"';
|
||||
|
|
|
@ -223,7 +223,7 @@ async function calcSimmilarity(result) {
|
|||
log('setting face compare baseline:', result.face[0]);
|
||||
if (result.face[0].tensor) {
|
||||
const c = document.getElementById('orig');
|
||||
human.tf.browser.draw(result.face[0].tensor, c);
|
||||
human.draw.tensor(result.face[0].tensor, c);
|
||||
} else {
|
||||
document.getElementById('compare-canvas').getContext('2d').drawImage(compare.original.canvas, 0, 0, 200, 200);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ const log = require('@vladmandic/pilogger'); // eslint-disable-line node/no-unpu
|
|||
const canvas = require('canvas'); // eslint-disable-line node/no-unpublished-require
|
||||
|
||||
const config = {
|
||||
cacheSensitivity: 0,
|
||||
cacheSensitivity: 0.01,
|
||||
wasmPlatformFetch: true,
|
||||
modelBasePath: 'https://vladmandic.github.io/human-models/models/',
|
||||
};
|
||||
|
|
|
@ -92,7 +92,7 @@ async function detect(input) {
|
|||
try {
|
||||
result = await human.detect(tensor, myConfig);
|
||||
} catch (err) {
|
||||
log.error('caught');
|
||||
log.error('caught', err);
|
||||
}
|
||||
|
||||
// dispose image tensor as we no longer need it
|
||||
|
|
|
@ -20,7 +20,7 @@ const config = { // just enable all and leave default settings
|
|||
modelBasePath: 'file://models',
|
||||
debug: true,
|
||||
softwareKernels: true, // slower but enhanced precision since face rotation can work in software mode in nodejs environments
|
||||
cacheSensitivity: 0,
|
||||
cacheSensitivity: 0.01,
|
||||
face: { enabled: true, detector: { maxDetected: 100, minConfidence: 0.1 } },
|
||||
object: { enabled: true, maxDetected: 100, minConfidence: 0.1 },
|
||||
gesture: { enabled: true },
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
body { font-size: 1rem; font-family: "CenturyGothic", "Segoe UI", sans-serif; font-variant: small-caps; width: -webkit-fill-available; height: 100%; background: black; color: white; overflow: hidden; margin: 0; }
|
||||
select { font-size: 1rem; font-family: "CenturyGothic", "Segoe UI", sans-serif; font-variant: small-caps; background: gray; color: white; border: none; }
|
||||
</style>
|
||||
<script src="../segmentation/index.js" type="module"></script>
|
||||
<script src="../segmentation/index.js" type="module"></script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript><h1>javascript is required</h1></noscript>
|
||||
|
|
|
@ -85,7 +85,7 @@ async function main() {
|
|||
return;
|
||||
}
|
||||
dom.fps.innerText = `fps: ${Math.round(10000 / (t1 - t0)) / 10}`; // mark performance
|
||||
human.tf.browser.draw(rgba, dom.output); // draw raw output
|
||||
human.draw.tensor(rgba, dom.output); // draw raw output
|
||||
human.tf.dispose(rgba); // dispose tensors
|
||||
ctxMerge.globalCompositeOperation = 'source-over';
|
||||
ctxMerge.drawImage(dom.background, 0, 0); // draw original video to first stacked canvas
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
author: <https://github.com/vladmandic>'
|
||||
*/
|
||||
|
||||
var e="4.17.0";var s="4.17.0";var t="4.17.0";var n="4.17.0";var r="4.17.0";var i="4.14.0";var h={tfjs:e,"tfjs-core":e,"tfjs-converter":s,"tfjs-backend-cpu":t,"tfjs-backend-webgl":n,"tfjs-backend-wasm":r,"tfjs-backend-webgpu":i};export{h as version};
|
||||
var e="4.22.0";var s="4.22.0";var t="4.22.0";var n="4.22.0";var r="4.22.0";var i="4.22.0";var h={tfjs:e,"tfjs-core":e,"tfjs-converter":s,"tfjs-backend-cpu":t,"tfjs-backend-webgl":n,"tfjs-backend-wasm":r,"tfjs-backend-webgpu":i};export{h as version};
|
||||
|
|
75
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@vladmandic/human",
|
||||
"version": "3.2.1",
|
||||
"version": "3.3.5",
|
||||
"description": "Human: AI-powered 3D Face Detection & Rotation Tracking, Face Description & Recognition, Body Pose Tracking, 3D Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction, Gesture Recognition",
|
||||
"sideEffects": false,
|
||||
"main": "dist/human.node.js",
|
||||
|
@ -8,13 +8,7 @@
|
|||
"browser": "dist/human.esm.js",
|
||||
"types": "types/human.d.ts",
|
||||
"exports": {
|
||||
"node": {
|
||||
"require": "./dist/human.node.js",
|
||||
"import": "./dist/human.node.js",
|
||||
"module": "./dist/human.node.js"
|
||||
},
|
||||
"require": "./dist/human.node.js",
|
||||
"import": "./dist/human.esm.js",
|
||||
"node": "./dist/human.node.js",
|
||||
"script": "./dist/human.js",
|
||||
"module": "./dist/human.esm.js",
|
||||
"types": "./types/human.d.ts",
|
||||
|
@ -29,7 +23,9 @@
|
|||
"dist/human.node-wasm": "./dist/human.node-wasm.js",
|
||||
"dist/human.node-wasm.js": "./dist/human.node-wasm.js",
|
||||
"dist/human.node-gpu": "./dist/human.node-gpu.js",
|
||||
"dist/human.node-gpu.js": "./dist/human.node-gpu.js"
|
||||
"dist/human.node-gpu.js": "./dist/human.node-gpu.js",
|
||||
"require": "./dist/human.node.js",
|
||||
"import": "./dist/human.esm.js"
|
||||
},
|
||||
"author": "Vladimir Mandic <mandic00@live.com>",
|
||||
"bugs": {
|
||||
|
@ -78,39 +74,40 @@
|
|||
"tensorflow"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@html-eslint/eslint-plugin": "^0.21.0",
|
||||
"@html-eslint/parser": "^0.21.0",
|
||||
"@microsoft/api-extractor": "^7.40.1",
|
||||
"@tensorflow/tfjs-backend-cpu": "^4.17.0",
|
||||
"@tensorflow/tfjs-backend-wasm": "^4.17.0",
|
||||
"@tensorflow/tfjs-backend-webgl": "^4.17.0",
|
||||
"@tensorflow/tfjs-backend-webgpu": "4.14.0",
|
||||
"@tensorflow/tfjs-converter": "^4.17.0",
|
||||
"@tensorflow/tfjs-core": "^4.17.0",
|
||||
"@tensorflow/tfjs-data": "^4.17.0",
|
||||
"@tensorflow/tfjs-layers": "^4.17.0",
|
||||
"@tensorflow/tfjs-node": "^4.17.0",
|
||||
"@tensorflow/tfjs-node-gpu": "^4.17.0",
|
||||
"@types/node": "^20.11.19",
|
||||
"@html-eslint/eslint-plugin": "^0.26.0",
|
||||
"@html-eslint/parser": "^0.26.0",
|
||||
"@microsoft/api-extractor": "^7.49.2",
|
||||
"@tensorflow/tfjs-backend-cpu": "^4.22.0",
|
||||
"@tensorflow/tfjs-backend-wasm": "^4.22.0",
|
||||
"@tensorflow/tfjs-backend-webgl": "^4.22.0",
|
||||
"@tensorflow/tfjs-backend-webgpu": "4.22.0",
|
||||
"@tensorflow/tfjs-converter": "^4.22.0",
|
||||
"@tensorflow/tfjs-core": "^4.22.0",
|
||||
"@tensorflow/tfjs-data": "^4.22.0",
|
||||
"@tensorflow/tfjs-layers": "^4.22.0",
|
||||
"@tensorflow/tfjs-node": "^4.22.0",
|
||||
"@tensorflow/tfjs-node-gpu": "^4.22.0",
|
||||
"@types/emscripten": "^1.40.0",
|
||||
"@types/node": "^22.13.1",
|
||||
"@types/offscreencanvas": "^2019.7.3",
|
||||
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||
"@typescript-eslint/parser": "^6.21.0",
|
||||
"@vladmandic/build": "^0.9.3",
|
||||
"@vladmandic/pilogger": "^0.4.9",
|
||||
"@typescript-eslint/eslint-plugin": "^8.8.1",
|
||||
"@typescript-eslint/parser": "^8.8.1",
|
||||
"@vladmandic/build": "^0.10.2",
|
||||
"@vladmandic/pilogger": "^0.5.1",
|
||||
"@vladmandic/tfjs": "github:vladmandic/tfjs",
|
||||
"canvas": "^2.11.2",
|
||||
"esbuild": "^0.19.12",
|
||||
"eslint": "8.55.0",
|
||||
"canvas": "^3.1.0",
|
||||
"esbuild": "^0.24.2",
|
||||
"eslint": "8.57.0",
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-plugin-html": "^7.1.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-json": "^3.1.0",
|
||||
"eslint-plugin-markdown": "^3.0.1",
|
||||
"eslint-plugin-html": "^8.1.2",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-json": "^4.0.1",
|
||||
"eslint-plugin-markdown": "^5.1.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"rimraf": "^5.0.5",
|
||||
"tslib": "^2.6.2",
|
||||
"typedoc": "0.25.4",
|
||||
"typescript": "~5.3.3"
|
||||
"eslint-plugin-promise": "^7.1.0",
|
||||
"rimraf": "^6.0.1",
|
||||
"tslib": "^2.8.1",
|
||||
"typedoc": "0.27.6",
|
||||
"typescript": "5.7.3"
|
||||
}
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 164 KiB |
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 150 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
|
@ -1,7 +1,7 @@
|
|||
/* eslint-disable no-multi-spaces */
|
||||
|
||||
/** Possible TensorFlow backends */
|
||||
export type BackendEnum = '' | 'cpu' | 'wasm' | 'webgl' | 'humangl' | 'tensorflow' | 'webgpu';
|
||||
export type BackendEnum = '' | 'cpu' | 'wasm' | 'webgl' | 'humangl' | 'tensorflow' | 'webgpu' | 'none';
|
||||
|
||||
/** Possible values for `human.warmup` */
|
||||
export type WarmupEnum = '' | 'none' | 'face' | 'full' | 'body';
|
||||
|
@ -39,6 +39,8 @@ export interface FaceDetectorConfig extends GenericConfig {
|
|||
iouThreshold: number,
|
||||
/** how much should face box be enlarged over the min/max facial coordinates */
|
||||
scale: number,
|
||||
/** automatically pad image to square */
|
||||
square: boolean,
|
||||
/** should child models perform on masked image of a face */
|
||||
mask: boolean,
|
||||
/** should face detection return processed and cropped face tensor that can with an external model for addtional processing?
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* Module that implements helper draw functions, exposed as human.draw
|
||||
*/
|
||||
|
||||
import * as tf from 'dist/tfjs.esm.js';
|
||||
import { mergeDeep, now } from '../util/util';
|
||||
import { env } from '../util/env';
|
||||
import { getCanvasContext, rect } from './primitives';
|
||||
|
@ -14,6 +15,7 @@ import { gesture } from './gesture';
|
|||
import { defaultLabels } from './labels';
|
||||
import type { Result, PersonResult } from '../result';
|
||||
import type { AnyCanvas, DrawOptions } from '../exports';
|
||||
import type { Tensor2D } from '../tfjs/types';
|
||||
|
||||
let drawTime = 0;
|
||||
|
||||
|
@ -60,6 +62,22 @@ export function canvas(input: AnyCanvas | HTMLImageElement | HTMLVideoElement, o
|
|||
ctx.drawImage(input, 0, 0);
|
||||
}
|
||||
|
||||
/** draw processed canvas */
|
||||
export async function tensor(input: Tensor2D, output: HTMLCanvasElement) {
|
||||
if (!input || !output) return;
|
||||
if (!env.browser) return;
|
||||
// const backend = tf.getBackend();
|
||||
// if (backend === 'webgpu') tf.browser.draw(input, output);
|
||||
// else await tf.browser.toPixels(input, output);
|
||||
await tf.browser.toPixels(input, output);
|
||||
// const ctx = getCanvasContext(output) as CanvasRenderingContext2D;
|
||||
// if (!ctx) return;
|
||||
// const image = await process(input);
|
||||
// result.canvas = image.canvas;
|
||||
// human.tf.dispose(image.tensor);
|
||||
// ctx.drawImage(image.canvas, 0, 0);
|
||||
}
|
||||
|
||||
/** meta-function that performs draw for: canvas, face, body, hand */
|
||||
export async function all(inCanvas: AnyCanvas, result: Result, drawOptions?: Partial<DrawOptions>) {
|
||||
if (!result?.performance || !inCanvas) return null;
|
||||
|
|
|
@ -60,7 +60,9 @@ export const calculateFaceAngle = (face: FaceResult, imageSize: [number, number]
|
|||
let thetaZ: number;
|
||||
if (r10 < 1) { // YZX calculation
|
||||
if (r10 > -1) {
|
||||
thetaZ = Math.asin(r10);
|
||||
// thetaZ = Math.asin(r10);
|
||||
const cosThetaZ = Math.sqrt(r00 * r00 + r20 * r20); // <https://github.com/vladmandic/human/issues/464>
|
||||
thetaZ = Math.atan2(r10, cosThetaZ);
|
||||
thetaY = Math.atan2(-r20, r00);
|
||||
thetaX = Math.atan2(-r12, r11);
|
||||
} else {
|
||||
|
@ -76,9 +78,9 @@ export const calculateFaceAngle = (face: FaceResult, imageSize: [number, number]
|
|||
if (Number.isNaN(thetaX)) thetaX = 0;
|
||||
if (Number.isNaN(thetaY)) thetaY = 0;
|
||||
if (Number.isNaN(thetaZ)) thetaZ = 0;
|
||||
return { pitch: 2 * -thetaX, yaw: 2 * -thetaY, roll: 2 * -thetaZ };
|
||||
// return { pitch: 2 * -thetaX, yaw: 2 * -thetaY, roll: 2 * -thetaZ };
|
||||
return { pitch: -thetaX, yaw: -thetaY, roll: -thetaZ };
|
||||
};
|
||||
|
||||
/*
|
||||
const meshToEulerAngle = (mesh) => { // simple Euler angle calculation based existing 3D mesh
|
||||
const radians = (a1, a2, b1, b2) => Math.atan2(b2 - a2, b1 - a1);
|
||||
|
|
|
@ -55,9 +55,20 @@ export async function getBoxes(inputImage: Tensor4D, config: Config): Promise<De
|
|||
// sanity check on input
|
||||
if ((!inputImage) || (inputImage['isDisposedInternal']) || (inputImage.shape.length !== 4) || (inputImage.shape[1] < 1) || (inputImage.shape[2] < 1)) return [];
|
||||
const t: Record<string, Tensor> = {};
|
||||
t.resized = tf.image.resizeBilinear(inputImage, [inputSize, inputSize]);
|
||||
let pad = [0, 0];
|
||||
let scale = [1, 1];
|
||||
if (config?.face?.detector?.square) {
|
||||
const xy = Math.max(inputImage.shape[2], inputImage.shape[1]);
|
||||
pad = [Math.floor((xy - inputImage.shape[2]) / 2), Math.floor((xy - inputImage.shape[1]) / 2)];
|
||||
t.padded = tf.pad(inputImage, [[0, 0], [pad[1], pad[1]], [pad[0], pad[0]], [0, 0]]);
|
||||
scale = [inputImage.shape[2] / xy, inputImage.shape[1] / xy];
|
||||
pad = [pad[0] / inputSize, pad[1] / inputSize];
|
||||
} else {
|
||||
t.padded = inputImage.clone();
|
||||
}
|
||||
t.resized = tf.image.resizeBilinear(t.padded as Tensor4D, [inputSize, inputSize]);
|
||||
t.div = tf.div(t.resized, constants.tf127);
|
||||
t.normalized = tf.sub(t.div, constants.tf05);
|
||||
t.normalized = tf.sub(t.div, constants.tf1);
|
||||
const res = model?.execute(t.normalized) as Tensor[];
|
||||
if (Array.isArray(res) && res.length > 2) { // pinto converted model?
|
||||
const sorted = res.sort((a, b) => a.size - b.size);
|
||||
|
@ -81,7 +92,6 @@ export async function getBoxes(inputImage: Tensor4D, config: Config): Promise<De
|
|||
const scores = await t.scores.data();
|
||||
for (let i = 0; i < nms.length; i++) {
|
||||
const confidence = scores[nms[i]];
|
||||
|
||||
if (confidence > (config.face.detector?.minConfidence || 0)) {
|
||||
const b: Record<string, Tensor> = {};
|
||||
b.bbox = tf.slice(t.boxes, [nms[i], 0], [1, -1]);
|
||||
|
@ -89,9 +99,15 @@ export async function getBoxes(inputImage: Tensor4D, config: Config): Promise<De
|
|||
b.squeeze = tf.squeeze(b.slice);
|
||||
b.landmarks = tf.reshape(b.squeeze, [keypointsCount, -1]);
|
||||
const points = await b.bbox.data();
|
||||
const unpadded = [ // TODO fix this math
|
||||
points[0] * scale[0] - pad[0],
|
||||
points[1] * scale[1] - pad[1],
|
||||
points[2] * scale[0] - pad[0],
|
||||
points[3] * scale[1] - pad[1],
|
||||
];
|
||||
const rawBox = {
|
||||
startPoint: [points[0], points[1]] as Point,
|
||||
endPoint: [points[2], points[3]] as Point,
|
||||
startPoint: [unpadded[0], unpadded[1]] as Point,
|
||||
endPoint: [unpadded[2], unpadded[3]] as Point,
|
||||
landmarks: (await b.landmarks.array()) as Point[],
|
||||
confidence,
|
||||
};
|
||||
|
|
|
@ -17,7 +17,8 @@ export function distance(descriptor1: Descriptor, descriptor2: Descriptor, optio
|
|||
const diff = (!options.order || options.order === 2) ? (descriptor1[i] - descriptor2[i]) : (Math.abs(descriptor1[i] - descriptor2[i]));
|
||||
sum += (!options.order || options.order === 2) ? (diff * diff) : (diff ** options.order);
|
||||
}
|
||||
return (options.multiplier || 20) * sum;
|
||||
const dist = Math.round(100 * (options.multiplier || 20) * sum) / 100;
|
||||
return dist;
|
||||
}
|
||||
|
||||
// invert distance to similarity, normalize to given range and clamp
|
||||
|
@ -25,7 +26,7 @@ const normalizeDistance = (dist, order, min, max) => {
|
|||
if (dist === 0) return 1; // short circuit for identical inputs
|
||||
const root = order === 2 ? Math.sqrt(dist) : dist ** (1 / order); // take root of distance
|
||||
const norm = (1 - (root / 100) - min) / (max - min); // normalize to range
|
||||
const clamp = Math.max(Math.min(norm, 1), 0); // clamp to 0..1
|
||||
const clamp = Math.round(100 * Math.max(Math.min(norm, 1), 0)) / 100; // clamp to 0..1
|
||||
return clamp;
|
||||
};
|
||||
|
||||
|
|
|
@ -290,7 +290,6 @@ const checksum = async (input: Tensor): Promise<number> => { // use tf sum or js
|
|||
export async function skip(config: Partial<Config>, input: Tensor) {
|
||||
let skipFrame = false;
|
||||
if (config.cacheSensitivity === 0 || !input.shape || input.shape.length !== 4 || input.shape[1] > 3840 || input.shape[2] > 2160) return skipFrame; // cache disabled or input is invalid or too large for cache analysis
|
||||
|
||||
/*
|
||||
const checkSum = await checksum(input);
|
||||
const diff = 100 * (Math.max(checkSum, last.inputSum) / Math.min(checkSum, last.inputSum) - 1);
|
||||
|
|
|
@ -27,7 +27,7 @@ class GLProgram {
|
|||
this.gl = gl;
|
||||
const vertexShader = this.compile(vertexSource, this.gl.VERTEX_SHADER);
|
||||
const fragmentShader = this.compile(fragmentSource, this.gl.FRAGMENT_SHADER);
|
||||
this.id = this.gl.createProgram() as WebGLProgram;
|
||||
this.id = this.gl.createProgram();
|
||||
if (!vertexShader || !fragmentShader) return;
|
||||
if (!this.id) {
|
||||
log('filter: could not create webgl program');
|
||||
|
|
|
@ -100,13 +100,13 @@ export class Models {
|
|||
let totalSizeWeights = 0;
|
||||
let totalSizeLoading = 0;
|
||||
for (const m of Object.values(modelStats)) {
|
||||
totalSizeFromManifest += m.sizeFromManifest;
|
||||
totalSizeWeights += m.sizeLoadedWeights;
|
||||
totalSizeLoading += m.sizeDesired;
|
||||
totalSizeFromManifest += Number.isNaN(+m.sizeFromManifest) ? 0 : m.sizeFromManifest;
|
||||
totalSizeWeights += Number.isNaN(+m.sizeLoadedWeights) ? 0 : m.sizeLoadedWeights;
|
||||
totalSizeLoading += Number.isNaN(+m.sizeDesired) ? 0 : m.sizeDesired;
|
||||
}
|
||||
const percentageLoaded = totalSizeLoading > 0 ? totalSizeWeights / totalSizeLoading : 0;
|
||||
return {
|
||||
numLoadedModels: Object.values(modelStats).length,
|
||||
numLoadedModels: Object.values(modelStats).filter((m) => m?.loaded).length,
|
||||
numDefinedModels: Object.keys(this.models).length,
|
||||
percentageLoaded,
|
||||
totalSizeFromManifest,
|
||||
|
@ -178,7 +178,7 @@ export class Models {
|
|||
return models;
|
||||
}
|
||||
|
||||
loaded() {
|
||||
loaded(): string[] {
|
||||
const list = this.list();
|
||||
const loaded = list.filter((model) => model.loaded).map((model) => model.name);
|
||||
return loaded;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*/
|
||||
|
||||
// data:image/jpeg;base64,
|
||||
export const face = `
|
||||
export const face: string = `
|
||||
/9j/4AAQSkZJRgABAQEAYABgAAD/4QBoRXhpZgAATU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUA
|
||||
AAABAAAARgEoAAMAAAABAAIAAAExAAIAAAARAAAATgAAAAAAAABgAAAAAQAAAGAAAAABcGFpbnQu
|
||||
bmV0IDQuMi4xMwAA/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcUGBgXFBYWGh0lHxob
|
||||
|
|
|
@ -121,14 +121,17 @@ export async function check(instance: Human, force = false) {
|
|||
log('override: backend set to webgpu but browser does not support webgpu');
|
||||
instance.config.backend = 'webgl';
|
||||
} else {
|
||||
const adapter = await navigator.gpu.requestAdapter();
|
||||
const adapter: GPUAdapter = await navigator.gpu.requestAdapter() as GPUAdapter;
|
||||
if (instance.config.debug) log('enumerated webgpu adapter:', adapter);
|
||||
if (!adapter) {
|
||||
log('override: backend set to webgpu but browser reports no available gpu');
|
||||
instance.config.backend = 'webgl';
|
||||
} else {
|
||||
// @ts-ignore requestAdapterInfo is not in tslib
|
||||
const adapterInfo = 'requestAdapterInfo' in adapter ? await adapter.requestAdapterInfo() : undefined;
|
||||
let adapterInfo;
|
||||
// @ts-ignore gpu adapter info
|
||||
if ('requestAdapterInfo' in adapter) adapterInfo = await adapter?.requestAdapterInfo();
|
||||
// @ts-ignore gpu adapter info
|
||||
else adapterInfo = adapter.info;
|
||||
// if (adapter.features) adapter.features.forEach((feature) => log('webgpu features:', feature));
|
||||
log('webgpu adapter info:', adapterInfo);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ const options = {
|
|||
|
||||
export interface ModelInfo {
|
||||
name: string,
|
||||
loaded: boolean,
|
||||
inCache: boolean,
|
||||
sizeDesired: number,
|
||||
sizeFromManifest: number,
|
||||
|
@ -42,6 +43,7 @@ export async function loadModel(modelPath: string | undefined): Promise<GraphMod
|
|||
const cachedModelName = 'indexeddb://' + shortModelName; // generate short model name for cache
|
||||
modelStats[shortModelName] = {
|
||||
name: shortModelName,
|
||||
loaded: false,
|
||||
sizeFromManifest: 0,
|
||||
sizeLoadedWeights: 0,
|
||||
sizeDesired: modelsDefs[shortModelName],
|
||||
|
@ -59,7 +61,7 @@ export async function loadModel(modelPath: string | undefined): Promise<GraphMod
|
|||
modelStats[shortModelName].url = modelStats[shortModelName].inCache ? cachedModelName : modelUrl;
|
||||
const tfLoadOptions = typeof fetch === 'undefined' ? {} : { fetchFunc: (url: string, init?: RequestInit) => httpHandler(url, init) };
|
||||
let model: GraphModel = new tf.GraphModel(modelStats[shortModelName].url, tfLoadOptions) as unknown as GraphModel; // create model prototype and decide if load from cache or from original modelurl
|
||||
let loaded = false;
|
||||
modelStats[shortModelName].loaded = false;
|
||||
try {
|
||||
// @ts-ignore private function
|
||||
model.findIOHandler(); // decide how to actually load a model
|
||||
|
@ -74,13 +76,13 @@ export async function loadModel(modelPath: string | undefined): Promise<GraphMod
|
|||
if (artifacts) model.loadSync(artifacts); // load weights
|
||||
else model = await tf.loadGraphModel(modelStats[shortModelName].inCache ? cachedModelName : modelUrl, tfLoadOptions) as unknown as GraphModel;
|
||||
// @ts-ignore private property
|
||||
modelStats[shortModelName].sizeLoadedWeights = model.artifacts?.weightData?.byteLength || 0;
|
||||
modelStats[shortModelName].sizeLoadedWeights = model.artifacts?.weightData?.byteLength || model.artifacts?.weightData?.[0].byteLength || 0;
|
||||
if (options.verbose) log('load:', { model: shortModelName, url: model['modelUrl'], bytes: modelStats[shortModelName].sizeLoadedWeights });
|
||||
loaded = true;
|
||||
modelStats[shortModelName].loaded = true;
|
||||
} catch (err) {
|
||||
log('error loading model:', modelUrl, err);
|
||||
}
|
||||
if (loaded && options.cacheModels && options.cacheSupported && !modelStats[shortModelName].inCache) { // save model to cache
|
||||
if (modelStats[shortModelName].loaded && options.cacheModels && options.cacheSupported && !modelStats[shortModelName].inCache) { // save model to cache
|
||||
try {
|
||||
const saveResult = await model.save(cachedModelName);
|
||||
if (options.debug) log('model saved:', cachedModelName, saveResult);
|
||||
|
|
|
@ -154,7 +154,12 @@ export class Env {
|
|||
try {
|
||||
if (this.webgpu.supported) {
|
||||
const adapter = await navigator.gpu.requestAdapter();
|
||||
this.webgpu.adapter = await adapter?.requestAdapterInfo();
|
||||
if (adapter) {
|
||||
// @ts-ignore requestAdapterInfo is not in tslib
|
||||
if ('requestAdapterInfo' in adapter) this.webgpu.adapter = await adapter.requestAdapterInfo();
|
||||
// @ts-ignore adapter.info is not in tslib
|
||||
else this.webgpu.adapter = await adapter.info;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
this.webgpu.supported = false;
|
||||
|
|
|
@ -166,6 +166,7 @@ export async function warmup(instance: Human, userConfig?: Partial<Config>): Pro
|
|||
}
|
||||
return new Promise(async (resolve) => {
|
||||
await instance.models.load();
|
||||
await tf.ready();
|
||||
await runCompile(instance);
|
||||
const res = await runInference(instance);
|
||||
const t1 = now();
|
||||
|
|
102
test/build.log
|
@ -1,51 +1,51 @@
|
|||
2024-02-15 12:49:25 [32mDATA: [39m Build {"name":"@vladmandic/human","version":"3.2.1"}
|
||||
2024-02-15 12:49:25 [36mINFO: [39m Application: {"name":"@vladmandic/human","version":"3.2.1"}
|
||||
2024-02-15 12:49:25 [36mINFO: [39m Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
|
||||
2024-02-15 12:49:25 [36mINFO: [39m Toolchain: {"build":"0.9.2","esbuild":"0.19.12","typescript":"5.3.3","typedoc":"0.25.4","eslint":"8.55.0"}
|
||||
2024-02-15 12:49:25 [36mINFO: [39m Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
|
||||
2024-02-15 12:49:25 [35mSTATE:[39m Clean: {"locations":["dist/*","types/*","typedoc/*"]}
|
||||
2024-02-15 12:49:25 [35mSTATE:[39m Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1289,"outputBytes":358}
|
||||
2024-02-15 12:49:25 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":566,"outputBytes":957}
|
||||
2024-02-15 12:49:25 [35mSTATE:[39m Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":80,"inputBytes":676266,"outputBytes":320934}
|
||||
2024-02-15 12:49:25 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":574,"outputBytes":965}
|
||||
2024-02-15 12:49:25 [35mSTATE:[39m Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":80,"inputBytes":676274,"outputBytes":320938}
|
||||
2024-02-15 12:49:25 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":662,"outputBytes":2003}
|
||||
2024-02-15 12:49:25 [35mSTATE:[39m Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":80,"inputBytes":677312,"outputBytes":321049}
|
||||
2024-02-15 12:49:25 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":1403,"outputBytes":690}
|
||||
2024-02-15 12:49:25 [35mSTATE:[39m Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":80,"inputBytes":675999,"outputBytes":319515}
|
||||
2024-02-15 12:49:25 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/bundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":10,"inputBytes":1403,"outputBytes":1294474}
|
||||
2024-02-15 12:49:25 [35mSTATE:[39m Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":80,"inputBytes":1969783,"outputBytes":1609692}
|
||||
2024-02-15 12:49:25 [35mSTATE:[39m Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":80,"inputBytes":1969783,"outputBytes":2120081}
|
||||
2024-02-15 12:49:26 [35mSTATE:[39m Typings: {"input":"src/human.ts","output":"types/lib","files":14}
|
||||
2024-02-15 12:49:28 [35mSTATE:[39m TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":81,"generated":true}
|
||||
2024-02-15 12:49:28 [35mSTATE:[39m Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":6318,"outputBytes":2970}
|
||||
2024-02-15 12:49:28 [35mSTATE:[39m Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":17499,"outputBytes":9399}
|
||||
2024-02-15 12:49:28 [35mSTATE:[39m Compile: {"name":"demo/tracker","format":"esm","platform":"browser","input":"demo/tracker/index.ts","output":"demo/tracker/index.js","files":2,"inputBytes":54375,"outputBytes":22791}
|
||||
2024-02-15 12:49:35 [35mSTATE:[39m Lint: {"locations":["**/*.json","src/**/*.ts","test/**/*.js","demo/**/*.js","**/*.md"],"files":172,"errors":0,"warnings":0}
|
||||
2024-02-15 12:49:35 [35mSTATE:[39m ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
|
||||
2024-02-15 12:49:35 [35mSTATE:[39m Copy: {"input":"node_modules/@vladmandic/tfjs/types/tfjs-core.d.ts","output":"types/tfjs-core.d.ts"}
|
||||
2024-02-15 12:49:35 [36mINFO: [39m Done...
|
||||
2024-02-15 12:49:35 [35mSTATE:[39m Copy: {"input":"node_modules/@vladmandic/tfjs/types/tfjs.d.ts","output":"types/tfjs.esm.d.ts"}
|
||||
2024-02-15 12:49:35 [35mSTATE:[39m Copy: {"input":"src/types/tsconfig.json","output":"types/tsconfig.json"}
|
||||
2024-02-15 12:49:35 [35mSTATE:[39m Copy: {"input":"src/types/eslint.json","output":"types/.eslintrc.json"}
|
||||
2024-02-15 12:49:35 [35mSTATE:[39m Copy: {"input":"src/types/tfjs.esm.d.ts","output":"dist/tfjs.esm.d.ts"}
|
||||
2024-02-15 12:49:35 [35mSTATE:[39m Filter: {"input":"types/tfjs-core.d.ts"}
|
||||
2024-02-15 12:49:36 [31mERROR:[39m API-Extractor: {}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Filter: {"input":"types/human.d.ts"}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Write: {"output":"dist/human.esm-nobundle.d.ts"}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Write: {"output":"dist/human.esm.d.ts"}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Write: {"output":"dist/human.d.ts"}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Write: {"output":"dist/human.node-gpu.d.ts"}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Write: {"output":"dist/human.node.d.ts"}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Write: {"output":"dist/human.node-wasm.d.ts"}
|
||||
2024-02-15 12:49:36 [36mINFO: [39m Analyze models: {"folders":8,"result":"models/models.json"}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Models {"folder":"./models","models":12}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Models {"folder":"../human-models/models","models":44}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Models {"folder":"../blazepose/model/","models":4}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Models {"folder":"../anti-spoofing/model","models":1}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Models {"folder":"../efficientpose/models","models":3}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Models {"folder":"../insightface/models","models":5}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Models {"folder":"../movenet/models","models":3}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Models {"folder":"../nanodet/models","models":4}
|
||||
2024-02-15 12:49:36 [35mSTATE:[39m Models: {"count":58,"totalSize":380063249}
|
||||
2024-02-15 12:49:36 [36mINFO: [39m Human Build complete... {"logFile":"test/build.log"}
|
||||
2025-02-05 09:39:04 [32mDATA: [39m Build {"name":"@vladmandic/human","version":"3.3.5"}
|
||||
2025-02-05 09:39:04 [36mINFO: [39m Application: {"name":"@vladmandic/human","version":"3.3.5"}
|
||||
2025-02-05 09:39:04 [36mINFO: [39m Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
|
||||
2025-02-05 09:39:04 [36mINFO: [39m Toolchain: {"build":"0.10.2","esbuild":"0.24.2","typescript":"5.7.3","typedoc":"0.27.6","eslint":"8.57.0"}
|
||||
2025-02-05 09:39:04 [36mINFO: [39m Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
|
||||
2025-02-05 09:39:04 [35mSTATE:[39m Clean: {"locations":["dist/*","types/*","typedoc/*"]}
|
||||
2025-02-05 09:39:04 [35mSTATE:[39m Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1289,"outputBytes":358}
|
||||
2025-02-05 09:39:04 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":566,"outputBytes":957}
|
||||
2025-02-05 09:39:04 [35mSTATE:[39m Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":80,"inputBytes":678664,"outputBytes":321804}
|
||||
2025-02-05 09:39:04 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":574,"outputBytes":965}
|
||||
2025-02-05 09:39:04 [35mSTATE:[39m Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":80,"inputBytes":678672,"outputBytes":321808}
|
||||
2025-02-05 09:39:04 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":662,"outputBytes":2003}
|
||||
2025-02-05 09:39:04 [35mSTATE:[39m Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":80,"inputBytes":679710,"outputBytes":321919}
|
||||
2025-02-05 09:39:04 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":1403,"outputBytes":690}
|
||||
2025-02-05 09:39:04 [35mSTATE:[39m Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":80,"inputBytes":678397,"outputBytes":320365}
|
||||
2025-02-05 09:39:04 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/bundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":10,"inputBytes":1403,"outputBytes":1267320}
|
||||
2025-02-05 09:39:04 [35mSTATE:[39m Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":80,"inputBytes":1945027,"outputBytes":1583413}
|
||||
2025-02-05 09:39:04 [35mSTATE:[39m Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":80,"inputBytes":1945027,"outputBytes":2067530}
|
||||
2025-02-05 09:39:06 [35mSTATE:[39m Typings: {"input":"src/human.ts","output":"types/lib","files":78}
|
||||
2025-02-05 09:39:08 [35mSTATE:[39m TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":81,"generated":true}
|
||||
2025-02-05 09:39:08 [35mSTATE:[39m Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":6318,"outputBytes":2970}
|
||||
2025-02-05 09:39:08 [35mSTATE:[39m Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":17498,"outputBytes":9397}
|
||||
2025-02-05 09:39:08 [35mSTATE:[39m Compile: {"name":"demo/tracker","format":"esm","platform":"browser","input":"demo/tracker/index.ts","output":"demo/tracker/index.js","files":2,"inputBytes":54375,"outputBytes":22791}
|
||||
2025-02-05 09:39:16 [35mSTATE:[39m Lint: {"locations":["**/*.json","src/**/*.ts","test/**/*.js","demo/**/*.js","**/*.md"],"files":171,"errors":0,"warnings":0}
|
||||
2025-02-05 09:39:16 [35mSTATE:[39m ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
|
||||
2025-02-05 09:39:16 [35mSTATE:[39m Copy: {"input":"node_modules/@vladmandic/tfjs/types/tfjs-core.d.ts","output":"types/tfjs-core.d.ts"}
|
||||
2025-02-05 09:39:16 [36mINFO: [39m Done...
|
||||
2025-02-05 09:39:16 [35mSTATE:[39m Copy: {"input":"node_modules/@vladmandic/tfjs/types/tfjs.d.ts","output":"types/tfjs.esm.d.ts"}
|
||||
2025-02-05 09:39:16 [35mSTATE:[39m Copy: {"input":"src/types/tsconfig.json","output":"types/tsconfig.json"}
|
||||
2025-02-05 09:39:16 [35mSTATE:[39m Copy: {"input":"src/types/eslint.json","output":"types/.eslintrc.json"}
|
||||
2025-02-05 09:39:16 [35mSTATE:[39m Copy: {"input":"src/types/tfjs.esm.d.ts","output":"dist/tfjs.esm.d.ts"}
|
||||
2025-02-05 09:39:16 [35mSTATE:[39m Filter: {"input":"types/tfjs-core.d.ts"}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m API-Extractor: {"succeeeded":true,"errors":0,"warnings":0}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Filter: {"input":"types/human.d.ts"}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Write: {"output":"dist/human.esm-nobundle.d.ts"}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Write: {"output":"dist/human.esm.d.ts"}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Write: {"output":"dist/human.d.ts"}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Write: {"output":"dist/human.node-gpu.d.ts"}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Write: {"output":"dist/human.node.d.ts"}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Write: {"output":"dist/human.node-wasm.d.ts"}
|
||||
2025-02-05 09:39:17 [36mINFO: [39m Analyze models: {"folders":8,"result":"models/models.json"}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Models {"folder":"./models","models":12}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Models {"folder":"../human-models/models","models":44}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Models {"folder":"../blazepose/model/","models":4}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Models {"folder":"../anti-spoofing/model","models":1}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Models {"folder":"../efficientpose/models","models":3}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Models {"folder":"../insightface/models","models":5}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Models {"folder":"../movenet/models","models":3}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Models {"folder":"../nanodet/models","models":4}
|
||||
2025-02-05 09:39:17 [35mSTATE:[39m Models: {"count":58,"totalSize":380063249}
|
||||
2025-02-05 09:39:17 [36mINFO: [39m Human Build complete... {"logFile":"test/build.log"}
|
||||
|
|
|
@ -3,7 +3,7 @@ const H = require('../dist/human.node.js');
|
|||
const test = require('./test-node-main.js').test;
|
||||
|
||||
const config = {
|
||||
cacheSensitivity: 0,
|
||||
cacheSensitivity: 0.01,
|
||||
modelBasePath: 'file://models/',
|
||||
backend: 'cpu',
|
||||
debug: false,
|
||||
|
|
|
@ -3,7 +3,7 @@ const H = require('../dist/human.node-gpu.js');
|
|||
const test = require('./test-node-main.js').test;
|
||||
|
||||
const config = {
|
||||
cacheSensitivity: 0,
|
||||
cacheSensitivity: 0.01,
|
||||
modelBasePath: 'file://models/',
|
||||
backend: 'tensorflow',
|
||||
debug: false,
|
||||
|
|
|
@ -10,7 +10,7 @@ H.env.Canvas = Canvas; // requires monkey-patch as wasm does not have tf.browser
|
|||
H.env.Image = Image; // requires monkey-patch as wasm does not have tf.browser namespace
|
||||
|
||||
const config = {
|
||||
cacheSensitivity: 0,
|
||||
cacheSensitivity: 0.01,
|
||||
modelBasePath: 'https://vladmandic.github.io/human-models/models/',
|
||||
backend: 'wasm',
|
||||
// wasmPath: 'node_modules/@tensorflow/tfjs-backend-wasm/dist/',
|
||||
|
|
|
@ -4,7 +4,7 @@ const H = require('../dist/human.node.js');
|
|||
const test = require('./test-node-main.js').test;
|
||||
|
||||
const config = {
|
||||
cacheSensitivity: 0,
|
||||
cacheSensitivity: 0.01,
|
||||
modelBasePath: 'file://models/',
|
||||
backend: 'tensorflow',
|
||||
debug: false,
|
||||
|
|
|
@ -6,7 +6,7 @@ const H = require('../dist/human.node.js');
|
|||
const models = ['emotion.json', 'gear-e1.json', 'gear-e2.json', 'affectnet-mobilenet.json'];
|
||||
const humanConfig = {
|
||||
debug: false,
|
||||
cacheSensitivity: 0,
|
||||
cacheSensitivity: 0.01,
|
||||
modelBasePath: 'https://vladmandic.github.io/human-models/models/',
|
||||
face: {
|
||||
scale: 1.4,
|
||||
|
|
|
@ -12,7 +12,7 @@ process.env.TF_CPP_MIN_LOG_LEVEL = '2';
|
|||
const humanConfig = {
|
||||
backend: 'tensorflow',
|
||||
debug: false,
|
||||
cacheSensitivity: 0,
|
||||
cacheSensitivity: 0.01,
|
||||
modelBasePath: 'https://vladmandic.github.io/human-models/models/',
|
||||
face: {
|
||||
detector: { enabled: true, modelPath: 'blazeface-back.json' },
|
||||
|
|
|
@ -107,7 +107,7 @@ async function testWarmup(human, title) {
|
|||
try {
|
||||
warmup = await human.warmup(config);
|
||||
} catch (err) {
|
||||
log('error', 'error warmup');
|
||||
log('error', 'error warmup', err);
|
||||
}
|
||||
if (warmup) {
|
||||
log('state', 'passed: warmup:', config.warmup, title);
|
||||
|
|
1809
test/test.log
|
@ -51,9 +51,9 @@
|
|||
"tabSize": 2
|
||||
},
|
||||
"exclude": ["node_modules/", "types/", "dist/**/*.js"],
|
||||
"include": ["src", "tfjs/*.ts", "types/human.d.ts", "test/**/*.ts", "demo/**/*.ts", "demo/facedetect/loader.js"],
|
||||
"include": ["src", "tfjs/*.ts", "types/human.d.ts", "test/**/*.ts"],
|
||||
"typedocOptions": {
|
||||
"excludeExternals": true,
|
||||
"externalPattern": ["**/node_modules/**", "tfjs/"]
|
||||
"externalPattern": ["**/node_modules/**", "tfjs/", "demo/"]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
window.hierarchyData = "eJyV1D1vgzAQBuD/crPTYvPN1s+0UqsOGasMFI7ELdiR7Vaqovz3yhkKmOWygAX38nDG+AhGa2eheuciyrYMDHY9Nk5qZaE6gr/qz6oeECpYo0IjmzutOrkDBl9StVCJNGPwbXqoQCqHpqsbtNez2qu9G3pg0PS1tVCBs+3Kh1f/AX9zL/vWoDq/DeeMC5EyLmI/inPGRSL8oWBcpIk/lIyLzI/yiHFR+FHJGY+jnPGYp9sTA/+gSQOPdYP36LBx2pC6WAYIrZxdkQbuK9o92RyLqV4c9vlspCV7YzHZywPvxjlUfuWQ0SBBlROx+KK2MfJwkb3IkPUi0B8GfZE8q6eqaRLOtnJyc9C6o8/2PEGWy0B+kT+o0NLX1jxAdbOw4zXW9H92LKZ6eRR4ZOsyp5j2davbX5IzFlKdcrofPNWqJTljIdGJo+k+8PbxiY0jSdNSqsWne+oGdwMqV5N/vmWA4p5Of40CVuo="
|
|
@ -15,8 +15,6 @@
|
|||
--dark-hl-6: #DCDCAA;
|
||||
--light-hl-7: #098658;
|
||||
--dark-hl-7: #B5CEA8;
|
||||
--light-hl-8: #000000;
|
||||
--dark-hl-8: #C8C8C8;
|
||||
--light-code-background: #FFFFFF;
|
||||
--dark-code-background: #1E1E1E;
|
||||
}
|
||||
|
@ -30,7 +28,6 @@
|
|||
--hl-5: var(--light-hl-5);
|
||||
--hl-6: var(--light-hl-6);
|
||||
--hl-7: var(--light-hl-7);
|
||||
--hl-8: var(--light-hl-8);
|
||||
--code-background: var(--light-code-background);
|
||||
} }
|
||||
|
||||
|
@ -43,7 +40,6 @@
|
|||
--hl-5: var(--dark-hl-5);
|
||||
--hl-6: var(--dark-hl-6);
|
||||
--hl-7: var(--dark-hl-7);
|
||||
--hl-8: var(--dark-hl-8);
|
||||
--code-background: var(--dark-code-background);
|
||||
} }
|
||||
|
||||
|
@ -56,7 +52,6 @@
|
|||
--hl-5: var(--light-hl-5);
|
||||
--hl-6: var(--light-hl-6);
|
||||
--hl-7: var(--light-hl-7);
|
||||
--hl-8: var(--light-hl-8);
|
||||
--code-background: var(--light-code-background);
|
||||
}
|
||||
|
||||
|
@ -69,7 +64,6 @@
|
|||
--hl-5: var(--dark-hl-5);
|
||||
--hl-6: var(--dark-hl-6);
|
||||
--hl-7: var(--dark-hl-7);
|
||||
--hl-8: var(--dark-hl-8);
|
||||
--code-background: var(--dark-code-background);
|
||||
}
|
||||
|
||||
|
@ -81,5 +75,4 @@
|
|||
.hl-5 { color: var(--hl-5); }
|
||||
.hl-6 { color: var(--hl-6); }
|
||||
.hl-7 { color: var(--hl-7); }
|
||||
.hl-8 { color: var(--hl-8); }
|
||||
pre, code { background: var(--code-background); }
|
||||
|
|
After Width: | Height: | Size: 12 KiB |
|
@ -1 +1 @@
|
|||
window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAA5WZT3PbNhDFvwt7dZtIVtLGN/9RFU+s2mNnmkOmB5hcSajIBQcEFaudfvcOCUkACXCXuu577ydwAZIg9P3fxMCbSa6SDFaizk1ykZTCbJKrRGIGb79sTJH/5LStxCy5mk0+zS7fz/67OKW/AlZKu3ChsjqH6p2ttxSX9nKZFj/CVFPtZS6SdCPzTAMmV99PcVUaqbByhJ3QUryeGAe9y7qcegMQee7SqxrTNmDTIs+7yY/+0F9Vth+MNiKRTQXuRDWYtjKRX4kUBtONSGTXUJlaD8cPOkHYCMwG441IZCVKM5htRCKrXv+GdDhtZSJfgq4UDuatHOT/8giFMOkmXK9tedSCvYMq1bI0/r1i9uWJ4fQubvr+06+TD/7CXTb+x/7691m+g6NlsjIC44vK0o4OalXK+LqwgEYlwpUsZC60NNGbyiKch54llUFeRaaprY+ap2UPkeaiqhxiGSFNpr95Y/gCGiF/LCv/gWpANzfnCXMy9abnw0d/ohvvixGGRDkXxdqJXGbCQOuO9tnSOj6y188Ctw4EWBfVu6bWDfmdmeMu7Oscd1Q3F1qUm96gj1GnUYTPdSEwDLdlKtd/sR2Dtv7zhMp+g9dbUYRZW6eSNyrb3ypcyXV0zp1MTXbj+gL7Ukk0g5ijgQM9Q9XbHXQwVqYgxOXwl3KnxY/gWecRPJ3C/C5SuEYjX0qlVsSAIj4WawxgMwAO2/VxWIY2DnJ8qfCjC5w82kBqlGa5vo2Dzgs1YqwdF4dcgODG6Cwc7F7LioE5Cwd7kDtAqDhg18ZBl1BtGKCzcDDi1ncyCZG5AbL9noECLQBBy5QgdRw0qt3lkijPQaE+C8wIjpM5CNFoJ7NbhXtcqSjjpFKIx3YTTVyOb+BBxCX5Bgr01G7LCZBvoEAEgg+/wLoANIJ5MIU2Cmo3AgTON1Cga9zf9j4p7ZfASeA+AK5xf1+INUQAbX1E/k+ZgYrk2zqXvxHpFjCbY130EZ7EUlS2v0ZUdgICUEc9j3WTi3/gSVVBgwZs59Hnq5VMJaDhf6FjHfMri/73vqMuYp/6ccqDwKwQehvDHLVzOGQ/A9M55FOD/gBDwX3fOfyl2gGDPljOoTZXyVAPFp76FlLeuNRhN9VPHspsegdogoePrbLZNwMaRR5/gHVVjmX3cdH17kljKEPr3ddYjsQ1BAc9tjoue1vrPJ5vlHGMO6khjc1tT+ZoC8AsvBpb5bNt4/tv4CPCEzlSsxEamGFPGkP5ui+jiKbO5dtXot3ABCvW11gOlnXQj7bIJrWsBvrgSRzFDjPWCadwjKfu+YKNP0XOFILkc+cU2wafg8PrMOdvsmIbhr7O8exZzuSuzznWx+WnA/npyPzlQP5yZH42kJ+NzD/IbTAbTuEY34Qu6jI2G05hD6Ht30zxv3MOGvFXDvgHiy4JuOsf03VjRRk/c26F8PDzf7TeFt4zGwAA"
|
||||
window.navigationData = "eJyVmU9z2zYQxb8Le3WbSFbSxjf/URVP7Npje5pDJgeYXEmoyAUHBBWrnXz3DglJAAlwl7rue+8nEABJcPXtv8TAm0kukkyLH8lZUgqzTi6SQmV1DtW7pvrb2hR5cpZsJGbJxewsSdcyzzRgcvHtGFelkQorR9gKLcXrkbHXu6zz6c+zI0HkuUsva0zbgE2LPO8mP8685KvKdoPRRiSyqcCtqAbTVibyS5HCYLoRiewKKlPr4fheJwhrgdlgvBGJrERpBrONSGTV6z+QDqetTORL0JXCwbyVibwBrJQezFs5yH/3CIUw6Trc72151Ia/gSrVsjT+MMyuPDKc3sVN33/6ffLB3/j3jf+hf//4LN/B0TJZGYHxTWlpBwe1q2V8X1lAoxLhShYyF1qa6E1pEc5Dr5LKIK8iy9TWR63TfQ+R5qKqHOI+QppM//DG8AU0Qv5QegyJBnRzcx8xR1NveT589Be68T4bYUiUc1GsrchlJgy07ug8W1rHR871S++eOsz1S+Rm8pf7SeDGpQDronrX1LoJf0bnuA3XY45bahUWWpTr3sUeok6jCJ/rQmAYbstUrj8vh6Ct/zqhsl/h9VoUYdbWqeSVynbXCpdyFd0rTqY2SeP6ArtSSTSDmIOBAz1BVefDGCtTEOJy+Eu50eJH8Iz0CJ5OYf4UKVyikc+lUktiQBEfizUGsBkAh+36OCxDGwc5vIz40QVOHm0gNUqzXN/GQeeFGjHWjotDLkBwY3QWDnarZcXAnIWD3cktIFQcsGvjoPdQrRmgs3Aw4tZ3MgmRuQFy+j0DBVoAgpYpQeo4aFR7uiZRnoNCfRaYERwncxBiop3MHjFucamijKNKIR7awztxOb6BBxGX5Bso0GP7OUCAfAMFIhB8+BlWBaARzIMptFFQexAgcL6BAl3i7rr3KWu/II4C9+FwibvbQqwgAmjrI/J/ywxUJN/WufyVSDeA2Rzroo/wJJaist0lorILEIA66mmsq1z8C4+qCiZowHYafb5cylQCGv4XOtYxv7Lo9xkcdRFrMcQpdwKzQuhNDHPQTuGQ8xmYTiEfJ+gvMBTc953Cv1dbYNB7yynU5ioZ6t7CU99CyhuX2p+m+sl9mU1vAU3w8LFVNvtmQKPI4w+wrsqx7Dkuut89aQxlaL/7GsuRuIKgQWSr47LXtc7j+UYZx7iRGtLY2vZkjrYAzMKrsVU+2058/w18QHgiR2oOQgMr7EljKC+7Mopo6ly+fSXaA0ywY32N5WBZB/PRFtmkltXAPHgSR7HDjM2EUzjGY7e/YOOPkZ5CkHzqdM9t8Clomoc5/5AVOzD0dY5nezmTmz7nUB+Xnw7kpyPz5wP585H52UB+NjJ/JzfBajiFY3wVuqjL2Go4hW1ew1LUuYn/jbTXiL+QwG8suiTgtt+m68aKMt6rbgWi070fkn9wz8C+aH9x2r5lOvk0O38/+/n9f3cUMM8="
|
|
@ -0,0 +1,2 @@
|
|||
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>tensor | @vladmandic/human - v3.3.5</title><meta name="description" content="Documentation for @vladmandic/human"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">@vladmandic/human - v3.3.5</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../index.html">@vladmandic/human</a></li><li><a href="../modules/draw.html">draw</a></li><li><a href="draw.tensor.html">tensor</a></li></ul><h1>Function tensor</h1></div><section class="tsd-panel"><ul class="tsd-signatures"><li class="tsd-signature tsd-anchor-link"><a id="tensor" class="tsd-anchor"></a><span class="tsd-kind-call-signature">tensor</span><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">input</span><span class="tsd-signature-symbol">:</span> <a href="../types/Tensor2D.html" class="tsd-signature-type tsd-kind-type-alias">Tensor2D</a><span class="tsd-signature-symbol">,</span> <span class="tsd-kind-parameter">output</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">HTMLCanvasElement</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">></span><a href="#tensor" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></li><li class="tsd-description"><div class="tsd-comment tsd-typography"><p>draw processed canvas</p>
|
||||
</div><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">input</span>: <a href="../types/Tensor2D.html" class="tsd-signature-type tsd-kind-type-alias">Tensor2D</a></span></li><li><span><span class="tsd-kind-parameter">output</span>: <span class="tsd-signature-type">HTMLCanvasElement</span></span></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">></span></h4><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/vladmandic/human/blob/main/src/draw/draw.ts#L66">src/draw/draw.ts:66</a></li></ul></aside></li></ul></section></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../index.html">@vladmandic/human - v3.3.5</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer></footer><div class="overlay"></div></body></html>
|