enhanced movenet postprocessing

pull/193/head
Vladimir Mandic 2021-10-14 12:26:59 -04:00
parent 9ba929e335
commit 105527dfd6
22 changed files with 3103 additions and 2575 deletions

View File

@ -11,6 +11,7 @@
### **HEAD -> main** 2021/10/13 mandic00@live.com
- use transferrable buffer for worker messages
- add optional anti-spoofing module
- add node-match advanced example using worker thread pool
- package updates

View File

@ -32,7 +32,7 @@ let human;
let userConfig = {
// face: { enabled: false },
// body: { enabled: false },
// body: { enabled: true },
// hand: { enabled: false },
/*
warmup: 'none',

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

586
dist/human.esm.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

756
dist/human.js vendored

File diff suppressed because one or more lines are too long

761
dist/human.node-gpu.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

761
dist/human.node.js vendored

File diff suppressed because it is too large Load Diff

View File

@ -66,15 +66,15 @@
"@tensorflow/tfjs-layers": "^3.9.0",
"@tensorflow/tfjs-node": "^3.9.0",
"@tensorflow/tfjs-node-gpu": "^3.9.0",
"@types/node": "^16.10.5",
"@types/node": "^16.10.9",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"@vladmandic/build": "^0.6.0",
"@vladmandic/pilogger": "^0.3.3",
"canvas": "^2.8.0",
"dayjs": "^1.10.7",
"esbuild": "^0.13.5",
"eslint": "8.0.0",
"esbuild": "^0.13.6",
"eslint": "8.0.1",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-json": "^3.1.0",

View File

@ -8,6 +8,7 @@ import { log, join } from '../util/util';
import * as box from '../util/box';
import * as tf from '../../dist/tfjs.esm.js';
import * as coords from './movenetcoords';
import * as fix from './movenetfix';
import type { BodyKeypoint, BodyResult, Box, Point } from '../result';
import type { GraphModel, Tensor } from '../tfjs/types';
import type { Config } from '../config';
@ -16,19 +17,17 @@ import { env } from '../util/env';
let model: GraphModel | null;
let inputSize = 0;
const boxExpandFact = 1.5; // increase to 150%
let skipped = Number.MAX_SAFE_INTEGER;
// const boxExpandFact = 1.5; // increase to 150%
const cache: {
boxes: Array<Box>,
boxes: Array<Box>, // unused
bodies: Array<BodyResult>;
} = {
boxes: [],
bodies: [],
};
let skipped = Number.MAX_SAFE_INTEGER;
const keypoints: Array<BodyKeypoint> = [];
export async function load(config: Config): Promise<GraphModel> {
if (env.initial) model = null;
if (!model) {
@ -42,23 +41,9 @@ export async function load(config: Config): Promise<GraphModel> {
return model;
}
function fixSides() { // model sometimes mixes up left vs right keypoints so we fix them
for (const pair of coords.pairs) {
let left = keypoints.find((kp) => kp.part === pair[0]);
let right = keypoints.find((kp) => kp.part === pair[1]);
if (left && right) {
if (left.position[0] > right.position[0]) {
const tmp = left;
left = right;
right = tmp;
}
}
}
}
async function parseSinglePose(res, config, image, inputBox) {
const kpt = res[0][0];
keypoints.length = 0;
const keypoints: Array<BodyKeypoint> = [];
let score = 0;
for (let id = 0; id < kpt.length; id++) {
score = kpt[id][2];
@ -78,7 +63,6 @@ async function parseSinglePose(res, config, image, inputBox) {
});
}
}
fixSides();
score = keypoints.reduce((prev, curr) => (curr.score > prev ? curr.score : prev), 0);
const bodies: Array<BodyResult> = [];
const newBox = box.calc(keypoints.map((pt) => pt.position), [image.shape[2], image.shape[1]]);
@ -92,7 +76,9 @@ async function parseSinglePose(res, config, image, inputBox) {
}
annotations[name] = pt;
}
bodies.push({ id: 0, score, box: newBox.box, boxRaw: newBox.boxRaw, keypoints, annotations });
const body: BodyResult = { id: 0, score, box: newBox.box, boxRaw: newBox.boxRaw, keypoints, annotations };
fix.bodyParts(body);
bodies.push(body);
return bodies;
}
@ -102,7 +88,7 @@ async function parseMultiPose(res, config, image, inputBox) {
const kpt = res[0][id];
const totalScore = Math.round(100 * kpt[51 + 4]) / 100;
if (totalScore > config.body.minConfidence) {
keypoints.length = 0;
const keypoints: Array<BodyKeypoint> = [];
for (let i = 0; i < 17; i++) {
const score = kpt[3 * i + 2];
if (score > config.body.minConfidence) {
@ -118,7 +104,6 @@ async function parseMultiPose(res, config, image, inputBox) {
});
}
}
fixSides();
const newBox = box.calc(keypoints.map((pt) => pt.position), [image.shape[2], image.shape[1]]);
// movenet-multipose has built-in box details
// const boxRaw: Box = [kpt[51 + 1], kpt[51 + 0], kpt[51 + 3] - kpt[51 + 1], kpt[51 + 2] - kpt[51 + 0]];
@ -133,7 +118,9 @@ async function parseMultiPose(res, config, image, inputBox) {
}
annotations[name] = pt;
}
bodies.push({ id, score: totalScore, box: newBox.box, boxRaw: newBox.boxRaw, keypoints: [...keypoints], annotations });
const body: BodyResult = { id, score: totalScore, box: newBox.box, boxRaw: newBox.boxRaw, keypoints: [...keypoints], annotations };
fix.bodyParts(body);
bodies.push(body);
}
}
bodies.sort((a, b) => b.score - a.score);
@ -158,11 +145,14 @@ export async function predict(input: Tensor, config: Config): Promise<BodyResult
return new Promise(async (resolve) => {
const t: Record<string, Tensor> = {};
skipped = 0;
// run detection on squared input and cached boxes
/*
cache.bodies = []; // reset bodies result
if (cache.boxes.length >= (config.body.maxDetected || 0)) { // if we have enough cached boxes run detection using cache
for (let i = 0; i < cache.boxes.length; i++) { // run detection based on cached boxes
t.crop = tf.image.cropAndResize(input, [cache.boxes[i]], [0], [inputSize, inputSize], 'bilinear');
t.cast = tf.cast(t.crop, 'int32');
// t.input = prepareImage(input);
t.res = await model?.predict(t.cast) as Tensor;
const res = await t.res.array();
const newBodies = (t.res.shape[2] === 17) ? await parseSinglePose(res, config, input, cache.boxes[i]) : await parseMultiPose(res, config, input, cache.boxes[i]);
@ -171,11 +161,11 @@ export async function predict(input: Tensor, config: Config): Promise<BodyResult
}
}
if (cache.bodies.length !== config.body.maxDetected) { // did not find enough bodies based on cached boxes so run detection on full frame
t.resized = tf.image.resizeBilinear(input, [inputSize, inputSize], false);
t.cast = tf.cast(t.resized, 'int32');
t.res = await model?.predict(t.cast) as Tensor;
t.input = prepareImage(input);
t.res = await model?.predict(t.input) as Tensor;
const res = await t.res.array();
cache.bodies = (t.res.shape[2] === 17) ? await parseSinglePose(res, config, input, [0, 0, 1, 1]) : await parseMultiPose(res, config, input, [0, 0, 1, 1]);
for (const body of cache.bodies) rescaleBody(body, [input.shape[2] || 1, input.shape[1] || 1]);
Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));
}
cache.boxes.length = 0; // reset cache
@ -186,6 +176,21 @@ export async function predict(input: Tensor, config: Config): Promise<BodyResult
cache.boxes.push(cropBox);
}
}
*/
// run detection on squared input and no cached boxes
t.input = fix.padInput(input, inputSize);
t.res = await model?.predict(t.input) as Tensor;
const res = await t.res.array();
cache.bodies = (t.res.shape[2] === 17)
? await parseSinglePose(res, config, input, [0, 0, 1, 1])
: await parseMultiPose(res, config, input, [0, 0, 1, 1]);
for (const body of cache.bodies) {
fix.rescaleBody(body, [input.shape[2] || 1, input.shape[1] || 1]);
fix.jitter(body.keypoints);
}
Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));
resolve(cache.bodies);
});
}

View File

@ -1,4 +1,4 @@
export const kpt: Array<string> = [
export const kpt: Array<string> = [ // used to create part labels
'nose',
'leftEye',
'rightEye',
@ -18,7 +18,7 @@ export const kpt: Array<string> = [
'rightAnkle',
];
export const pairs: Array<string[]> = [
export const horizontal: Array<string[]> = [ // used to fix left vs right
['leftEye', 'rightEye'],
['leftEar', 'rightEar'],
['leftShoulder', 'rightShoulder'],
@ -29,7 +29,19 @@ export const pairs: Array<string[]> = [
['leftAnkle', 'rightAnkle'],
];
export const connected: Record<string, string[]> = {
export const vertical: Array<string[]> = [ // used to remove unlikely keypoint positions
['leftKnee', 'leftShoulder'],
['rightKnee', 'rightShoulder'],
['leftAnkle', 'leftKnee'],
['rightAnkle', 'rightKnee'],
];
export const relative: Array<string[][]> = [ // used to match relative body parts
[['leftHip', 'rightHip'], ['leftShoulder', 'rightShoulder']],
[['leftElbow', 'rightElbow'], ['leftShoulder', 'rightShoulder']],
];
export const connected: Record<string, string[]> = { // used to create body outline in annotations
leftLeg: ['leftHip', 'leftKnee', 'leftAnkle'],
rightLeg: ['rightHip', 'rightKnee', 'rightAnkle'],
torso: ['leftShoulder', 'rightShoulder', 'rightHip', 'leftHip', 'leftShoulder'],

107
src/body/movenetfix.ts Normal file
View File

@ -0,0 +1,107 @@
import type { BodyKeypoint, BodyResult } from '../result';
import * as box from '../util/box';
import * as coords from './movenetcoords';
import * as tf from '../../dist/tfjs.esm.js';
import type { Tensor } from '../tfjs/types';
const maxJitter = 0.005; // default allowed jitter is within 0.5%
const cache: {
keypoints: Array<BodyKeypoint>,
padding: [number, number][];
} = {
keypoints: [],
padding: [[0, 0], [0, 0], [0, 0], [0, 0]],
};
export function bodyParts(body: BodyResult) { // model sometimes mixes up left vs right keypoints so we fix them
for (const pair of coords.horizontal) { // fix body parts left vs right
const left = body.keypoints.findIndex((kp) => kp.part === pair[0]);
const right = body.keypoints.findIndex((kp) => kp.part === pair[1]);
if (body.keypoints[left] && body.keypoints[right]) {
if (body.keypoints[left].position[0] < body.keypoints[right].position[0]) {
const tmp = body.keypoints[left];
body.keypoints[left] = body.keypoints[right];
body.keypoints[right] = tmp;
}
}
}
for (const pair of coords.vertical) { // remove body parts with improbable vertical position
const lower = body.keypoints.findIndex((kp) => (kp && kp.part === pair[0]));
const higher = body.keypoints.findIndex((kp) => (kp && kp.part === pair[1]));
if (body.keypoints[lower] && body.keypoints[higher]) {
if (body.keypoints[lower].position[1] < body.keypoints[higher].position[1]) {
body.keypoints.splice(lower, 1);
}
}
}
for (const [pair, compare] of coords.relative) { // rearrange body parts according to their relative position
const left = body.keypoints.findIndex((kp) => (kp && kp.part === pair[0]));
const right = body.keypoints.findIndex((kp) => (kp && kp.part === pair[1]));
const leftTo = body.keypoints.findIndex((kp) => (kp && kp.part === compare[0]));
const rightTo = body.keypoints.findIndex((kp) => (kp && kp.part === compare[1]));
if (!body.keypoints[leftTo] || !body.keypoints[rightTo]) continue; // only if we have both compare points
const distanceLeft = body.keypoints[left] ? [
Math.abs(body.keypoints[leftTo].position[0] - body.keypoints[left].position[0]),
Math.abs(body.keypoints[rightTo].position[0] - body.keypoints[left].position[0]),
] : [0, 0];
const distanceRight = body.keypoints[right] ? [
Math.abs(body.keypoints[rightTo].position[0] - body.keypoints[right].position[0]),
Math.abs(body.keypoints[leftTo].position[0] - body.keypoints[right].position[0]),
] : [0, 0];
if (distanceLeft[0] > distanceLeft[1] || distanceRight[0] > distanceRight[1]) { // should flip keypoints
const tmp = body.keypoints[left];
body.keypoints[left] = body.keypoints[right];
body.keypoints[right] = tmp;
}
}
}
export function jitter(keypoints: Array<BodyKeypoint>): Array<BodyKeypoint> {
for (let i = 0; i < keypoints.length; i++) {
if (keypoints[i] && cache.keypoints[i]) {
const diff = [Math.abs(keypoints[i].positionRaw[0] - cache.keypoints[i].positionRaw[0]), Math.abs(keypoints[i].positionRaw[1] - cache.keypoints[i].positionRaw[1])];
if (diff[0] < maxJitter && diff[1] < maxJitter) {
keypoints[i] = cache.keypoints[i]; // below jitter so replace keypoint
} else {
cache.keypoints[i] = keypoints[i]; // above jitter so update cache
}
} else {
cache.keypoints[i] = keypoints[i]; // cache for keypoint doesnt exist so create it here
}
}
return keypoints;
}
export function padInput(input: Tensor, inputSize: number): Tensor {
const t: Record<string, Tensor> = {};
if (!input.shape || !input.shape[1] || !input.shape[2]) return input;
cache.padding = [
[0, 0], // dont touch batch
[input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0, input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0], // height before&after
[input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0, input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0], // width before&after
[0, 0], // dont touch rbg
];
t.pad = tf.pad(input, cache.padding);
t.resize = tf.image.resizeBilinear(t.pad, [inputSize, inputSize]);
const final = tf.cast(t.resize, 'int32');
Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));
return final;
}
export function rescaleBody(body: BodyResult, outputSize: [number, number]): BodyResult {
body.keypoints = body.keypoints.filter((kpt) => kpt && kpt.position); // filter invalid keypoints
for (const kpt of body.keypoints) {
kpt.position = [
kpt.position[0] * (outputSize[0] + cache.padding[2][0] + cache.padding[2][1]) / outputSize[0] - cache.padding[2][0],
kpt.position[1] * (outputSize[1] + cache.padding[1][0] + cache.padding[1][1]) / outputSize[1] - cache.padding[1][0],
];
kpt.positionRaw = [
kpt.position[0] / outputSize[0], kpt.position[1] / outputSize[1],
];
}
const rescaledBoxes = box.calc(body.keypoints.map((pt) => pt.position), outputSize);
body.box = rescaledBoxes.box;
body.boxRaw = rescaledBoxes.boxRaw;
return body;
}

View File

@ -426,7 +426,7 @@ const config: Config = {
// should be set to the minimum number for performance
// only valid for posenet and movenet-multipose as other models detects single pose
// set to -1 to autodetect based on number of detected faces
minConfidence: 0.2, // threshold for discarding a prediction
minConfidence: 0.3, // threshold for discarding a prediction
skipFrames: 1, // how many max frames to go without re-running the detector
// only used when cacheSensitivity is not zero
},

View File

@ -1,24 +1,24 @@
2021-10-13 14:43:36 INFO:  @vladmandic/human version 2.3.3
2021-10-13 14:43:36 INFO:  User: vlado Platform: linux Arch: x64 Node: v16.10.0
2021-10-13 14:43:36 INFO:  Application: {"name":"@vladmandic/human","version":"2.3.3"}
2021-10-13 14:43:36 INFO:  Environment: {"profile":"production","config":"build.json","tsconfig":true,"eslintrc":true,"git":true}
2021-10-13 14:43:36 INFO:  Toolchain: {"build":"0.6.0","esbuild":"0.13.5","typescript":"4.4.4","typedoc":"0.22.5","eslint":"8.0.0"}
2021-10-13 14:43:36 INFO:  Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
2021-10-13 14:43:36 STATE: Clean: {"locations":["dist/*","types/*","typedoc/*"]}
2021-10-13 14:43:36 STATE: Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":102,"outputBytes":1275}
2021-10-13 14:43:36 STATE: Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":54,"inputBytes":519262,"outputBytes":431321}
2021-10-13 14:43:36 STATE: Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":1283}
2021-10-13 14:43:36 STATE: Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":54,"inputBytes":519270,"outputBytes":431325}
2021-10-13 14:43:36 STATE: Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":149,"outputBytes":1350}
2021-10-13 14:43:36 STATE: Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":54,"inputBytes":519337,"outputBytes":431397}
2021-10-13 14:43:36 STATE: Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1063,"outputBytes":1631}
2021-10-13 14:43:36 STATE: Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":3085,"outputBytes":856}
2021-10-13 14:43:36 STATE: Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":54,"inputBytes":518843,"outputBytes":432935}
2021-10-13 14:43:37 STATE: Compile: {"name":"tfjs/browser/esm/bundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":8,"inputBytes":3085,"outputBytes":2691961}
2021-10-13 14:43:37 STATE: Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":54,"inputBytes":3209948,"outputBytes":1609306}
2021-10-13 14:43:38 STATE: Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":54,"inputBytes":3209948,"outputBytes":2924745}
2021-10-13 14:43:56 STATE: Typings: {"input":"src/human.ts","output":"types","files":6}
2021-10-13 14:44:02 STATE: TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":36,"generated":true}
2021-10-13 14:44:32 STATE: Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":90,"errors":0,"warnings":0}
2021-10-13 14:44:33 STATE: ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
2021-10-13 14:44:33 INFO:  Done...
2021-10-14 12:23:28 INFO:  @vladmandic/human version 2.3.3
2021-10-14 12:23:28 INFO:  User: vlado Platform: linux Arch: x64 Node: v16.10.0
2021-10-14 12:23:28 INFO:  Application: {"name":"@vladmandic/human","version":"2.3.3"}
2021-10-14 12:23:28 INFO:  Environment: {"profile":"production","config":"build.json","tsconfig":true,"eslintrc":true,"git":true}
2021-10-14 12:23:28 INFO:  Toolchain: {"build":"0.6.0","esbuild":"0.13.6","typescript":"4.4.4","typedoc":"0.22.5","eslint":"8.0.1"}
2021-10-14 12:23:28 INFO:  Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
2021-10-14 12:23:28 STATE: Clean: {"locations":["dist/*","types/*","typedoc/*"]}
2021-10-14 12:23:28 STATE: Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":102,"outputBytes":1275}
2021-10-14 12:23:28 STATE: Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":55,"inputBytes":525473,"outputBytes":434511}
2021-10-14 12:23:28 STATE: Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":1283}
2021-10-14 12:23:28 STATE: Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":55,"inputBytes":525481,"outputBytes":434515}
2021-10-14 12:23:28 STATE: Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":149,"outputBytes":1350}
2021-10-14 12:23:28 STATE: Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":55,"inputBytes":525548,"outputBytes":434587}
2021-10-14 12:23:28 STATE: Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1063,"outputBytes":1631}
2021-10-14 12:23:28 STATE: Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":3085,"outputBytes":856}
2021-10-14 12:23:28 STATE: Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":55,"inputBytes":525054,"outputBytes":436070}
2021-10-14 12:23:29 STATE: Compile: {"name":"tfjs/browser/esm/bundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":8,"inputBytes":3085,"outputBytes":2691961}
2021-10-14 12:23:30 STATE: Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":55,"inputBytes":3216159,"outputBytes":1611238}
2021-10-14 12:23:30 STATE: Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":55,"inputBytes":3216159,"outputBytes":2927935}
2021-10-14 12:23:48 STATE: Typings: {"input":"src/human.ts","output":"types","files":6}
2021-10-14 12:23:54 STATE: TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":36,"generated":true}
2021-10-14 12:24:25 STATE: Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":91,"errors":0,"warnings":0}
2021-10-14 12:24:25 STATE: ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
2021-10-14 12:24:25 INFO:  Done...

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
{"version":3,"file":"movenet.d.ts","sourceRoot":"","sources":["../../../src/body/movenet.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAgB,UAAU,EAAc,MAAM,WAAW,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAmBxC,wBAAsB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAW9D;AAqGD,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CA+ClF"}
{"version":3,"file":"movenet.d.ts","sourceRoot":"","sources":["../../../src/body/movenet.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAgB,UAAU,EAAc,MAAM,WAAW,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAiBxC,wBAAsB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAW9D;AAyFD,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAiElF"}

View File

@ -1,4 +1,6 @@
export declare const kpt: Array<string>;
export declare const pairs: Array<string[]>;
export declare const horizontal: Array<string[]>;
export declare const vertical: Array<string[]>;
export declare const relative: Array<string[][]>;
export declare const connected: Record<string, string[]>;
//# sourceMappingURL=movenetcoords.d.ts.map

View File

@ -1 +1 @@
{"version":3,"file":"movenetcoords.d.ts","sourceRoot":"","sources":["../../../src/body/movenetcoords.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,GAAG,EAAE,KAAK,CAAC,MAAM,CAkB7B,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,CASjC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAO9C,CAAC"}
{"version":3,"file":"movenetcoords.d.ts","sourceRoot":"","sources":["../../../src/body/movenetcoords.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,GAAG,EAAE,KAAK,CAAC,MAAM,CAkB7B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,MAAM,EAAE,CAStC,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,CAKpC,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,CAGtC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAO9C,CAAC"}

7
types/src/body/movenetfix.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
import type { BodyKeypoint, BodyResult } from '../result';
import type { Tensor } from '../tfjs/types';
export declare function bodyParts(body: BodyResult): void;
export declare function jitter(keypoints: Array<BodyKeypoint>): Array<BodyKeypoint>;
export declare function padInput(input: Tensor, inputSize: number): Tensor;
export declare function rescaleBody(body: BodyResult, outputSize: [number, number]): BodyResult;
//# sourceMappingURL=movenetfix.d.ts.map

View File

@ -0,0 +1 @@
{"version":3,"file":"movenetfix.d.ts","sourceRoot":"","sources":["../../../src/body/movenetfix.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAI1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAY5C,wBAAgB,SAAS,CAAC,IAAI,EAAE,UAAU,QAyCzC;AAED,wBAAgB,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC,CAc1E;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAcjE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,UAAU,CAetF"}