mirror of https://github.com/vladmandic/human
convert to typescript
parent
ea9847927b
commit
6fb133b55e
|
@ -46,7 +46,7 @@ Compatible with *Browser*, *WebWorker* and *NodeJS* execution on both Windows an
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
*This is a pre-release project, see [issues](https://github.com/vladmandic/human/issues) for list of known limitations and planned enhancements*
|
*See [issues](https://github.com/vladmandic/human/issues?q=) and [discussions](https://github.com/vladmandic/human/discussions) for list of known limitations and planned enhancements*
|
||||||
|
|
||||||
*Suggestions are welcome!*
|
*Suggestions are welcome!*
|
||||||
|
|
||||||
|
|
|
@ -56,14 +56,19 @@ async function detect(input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function test() {
|
async function test() {
|
||||||
|
// test with embedded face image
|
||||||
log.state('Processing embedded warmup image: face');
|
log.state('Processing embedded warmup image: face');
|
||||||
myConfig.warmup = 'face';
|
myConfig.warmup = 'face';
|
||||||
const resultFace = await human.warmup(myConfig);
|
const resultFace = await human.warmup(myConfig);
|
||||||
log.data(resultFace);
|
log.data('Face: ', resultFace.face);
|
||||||
|
|
||||||
|
// test with embedded full body image
|
||||||
log.state('Processing embedded warmup image: full');
|
log.state('Processing embedded warmup image: full');
|
||||||
myConfig.warmup = 'full';
|
myConfig.warmup = 'full';
|
||||||
const resultFull = await human.warmup(myConfig);
|
const resultFull = await human.warmup(myConfig);
|
||||||
log.data(resultFull);
|
log.data('Body:', resultFull.body);
|
||||||
|
log.data('Hand:', resultFull.hand);
|
||||||
|
log.data('Gesture:', resultFull.gesture);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"dist/human.esm.js": {
|
"dist/human.esm.js": {
|
||||||
"bytes": 1349003,
|
"bytes": 1343005,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"demo/draw.js": {
|
"demo/draw.js": {
|
||||||
|
@ -43,14 +43,14 @@
|
||||||
"imports": [],
|
"imports": [],
|
||||||
"exports": [],
|
"exports": [],
|
||||||
"inputs": {},
|
"inputs": {},
|
||||||
"bytes": 2028101
|
"bytes": 2018414
|
||||||
},
|
},
|
||||||
"dist/demo-browser-index.js": {
|
"dist/demo-browser-index.js": {
|
||||||
"imports": [],
|
"imports": [],
|
||||||
"exports": [],
|
"exports": [],
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"dist/human.esm.js": {
|
"dist/human.esm.js": {
|
||||||
"bytesInOutput": 1340450
|
"bytesInOutput": 1335513
|
||||||
},
|
},
|
||||||
"demo/draw.js": {
|
"demo/draw.js": {
|
||||||
"bytesInOutput": 6204
|
"bytesInOutput": 6204
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
"bytesInOutput": 16815
|
"bytesInOutput": 16815
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bytes": 1388309
|
"bytes": 1383372
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"src/log.js": {
|
"src/log.ts": {
|
||||||
"bytes": 401,
|
"bytes": 401,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"dist/tfjs.esm.js": {
|
"dist/tfjs.esm.js": {
|
||||||
"bytes": 1071833,
|
"bytes": 1071825,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/tfjs/backend.js": {
|
"src/tfjs/backend.ts": {
|
||||||
"bytes": 2171,
|
"bytes": 2168,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -21,11 +21,11 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/blazeface/blazeface.js": {
|
"src/blazeface/blazeface.ts": {
|
||||||
"bytes": 7024,
|
"bytes": 6024,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -34,8 +34,8 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/blazeface/box.js": {
|
"src/blazeface/box.ts": {
|
||||||
"bytes": 1935,
|
"bytes": 1727,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
|
@ -43,44 +43,40 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/blazeface/util.js": {
|
"src/blazeface/util.ts": {
|
||||||
"bytes": 3087,
|
"bytes": 2777,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/blazeface/coords.js": {
|
"src/blazeface/coords.ts": {
|
||||||
"bytes": 37915,
|
"bytes": 37783,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/blazeface/facepipeline.js": {
|
"src/blazeface/facepipeline.ts": {
|
||||||
"bytes": 14275,
|
"bytes": 14254,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/blazeface/box.js",
|
"path": "src/blazeface/box.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/blazeface/util.js",
|
"path": "src/blazeface/util.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/blazeface/coords.js",
|
"path": "src/blazeface/coords.ts",
|
||||||
"kind": "import-statement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/log.js",
|
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/blazeface/facemesh.js": {
|
"src/blazeface/facemesh.ts": {
|
||||||
"bytes": 2973,
|
"bytes": 2935,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -88,33 +84,33 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/blazeface/blazeface.js",
|
"path": "src/blazeface/blazeface.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/blazeface/facepipeline.js",
|
"path": "src/blazeface/facepipeline.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/blazeface/coords.js",
|
"path": "src/blazeface/coords.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/profile.js": {
|
"src/profile.ts": {
|
||||||
"bytes": 1045,
|
"bytes": 1004,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/faceboxes/faceboxes.js": {
|
"src/faceboxes/faceboxes.ts": {
|
||||||
"bytes": 2612,
|
"bytes": 2852,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -122,16 +118,16 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/age/age.js": {
|
"src/age/age.ts": {
|
||||||
"bytes": 2037,
|
"bytes": 2064,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -139,16 +135,16 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/gender/gender.js": {
|
"src/gender/gender.ts": {
|
||||||
"bytes": 2906,
|
"bytes": 2904,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -156,16 +152,16 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/emotion/emotion.js": {
|
"src/emotion/emotion.ts": {
|
||||||
"bytes": 3056,
|
"bytes": 3033,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -173,16 +169,16 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/embedding/embedding.js": {
|
"src/embedding/embedding.ts": {
|
||||||
"bytes": 2063,
|
"bytes": 1992,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -190,13 +186,13 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/modelBase.js": {
|
"src/posenet/modelBase.ts": {
|
||||||
"bytes": 1343,
|
"bytes": 1333,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
|
@ -204,93 +200,93 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/heapSort.js": {
|
"src/posenet/heapSort.ts": {
|
||||||
"bytes": 1590,
|
"bytes": 1645,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/posenet/buildParts.js": {
|
"src/posenet/buildParts.ts": {
|
||||||
"bytes": 1775,
|
"bytes": 1723,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/posenet/heapSort.js",
|
"path": "src/posenet/heapSort.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/keypoints.js": {
|
"src/posenet/keypoints.ts": {
|
||||||
"bytes": 2011,
|
"bytes": 2025,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/posenet/vectors.js": {
|
"src/posenet/vectors.ts": {
|
||||||
"bytes": 1273,
|
"bytes": 1075,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/posenet/keypoints.js",
|
"path": "src/posenet/keypoints.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/decoders.js": {
|
"src/posenet/decoders.ts": {
|
||||||
"bytes": 2083,
|
"bytes": 1943,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/keypoints.js",
|
"path": "src/posenet/keypoints.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/decodePose.js": {
|
"src/posenet/decodePose.ts": {
|
||||||
"bytes": 5368,
|
"bytes": 5152,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/posenet/keypoints.js",
|
"path": "src/posenet/keypoints.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/vectors.js",
|
"path": "src/posenet/vectors.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/decoders.js",
|
"path": "src/posenet/decoders.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/decodeMultiple.js": {
|
"src/posenet/decodeMultiple.ts": {
|
||||||
"bytes": 2373,
|
"bytes": 2259,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/posenet/buildParts.js",
|
"path": "src/posenet/buildParts.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/decodePose.js",
|
"path": "src/posenet/decodePose.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/vectors.js",
|
"path": "src/posenet/vectors.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/util.js": {
|
"src/posenet/util.ts": {
|
||||||
"bytes": 2262,
|
"bytes": 2017,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/posenet/keypoints.js",
|
"path": "src/posenet/keypoints.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/modelPoseNet.js": {
|
"src/posenet/posenet.ts": {
|
||||||
"bytes": 2519,
|
"bytes": 2376,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -298,42 +294,25 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/modelBase.js",
|
"path": "src/posenet/modelBase.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/decodeMultiple.js",
|
"path": "src/posenet/decodeMultiple.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/decodePose.js",
|
"path": "src/posenet/decodePose.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/util.js",
|
"path": "src/posenet/util.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/posenet.js": {
|
"src/handpose/box.ts": {
|
||||||
"bytes": 712,
|
"bytes": 2443,
|
||||||
"imports": [
|
|
||||||
{
|
|
||||||
"path": "src/posenet/modelPoseNet.js",
|
|
||||||
"kind": "import-statement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/posenet/keypoints.js",
|
|
||||||
"kind": "import-statement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/posenet/util.js",
|
|
||||||
"kind": "import-statement"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"src/handpose/box.js": {
|
|
||||||
"bytes": 2522,
|
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
|
@ -341,53 +320,49 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/handpose/handdetector.js": {
|
"src/handpose/handdetector.ts": {
|
||||||
"bytes": 3548,
|
"bytes": 3627,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/handpose/box.js",
|
"path": "src/handpose/box.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/handpose/util.js": {
|
"src/handpose/util.ts": {
|
||||||
"bytes": 2346,
|
"bytes": 2254,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/handpose/handpipeline.js": {
|
"src/handpose/handpipeline.ts": {
|
||||||
"bytes": 7246,
|
"bytes": 7344,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/handpose/box.js",
|
"path": "src/handpose/box.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/handpose/util.js",
|
"path": "src/handpose/util.ts",
|
||||||
"kind": "import-statement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/log.js",
|
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/handpose/anchors.js": {
|
"src/handpose/anchors.ts": {
|
||||||
"bytes": 224151,
|
"bytes": 224156,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/handpose/handpose.js": {
|
"src/handpose/handpose.ts": {
|
||||||
"bytes": 2578,
|
"bytes": 2529,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -395,32 +370,32 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/handpose/handdetector.js",
|
"path": "src/handpose/handdetector.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/handpose/handpipeline.js",
|
"path": "src/handpose/handpipeline.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/handpose/anchors.js",
|
"path": "src/handpose/anchors.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/gesture/gesture.js": {
|
"src/gesture/gesture.ts": {
|
||||||
"bytes": 4245,
|
"bytes": 4265,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/imagefx.js": {
|
"src/imagefx.js": {
|
||||||
"bytes": 19445,
|
"bytes": 19447,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/image.js": {
|
"src/image.ts": {
|
||||||
"bytes": 5871,
|
"bytes": 5851,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -437,19 +412,19 @@
|
||||||
"bytes": 9786,
|
"bytes": 9786,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/sample.js": {
|
"src/sample.ts": {
|
||||||
"bytes": 55382,
|
"bytes": 55382,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"package.json": {
|
"package.json": {
|
||||||
"bytes": 2321,
|
"bytes": 2344,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/human.js": {
|
"src/human.ts": {
|
||||||
"bytes": 18962,
|
"bytes": 19393,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -457,51 +432,51 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/tfjs/backend.js",
|
"path": "src/tfjs/backend.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/blazeface/facemesh.js",
|
"path": "src/blazeface/facemesh.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/faceboxes/faceboxes.js",
|
"path": "src/faceboxes/faceboxes.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/age/age.js",
|
"path": "src/age/age.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/gender/gender.js",
|
"path": "src/gender/gender.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/emotion/emotion.js",
|
"path": "src/emotion/emotion.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/embedding/embedding.js",
|
"path": "src/embedding/embedding.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/posenet.js",
|
"path": "src/posenet/posenet.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/handpose/handpose.js",
|
"path": "src/handpose/handpose.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/gesture/gesture.js",
|
"path": "src/gesture/gesture.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/image.js",
|
"path": "src/image.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -509,7 +484,7 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/sample.js",
|
"path": "src/sample.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -524,7 +499,7 @@
|
||||||
"imports": [],
|
"imports": [],
|
||||||
"exports": [],
|
"exports": [],
|
||||||
"inputs": {},
|
"inputs": {},
|
||||||
"bytes": 1932071
|
"bytes": 1923046
|
||||||
},
|
},
|
||||||
"dist/human.esm.js": {
|
"dist/human.esm.js": {
|
||||||
"imports": [],
|
"imports": [],
|
||||||
|
@ -532,125 +507,122 @@
|
||||||
"default"
|
"default"
|
||||||
],
|
],
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"src/blazeface/blazeface.js": {
|
"src/blazeface/facemesh.ts": {
|
||||||
"bytesInOutput": 2915
|
"bytesInOutput": 1445
|
||||||
},
|
},
|
||||||
"src/blazeface/box.js": {
|
"src/posenet/keypoints.ts": {
|
||||||
"bytesInOutput": 987
|
"bytesInOutput": 1690
|
||||||
},
|
|
||||||
"src/blazeface/util.js": {
|
|
||||||
"bytesInOutput": 1197
|
|
||||||
},
|
|
||||||
"src/blazeface/coords.js": {
|
|
||||||
"bytesInOutput": 30534
|
|
||||||
},
|
|
||||||
"src/blazeface/facepipeline.js": {
|
|
||||||
"bytesInOutput": 5578
|
|
||||||
},
|
|
||||||
"src/blazeface/facemesh.js": {
|
|
||||||
"bytesInOutput": 1518
|
|
||||||
},
|
|
||||||
"src/profile.js": {
|
|
||||||
"bytesInOutput": 637
|
|
||||||
},
|
|
||||||
"src/faceboxes/faceboxes.js": {
|
|
||||||
"bytesInOutput": 1387
|
|
||||||
},
|
|
||||||
"src/age/age.js": {
|
|
||||||
"bytesInOutput": 813
|
|
||||||
},
|
|
||||||
"src/gender/gender.js": {
|
|
||||||
"bytesInOutput": 1283
|
|
||||||
},
|
|
||||||
"src/emotion/emotion.js": {
|
|
||||||
"bytesInOutput": 1247
|
|
||||||
},
|
|
||||||
"src/embedding/embedding.js": {
|
|
||||||
"bytesInOutput": 870
|
|
||||||
},
|
|
||||||
"src/posenet/modelBase.js": {
|
|
||||||
"bytesInOutput": 679
|
|
||||||
},
|
|
||||||
"src/posenet/heapSort.js": {
|
|
||||||
"bytesInOutput": 1048
|
|
||||||
},
|
|
||||||
"src/posenet/buildParts.js": {
|
|
||||||
"bytesInOutput": 529
|
|
||||||
},
|
|
||||||
"src/posenet/keypoints.js": {
|
|
||||||
"bytesInOutput": 1638
|
|
||||||
},
|
|
||||||
"src/posenet/vectors.js": {
|
|
||||||
"bytesInOutput": 627
|
|
||||||
},
|
|
||||||
"src/posenet/decoders.js": {
|
|
||||||
"bytesInOutput": 875
|
|
||||||
},
|
|
||||||
"src/posenet/decodePose.js": {
|
|
||||||
"bytesInOutput": 1482
|
|
||||||
},
|
|
||||||
"src/posenet/decodeMultiple.js": {
|
|
||||||
"bytesInOutput": 704
|
|
||||||
},
|
|
||||||
"src/posenet/util.js": {
|
|
||||||
"bytesInOutput": 1065
|
|
||||||
},
|
|
||||||
"src/posenet/modelPoseNet.js": {
|
|
||||||
"bytesInOutput": 1167
|
|
||||||
},
|
|
||||||
"src/posenet/posenet.js": {
|
|
||||||
"bytesInOutput": 401
|
|
||||||
},
|
|
||||||
"src/handpose/handdetector.js": {
|
|
||||||
"bytesInOutput": 1704
|
|
||||||
},
|
|
||||||
"src/handpose/handpipeline.js": {
|
|
||||||
"bytesInOutput": 2485
|
|
||||||
},
|
|
||||||
"src/handpose/anchors.js": {
|
|
||||||
"bytesInOutput": 127006
|
|
||||||
},
|
|
||||||
"src/handpose/handpose.js": {
|
|
||||||
"bytesInOutput": 1331
|
|
||||||
},
|
|
||||||
"src/gesture/gesture.js": {
|
|
||||||
"bytesInOutput": 2424
|
|
||||||
},
|
},
|
||||||
"src/imagefx.js": {
|
"src/imagefx.js": {
|
||||||
"bytesInOutput": 11004
|
"bytesInOutput": 11016
|
||||||
},
|
},
|
||||||
"src/image.js": {
|
"src/log.ts": {
|
||||||
"bytesInOutput": 2480
|
|
||||||
},
|
|
||||||
"src/log.js": {
|
|
||||||
"bytesInOutput": 252
|
"bytesInOutput": 252
|
||||||
},
|
},
|
||||||
"dist/tfjs.esm.js": {
|
"dist/tfjs.esm.js": {
|
||||||
"bytesInOutput": 1062888
|
"bytesInOutput": 1062782
|
||||||
},
|
},
|
||||||
"src/tfjs/backend.js": {
|
"src/tfjs/backend.ts": {
|
||||||
"bytesInOutput": 1205
|
"bytesInOutput": 1205
|
||||||
},
|
},
|
||||||
"src/human.js": {
|
"src/blazeface/blazeface.ts": {
|
||||||
"bytesInOutput": 10537
|
"bytesInOutput": 2185
|
||||||
},
|
},
|
||||||
"src/handpose/box.js": {
|
"src/blazeface/box.ts": {
|
||||||
|
"bytesInOutput": 834
|
||||||
|
},
|
||||||
|
"src/blazeface/util.ts": {
|
||||||
|
"bytesInOutput": 858
|
||||||
|
},
|
||||||
|
"src/blazeface/coords.ts": {
|
||||||
|
"bytesInOutput": 28983
|
||||||
|
},
|
||||||
|
"src/blazeface/facepipeline.ts": {
|
||||||
|
"bytesInOutput": 5046
|
||||||
|
},
|
||||||
|
"src/human.ts": {
|
||||||
|
"bytesInOutput": 10223
|
||||||
|
},
|
||||||
|
"src/faceboxes/faceboxes.ts": {
|
||||||
|
"bytesInOutput": 1549
|
||||||
|
},
|
||||||
|
"src/profile.ts": {
|
||||||
|
"bytesInOutput": 606
|
||||||
|
},
|
||||||
|
"src/age/age.ts": {
|
||||||
|
"bytesInOutput": 826
|
||||||
|
},
|
||||||
|
"src/gender/gender.ts": {
|
||||||
|
"bytesInOutput": 1309
|
||||||
|
},
|
||||||
|
"src/emotion/emotion.ts": {
|
||||||
|
"bytesInOutput": 1243
|
||||||
|
},
|
||||||
|
"src/embedding/embedding.ts": {
|
||||||
|
"bytesInOutput": 802
|
||||||
|
},
|
||||||
|
"src/posenet/posenet.ts": {
|
||||||
|
"bytesInOutput": 1007
|
||||||
|
},
|
||||||
|
"src/posenet/modelBase.ts": {
|
||||||
|
"bytesInOutput": 646
|
||||||
|
},
|
||||||
|
"src/posenet/heapSort.ts": {
|
||||||
|
"bytesInOutput": 1017
|
||||||
|
},
|
||||||
|
"src/posenet/buildParts.ts": {
|
||||||
|
"bytesInOutput": 456
|
||||||
|
},
|
||||||
|
"src/posenet/decodePose.ts": {
|
||||||
|
"bytesInOutput": 1292
|
||||||
|
},
|
||||||
|
"src/posenet/vectors.ts": {
|
||||||
|
"bytesInOutput": 346
|
||||||
|
},
|
||||||
|
"src/posenet/decoders.ts": {
|
||||||
|
"bytesInOutput": 768
|
||||||
|
},
|
||||||
|
"src/posenet/decodeMultiple.ts": {
|
||||||
|
"bytesInOutput": 557
|
||||||
|
},
|
||||||
|
"src/posenet/util.ts": {
|
||||||
|
"bytesInOutput": 354
|
||||||
|
},
|
||||||
|
"src/handpose/handpose.ts": {
|
||||||
|
"bytesInOutput": 1263
|
||||||
|
},
|
||||||
|
"src/handpose/box.ts": {
|
||||||
"bytesInOutput": 938
|
"bytesInOutput": 938
|
||||||
},
|
},
|
||||||
"src/handpose/util.js": {
|
"src/handpose/handdetector.ts": {
|
||||||
|
"bytesInOutput": 1668
|
||||||
|
},
|
||||||
|
"src/handpose/util.ts": {
|
||||||
"bytesInOutput": 816
|
"bytesInOutput": 816
|
||||||
},
|
},
|
||||||
|
"src/handpose/handpipeline.ts": {
|
||||||
|
"bytesInOutput": 2449
|
||||||
|
},
|
||||||
|
"src/handpose/anchors.ts": {
|
||||||
|
"bytesInOutput": 126985
|
||||||
|
},
|
||||||
|
"src/gesture/gesture.ts": {
|
||||||
|
"bytesInOutput": 2391
|
||||||
|
},
|
||||||
|
"src/image.ts": {
|
||||||
|
"bytesInOutput": 2454
|
||||||
|
},
|
||||||
"config.js": {
|
"config.js": {
|
||||||
"bytesInOutput": 1426
|
"bytesInOutput": 1426
|
||||||
},
|
},
|
||||||
"src/sample.js": {
|
"src/sample.ts": {
|
||||||
"bytesInOutput": 55295
|
"bytesInOutput": 55295
|
||||||
},
|
},
|
||||||
"package.json": {
|
"package.json": {
|
||||||
"bytesInOutput": 16
|
"bytesInOutput": 16
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bytes": 1349003
|
"bytes": 1343005
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"src/log.js": {
|
"src/log.ts": {
|
||||||
"bytes": 401,
|
"bytes": 401,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"dist/tfjs.esm.js": {
|
"dist/tfjs.esm.js": {
|
||||||
"bytes": 681,
|
"bytes": 690,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/tfjs/backend.js": {
|
"src/tfjs/backend.ts": {
|
||||||
"bytes": 2171,
|
"bytes": 2168,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -22,10 +22,10 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/blazeface/blazeface.js": {
|
"src/blazeface/blazeface.js": {
|
||||||
"bytes": 7024,
|
"bytes": 6983,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/blazeface/facepipeline.js": {
|
"src/blazeface/facepipeline.js": {
|
||||||
"bytes": 14275,
|
"bytes": 14028,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
|
@ -71,16 +71,16 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/blazeface/facemesh.js": {
|
"src/blazeface/facemesh.js": {
|
||||||
"bytes": 2973,
|
"bytes": 2898,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -101,20 +101,20 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/profile.js": {
|
"src/profile.ts": {
|
||||||
"bytes": 1045,
|
"bytes": 1004,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/faceboxes/faceboxes.js": {
|
"src/faceboxes/faceboxes.ts": {
|
||||||
"bytes": 2612,
|
"bytes": 2852,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -122,16 +122,16 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/age/age.js": {
|
"src/age/age.ts": {
|
||||||
"bytes": 2037,
|
"bytes": 2064,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -139,16 +139,16 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/gender/gender.js": {
|
"src/gender/gender.ts": {
|
||||||
"bytes": 2906,
|
"bytes": 2904,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -156,16 +156,16 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/emotion/emotion.js": {
|
"src/emotion/emotion.ts": {
|
||||||
"bytes": 3056,
|
"bytes": 3033,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -173,16 +173,16 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/embedding/embedding.js": {
|
"src/embedding/embedding.ts": {
|
||||||
"bytes": 2063,
|
"bytes": 1992,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -190,7 +190,7 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -244,7 +244,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/decodePose.js": {
|
"src/posenet/decodePose.js": {
|
||||||
"bytes": 5368,
|
"bytes": 5216,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/posenet/keypoints.js",
|
"path": "src/posenet/keypoints.js",
|
||||||
|
@ -261,7 +261,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/decodeMultiple.js": {
|
"src/posenet/decodeMultiple.js": {
|
||||||
"bytes": 2373,
|
"bytes": 2303,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/posenet/buildParts.js",
|
"path": "src/posenet/buildParts.js",
|
||||||
|
@ -286,11 +286,11 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/modelPoseNet.js": {
|
"src/posenet/posenet.js": {
|
||||||
"bytes": 2519,
|
"bytes": 2406,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -315,23 +315,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/posenet.js": {
|
|
||||||
"bytes": 712,
|
|
||||||
"imports": [
|
|
||||||
{
|
|
||||||
"path": "src/posenet/modelPoseNet.js",
|
|
||||||
"kind": "import-statement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/posenet/keypoints.js",
|
|
||||||
"kind": "import-statement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/posenet/util.js",
|
|
||||||
"kind": "import-statement"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"src/handpose/box.js": {
|
"src/handpose/box.js": {
|
||||||
"bytes": 2522,
|
"bytes": 2522,
|
||||||
"imports": [
|
"imports": [
|
||||||
|
@ -355,11 +338,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/handpose/util.js": {
|
"src/handpose/util.js": {
|
||||||
"bytes": 2346,
|
"bytes": 2326,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/handpose/handpipeline.js": {
|
"src/handpose/handpipeline.js": {
|
||||||
"bytes": 7246,
|
"bytes": 7243,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
|
@ -374,7 +357,7 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -384,10 +367,10 @@
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/handpose/handpose.js": {
|
"src/handpose/handpose.js": {
|
||||||
"bytes": 2578,
|
"bytes": 2536,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -408,19 +391,19 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/gesture/gesture.js": {
|
"src/gesture/gesture.ts": {
|
||||||
"bytes": 4245,
|
"bytes": 4265,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/imagefx.js": {
|
"src/imagefx.js": {
|
||||||
"bytes": 19445,
|
"bytes": 19311,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/image.js": {
|
"src/image.ts": {
|
||||||
"bytes": 5871,
|
"bytes": 5851,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -437,7 +420,7 @@
|
||||||
"bytes": 9786,
|
"bytes": 9786,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/sample.js": {
|
"src/sample.ts": {
|
||||||
"bytes": 55382,
|
"bytes": 55382,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
|
@ -445,11 +428,11 @@
|
||||||
"bytes": 2321,
|
"bytes": 2321,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/human.js": {
|
"src/human.ts": {
|
||||||
"bytes": 18962,
|
"bytes": 19233,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -457,7 +440,7 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/tfjs/backend.js",
|
"path": "src/tfjs/backend.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -465,23 +448,23 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/faceboxes/faceboxes.js",
|
"path": "src/faceboxes/faceboxes.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/age/age.js",
|
"path": "src/age/age.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/gender/gender.js",
|
"path": "src/gender/gender.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/emotion/emotion.js",
|
"path": "src/emotion/emotion.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/embedding/embedding.js",
|
"path": "src/embedding/embedding.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -493,15 +476,15 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/gesture/gesture.js",
|
"path": "src/gesture/gesture.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/image.js",
|
"path": "src/image.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -509,7 +492,7 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/sample.js",
|
"path": "src/sample.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -524,14 +507,14 @@
|
||||||
"imports": [],
|
"imports": [],
|
||||||
"exports": [],
|
"exports": [],
|
||||||
"inputs": {},
|
"inputs": {},
|
||||||
"bytes": 714830
|
"bytes": 712944
|
||||||
},
|
},
|
||||||
"dist/human.node-gpu.js": {
|
"dist/human.node-gpu.js": {
|
||||||
"imports": [],
|
"imports": [],
|
||||||
"exports": [],
|
"exports": [],
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"dist/tfjs.esm.js": {
|
"dist/tfjs.esm.js": {
|
||||||
"bytesInOutput": 545
|
"bytesInOutput": 550
|
||||||
},
|
},
|
||||||
"src/blazeface/blazeface.js": {
|
"src/blazeface/blazeface.js": {
|
||||||
"bytesInOutput": 3077
|
"bytesInOutput": 3077
|
||||||
|
@ -549,25 +532,7 @@
|
||||||
"bytesInOutput": 5593
|
"bytesInOutput": 5593
|
||||||
},
|
},
|
||||||
"src/blazeface/facemesh.js": {
|
"src/blazeface/facemesh.js": {
|
||||||
"bytesInOutput": 1556
|
"bytesInOutput": 1574
|
||||||
},
|
|
||||||
"src/profile.js": {
|
|
||||||
"bytesInOutput": 631
|
|
||||||
},
|
|
||||||
"src/faceboxes/faceboxes.js": {
|
|
||||||
"bytesInOutput": 1425
|
|
||||||
},
|
|
||||||
"src/age/age.js": {
|
|
||||||
"bytesInOutput": 852
|
|
||||||
},
|
|
||||||
"src/gender/gender.js": {
|
|
||||||
"bytesInOutput": 1348
|
|
||||||
},
|
|
||||||
"src/emotion/emotion.js": {
|
|
||||||
"bytesInOutput": 1306
|
|
||||||
},
|
|
||||||
"src/embedding/embedding.js": {
|
|
||||||
"bytesInOutput": 908
|
|
||||||
},
|
},
|
||||||
"src/posenet/modelBase.js": {
|
"src/posenet/modelBase.js": {
|
||||||
"bytesInOutput": 688
|
"bytesInOutput": 688
|
||||||
|
@ -596,11 +561,8 @@
|
||||||
"src/posenet/util.js": {
|
"src/posenet/util.js": {
|
||||||
"bytesInOutput": 1051
|
"bytesInOutput": 1051
|
||||||
},
|
},
|
||||||
"src/posenet/modelPoseNet.js": {
|
|
||||||
"bytesInOutput": 1180
|
|
||||||
},
|
|
||||||
"src/posenet/posenet.js": {
|
"src/posenet/posenet.js": {
|
||||||
"bytesInOutput": 385
|
"bytesInOutput": 1223
|
||||||
},
|
},
|
||||||
"src/handpose/handdetector.js": {
|
"src/handpose/handdetector.js": {
|
||||||
"bytesInOutput": 1844
|
"bytesInOutput": 1844
|
||||||
|
@ -612,43 +574,61 @@
|
||||||
"bytesInOutput": 127005
|
"bytesInOutput": 127005
|
||||||
},
|
},
|
||||||
"src/handpose/handpose.js": {
|
"src/handpose/handpose.js": {
|
||||||
"bytesInOutput": 1363
|
"bytesInOutput": 1397
|
||||||
},
|
},
|
||||||
"src/gesture/gesture.js": {
|
"src/human.ts": {
|
||||||
"bytesInOutput": 2423
|
"bytesInOutput": 10355
|
||||||
},
|
},
|
||||||
"src/imagefx.js": {
|
"src/log.ts": {
|
||||||
"bytesInOutput": 10999
|
|
||||||
},
|
|
||||||
"src/image.js": {
|
|
||||||
"bytesInOutput": 2478
|
|
||||||
},
|
|
||||||
"src/human.js": {
|
|
||||||
"bytesInOutput": 10681
|
|
||||||
},
|
|
||||||
"src/log.js": {
|
|
||||||
"bytesInOutput": 251
|
"bytesInOutput": 251
|
||||||
},
|
},
|
||||||
"src/tfjs/backend.js": {
|
"src/tfjs/backend.ts": {
|
||||||
"bytesInOutput": 1304
|
"bytesInOutput": 1304
|
||||||
},
|
},
|
||||||
|
"src/faceboxes/faceboxes.ts": {
|
||||||
|
"bytesInOutput": 1592
|
||||||
|
},
|
||||||
|
"src/profile.ts": {
|
||||||
|
"bytesInOutput": 604
|
||||||
|
},
|
||||||
|
"src/age/age.ts": {
|
||||||
|
"bytesInOutput": 828
|
||||||
|
},
|
||||||
|
"src/gender/gender.ts": {
|
||||||
|
"bytesInOutput": 1337
|
||||||
|
},
|
||||||
|
"src/emotion/emotion.ts": {
|
||||||
|
"bytesInOutput": 1265
|
||||||
|
},
|
||||||
|
"src/embedding/embedding.ts": {
|
||||||
|
"bytesInOutput": 851
|
||||||
|
},
|
||||||
"src/handpose/box.js": {
|
"src/handpose/box.js": {
|
||||||
"bytesInOutput": 958
|
"bytesInOutput": 958
|
||||||
},
|
},
|
||||||
"src/handpose/util.js": {
|
"src/handpose/util.js": {
|
||||||
"bytesInOutput": 812
|
"bytesInOutput": 812
|
||||||
},
|
},
|
||||||
|
"src/gesture/gesture.ts": {
|
||||||
|
"bytesInOutput": 2391
|
||||||
|
},
|
||||||
|
"src/image.ts": {
|
||||||
|
"bytesInOutput": 2434
|
||||||
|
},
|
||||||
|
"src/imagefx.js": {
|
||||||
|
"bytesInOutput": 11045
|
||||||
|
},
|
||||||
"config.js": {
|
"config.js": {
|
||||||
"bytesInOutput": 1426
|
"bytesInOutput": 1426
|
||||||
},
|
},
|
||||||
"src/sample.js": {
|
"src/sample.ts": {
|
||||||
"bytesInOutput": 55295
|
"bytesInOutput": 55295
|
||||||
},
|
},
|
||||||
"package.json": {
|
"package.json": {
|
||||||
"bytesInOutput": 16
|
"bytesInOutput": 16
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bytes": 280251
|
"bytes": 279609
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"src/log.js": {
|
"src/log.ts": {
|
||||||
"bytes": 401,
|
"bytes": 401,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"dist/tfjs.esm.js": {
|
"dist/tfjs.esm.js": {
|
||||||
"bytes": 1071833,
|
"bytes": 1071825,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/tfjs/backend.js": {
|
"src/tfjs/backend.ts": {
|
||||||
"bytes": 2171,
|
"bytes": 2168,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -21,11 +21,11 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/blazeface/blazeface.js": {
|
"src/blazeface/blazeface.ts": {
|
||||||
"bytes": 7024,
|
"bytes": 6024,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -34,8 +34,8 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/blazeface/box.js": {
|
"src/blazeface/box.ts": {
|
||||||
"bytes": 1935,
|
"bytes": 1727,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
|
@ -43,44 +43,40 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/blazeface/util.js": {
|
"src/blazeface/util.ts": {
|
||||||
"bytes": 3087,
|
"bytes": 2777,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/blazeface/coords.js": {
|
"src/blazeface/coords.ts": {
|
||||||
"bytes": 37915,
|
"bytes": 37783,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/blazeface/facepipeline.js": {
|
"src/blazeface/facepipeline.ts": {
|
||||||
"bytes": 14275,
|
"bytes": 14254,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/blazeface/box.js",
|
"path": "src/blazeface/box.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/blazeface/util.js",
|
"path": "src/blazeface/util.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/blazeface/coords.js",
|
"path": "src/blazeface/coords.ts",
|
||||||
"kind": "import-statement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/log.js",
|
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/blazeface/facemesh.js": {
|
"src/blazeface/facemesh.ts": {
|
||||||
"bytes": 2973,
|
"bytes": 2935,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -88,33 +84,33 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/blazeface/blazeface.js",
|
"path": "src/blazeface/blazeface.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/blazeface/facepipeline.js",
|
"path": "src/blazeface/facepipeline.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/blazeface/coords.js",
|
"path": "src/blazeface/coords.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/profile.js": {
|
"src/profile.ts": {
|
||||||
"bytes": 1045,
|
"bytes": 1004,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/faceboxes/faceboxes.js": {
|
"src/faceboxes/faceboxes.ts": {
|
||||||
"bytes": 2612,
|
"bytes": 2852,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -122,16 +118,16 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/age/age.js": {
|
"src/age/age.ts": {
|
||||||
"bytes": 2037,
|
"bytes": 2064,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -139,16 +135,16 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/gender/gender.js": {
|
"src/gender/gender.ts": {
|
||||||
"bytes": 2906,
|
"bytes": 2904,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -156,16 +152,16 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/emotion/emotion.js": {
|
"src/emotion/emotion.ts": {
|
||||||
"bytes": 3056,
|
"bytes": 3033,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -173,16 +169,16 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/embedding/embedding.js": {
|
"src/embedding/embedding.ts": {
|
||||||
"bytes": 2063,
|
"bytes": 1992,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -190,13 +186,13 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/modelBase.js": {
|
"src/posenet/modelBase.ts": {
|
||||||
"bytes": 1343,
|
"bytes": 1333,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
|
@ -204,93 +200,93 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/heapSort.js": {
|
"src/posenet/heapSort.ts": {
|
||||||
"bytes": 1590,
|
"bytes": 1645,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/posenet/buildParts.js": {
|
"src/posenet/buildParts.ts": {
|
||||||
"bytes": 1775,
|
"bytes": 1723,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/posenet/heapSort.js",
|
"path": "src/posenet/heapSort.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/keypoints.js": {
|
"src/posenet/keypoints.ts": {
|
||||||
"bytes": 2011,
|
"bytes": 2025,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/posenet/vectors.js": {
|
"src/posenet/vectors.ts": {
|
||||||
"bytes": 1273,
|
"bytes": 1075,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/posenet/keypoints.js",
|
"path": "src/posenet/keypoints.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/decoders.js": {
|
"src/posenet/decoders.ts": {
|
||||||
"bytes": 2083,
|
"bytes": 1943,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/keypoints.js",
|
"path": "src/posenet/keypoints.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/decodePose.js": {
|
"src/posenet/decodePose.ts": {
|
||||||
"bytes": 5368,
|
"bytes": 5152,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/posenet/keypoints.js",
|
"path": "src/posenet/keypoints.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/vectors.js",
|
"path": "src/posenet/vectors.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/decoders.js",
|
"path": "src/posenet/decoders.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/decodeMultiple.js": {
|
"src/posenet/decodeMultiple.ts": {
|
||||||
"bytes": 2373,
|
"bytes": 2259,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/posenet/buildParts.js",
|
"path": "src/posenet/buildParts.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/decodePose.js",
|
"path": "src/posenet/decodePose.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/vectors.js",
|
"path": "src/posenet/vectors.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/util.js": {
|
"src/posenet/util.ts": {
|
||||||
"bytes": 2262,
|
"bytes": 2017,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/posenet/keypoints.js",
|
"path": "src/posenet/keypoints.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/modelPoseNet.js": {
|
"src/posenet/posenet.ts": {
|
||||||
"bytes": 2519,
|
"bytes": 2376,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -298,42 +294,25 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/modelBase.js",
|
"path": "src/posenet/modelBase.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/decodeMultiple.js",
|
"path": "src/posenet/decodeMultiple.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/decodePose.js",
|
"path": "src/posenet/decodePose.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/util.js",
|
"path": "src/posenet/util.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/posenet/posenet.js": {
|
"src/handpose/box.ts": {
|
||||||
"bytes": 712,
|
"bytes": 2443,
|
||||||
"imports": [
|
|
||||||
{
|
|
||||||
"path": "src/posenet/modelPoseNet.js",
|
|
||||||
"kind": "import-statement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/posenet/keypoints.js",
|
|
||||||
"kind": "import-statement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/posenet/util.js",
|
|
||||||
"kind": "import-statement"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"src/handpose/box.js": {
|
|
||||||
"bytes": 2522,
|
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
|
@ -341,53 +320,49 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/handpose/handdetector.js": {
|
"src/handpose/handdetector.ts": {
|
||||||
"bytes": 3548,
|
"bytes": 3627,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/handpose/box.js",
|
"path": "src/handpose/box.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/handpose/util.js": {
|
"src/handpose/util.ts": {
|
||||||
"bytes": 2346,
|
"bytes": 2254,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/handpose/handpipeline.js": {
|
"src/handpose/handpipeline.ts": {
|
||||||
"bytes": 7246,
|
"bytes": 7344,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/tfjs.esm.js",
|
"path": "dist/tfjs.esm.js",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/handpose/box.js",
|
"path": "src/handpose/box.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/handpose/util.js",
|
"path": "src/handpose/util.ts",
|
||||||
"kind": "import-statement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/log.js",
|
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/handpose/anchors.js": {
|
"src/handpose/anchors.ts": {
|
||||||
"bytes": 224151,
|
"bytes": 224156,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/handpose/handpose.js": {
|
"src/handpose/handpose.ts": {
|
||||||
"bytes": 2578,
|
"bytes": 2529,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -395,32 +370,32 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/handpose/handdetector.js",
|
"path": "src/handpose/handdetector.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/handpose/handpipeline.js",
|
"path": "src/handpose/handpipeline.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/handpose/anchors.js",
|
"path": "src/handpose/anchors.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/gesture/gesture.js": {
|
"src/gesture/gesture.ts": {
|
||||||
"bytes": 4245,
|
"bytes": 4265,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/imagefx.js": {
|
"src/imagefx.js": {
|
||||||
"bytes": 19445,
|
"bytes": 19447,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/image.js": {
|
"src/image.ts": {
|
||||||
"bytes": 5871,
|
"bytes": 5851,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -437,19 +412,19 @@
|
||||||
"bytes": 9786,
|
"bytes": 9786,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/sample.js": {
|
"src/sample.ts": {
|
||||||
"bytes": 55382,
|
"bytes": 55382,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"package.json": {
|
"package.json": {
|
||||||
"bytes": 2321,
|
"bytes": 2344,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"src/human.js": {
|
"src/human.ts": {
|
||||||
"bytes": 18962,
|
"bytes": 19393,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "src/log.js",
|
"path": "src/log.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -457,51 +432,51 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/tfjs/backend.js",
|
"path": "src/tfjs/backend.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/blazeface/facemesh.js",
|
"path": "src/blazeface/facemesh.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/faceboxes/faceboxes.js",
|
"path": "src/faceboxes/faceboxes.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/age/age.js",
|
"path": "src/age/age.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/gender/gender.js",
|
"path": "src/gender/gender.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/emotion/emotion.js",
|
"path": "src/emotion/emotion.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/embedding/embedding.js",
|
"path": "src/embedding/embedding.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/posenet/posenet.js",
|
"path": "src/posenet/posenet.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/handpose/handpose.js",
|
"path": "src/handpose/handpose.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/gesture/gesture.js",
|
"path": "src/gesture/gesture.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/image.js",
|
"path": "src/image.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/profile.js",
|
"path": "src/profile.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -509,7 +484,7 @@
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/sample.js",
|
"path": "src/sample.ts",
|
||||||
"kind": "import-statement"
|
"kind": "import-statement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -520,135 +495,132 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {
|
"outputs": {
|
||||||
"dist/human.js.map": {
|
"dist/human.ts.map": {
|
||||||
"imports": [],
|
"imports": [],
|
||||||
"exports": [],
|
"exports": [],
|
||||||
"inputs": {},
|
"inputs": {},
|
||||||
"bytes": 1932088
|
"bytes": 1923057
|
||||||
},
|
},
|
||||||
"dist/human.js": {
|
"dist/human.ts": {
|
||||||
"imports": [],
|
"imports": [],
|
||||||
"exports": [],
|
"exports": [],
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"src/blazeface/blazeface.js": {
|
"src/blazeface/facemesh.ts": {
|
||||||
"bytesInOutput": 2915
|
"bytesInOutput": 1445
|
||||||
},
|
},
|
||||||
"src/blazeface/box.js": {
|
"src/posenet/keypoints.ts": {
|
||||||
"bytesInOutput": 987
|
"bytesInOutput": 1690
|
||||||
},
|
|
||||||
"src/blazeface/util.js": {
|
|
||||||
"bytesInOutput": 1197
|
|
||||||
},
|
|
||||||
"src/blazeface/coords.js": {
|
|
||||||
"bytesInOutput": 30534
|
|
||||||
},
|
|
||||||
"src/blazeface/facepipeline.js": {
|
|
||||||
"bytesInOutput": 5578
|
|
||||||
},
|
|
||||||
"src/blazeface/facemesh.js": {
|
|
||||||
"bytesInOutput": 1518
|
|
||||||
},
|
|
||||||
"src/profile.js": {
|
|
||||||
"bytesInOutput": 637
|
|
||||||
},
|
|
||||||
"src/faceboxes/faceboxes.js": {
|
|
||||||
"bytesInOutput": 1387
|
|
||||||
},
|
|
||||||
"src/age/age.js": {
|
|
||||||
"bytesInOutput": 813
|
|
||||||
},
|
|
||||||
"src/gender/gender.js": {
|
|
||||||
"bytesInOutput": 1283
|
|
||||||
},
|
|
||||||
"src/emotion/emotion.js": {
|
|
||||||
"bytesInOutput": 1247
|
|
||||||
},
|
|
||||||
"src/embedding/embedding.js": {
|
|
||||||
"bytesInOutput": 870
|
|
||||||
},
|
|
||||||
"src/posenet/modelBase.js": {
|
|
||||||
"bytesInOutput": 679
|
|
||||||
},
|
|
||||||
"src/posenet/heapSort.js": {
|
|
||||||
"bytesInOutput": 1048
|
|
||||||
},
|
|
||||||
"src/posenet/buildParts.js": {
|
|
||||||
"bytesInOutput": 529
|
|
||||||
},
|
|
||||||
"src/posenet/keypoints.js": {
|
|
||||||
"bytesInOutput": 1638
|
|
||||||
},
|
|
||||||
"src/posenet/vectors.js": {
|
|
||||||
"bytesInOutput": 627
|
|
||||||
},
|
|
||||||
"src/posenet/decoders.js": {
|
|
||||||
"bytesInOutput": 875
|
|
||||||
},
|
|
||||||
"src/posenet/decodePose.js": {
|
|
||||||
"bytesInOutput": 1482
|
|
||||||
},
|
|
||||||
"src/posenet/decodeMultiple.js": {
|
|
||||||
"bytesInOutput": 704
|
|
||||||
},
|
|
||||||
"src/posenet/util.js": {
|
|
||||||
"bytesInOutput": 1065
|
|
||||||
},
|
|
||||||
"src/posenet/modelPoseNet.js": {
|
|
||||||
"bytesInOutput": 1167
|
|
||||||
},
|
|
||||||
"src/posenet/posenet.js": {
|
|
||||||
"bytesInOutput": 401
|
|
||||||
},
|
|
||||||
"src/handpose/handdetector.js": {
|
|
||||||
"bytesInOutput": 1704
|
|
||||||
},
|
|
||||||
"src/handpose/handpipeline.js": {
|
|
||||||
"bytesInOutput": 2485
|
|
||||||
},
|
|
||||||
"src/handpose/anchors.js": {
|
|
||||||
"bytesInOutput": 127006
|
|
||||||
},
|
|
||||||
"src/handpose/handpose.js": {
|
|
||||||
"bytesInOutput": 1331
|
|
||||||
},
|
|
||||||
"src/gesture/gesture.js": {
|
|
||||||
"bytesInOutput": 2424
|
|
||||||
},
|
},
|
||||||
"src/imagefx.js": {
|
"src/imagefx.js": {
|
||||||
"bytesInOutput": 11004
|
"bytesInOutput": 11016
|
||||||
},
|
},
|
||||||
"src/image.js": {
|
"src/human.ts": {
|
||||||
"bytesInOutput": 2480
|
"bytesInOutput": 10259
|
||||||
},
|
},
|
||||||
"src/human.js": {
|
"src/log.ts": {
|
||||||
"bytesInOutput": 10573
|
|
||||||
},
|
|
||||||
"src/log.js": {
|
|
||||||
"bytesInOutput": 252
|
"bytesInOutput": 252
|
||||||
},
|
},
|
||||||
"dist/tfjs.esm.js": {
|
"dist/tfjs.esm.js": {
|
||||||
"bytesInOutput": 1062888
|
"bytesInOutput": 1062782
|
||||||
},
|
},
|
||||||
"src/tfjs/backend.js": {
|
"src/tfjs/backend.ts": {
|
||||||
"bytesInOutput": 1205
|
"bytesInOutput": 1205
|
||||||
},
|
},
|
||||||
"src/handpose/box.js": {
|
"src/blazeface/blazeface.ts": {
|
||||||
|
"bytesInOutput": 2185
|
||||||
|
},
|
||||||
|
"src/blazeface/box.ts": {
|
||||||
|
"bytesInOutput": 834
|
||||||
|
},
|
||||||
|
"src/blazeface/util.ts": {
|
||||||
|
"bytesInOutput": 858
|
||||||
|
},
|
||||||
|
"src/blazeface/coords.ts": {
|
||||||
|
"bytesInOutput": 28983
|
||||||
|
},
|
||||||
|
"src/blazeface/facepipeline.ts": {
|
||||||
|
"bytesInOutput": 5046
|
||||||
|
},
|
||||||
|
"src/faceboxes/faceboxes.ts": {
|
||||||
|
"bytesInOutput": 1549
|
||||||
|
},
|
||||||
|
"src/profile.ts": {
|
||||||
|
"bytesInOutput": 606
|
||||||
|
},
|
||||||
|
"src/age/age.ts": {
|
||||||
|
"bytesInOutput": 826
|
||||||
|
},
|
||||||
|
"src/gender/gender.ts": {
|
||||||
|
"bytesInOutput": 1309
|
||||||
|
},
|
||||||
|
"src/emotion/emotion.ts": {
|
||||||
|
"bytesInOutput": 1243
|
||||||
|
},
|
||||||
|
"src/embedding/embedding.ts": {
|
||||||
|
"bytesInOutput": 802
|
||||||
|
},
|
||||||
|
"src/posenet/posenet.ts": {
|
||||||
|
"bytesInOutput": 1007
|
||||||
|
},
|
||||||
|
"src/posenet/modelBase.ts": {
|
||||||
|
"bytesInOutput": 646
|
||||||
|
},
|
||||||
|
"src/posenet/heapSort.ts": {
|
||||||
|
"bytesInOutput": 1017
|
||||||
|
},
|
||||||
|
"src/posenet/buildParts.ts": {
|
||||||
|
"bytesInOutput": 456
|
||||||
|
},
|
||||||
|
"src/posenet/decodePose.ts": {
|
||||||
|
"bytesInOutput": 1292
|
||||||
|
},
|
||||||
|
"src/posenet/vectors.ts": {
|
||||||
|
"bytesInOutput": 346
|
||||||
|
},
|
||||||
|
"src/posenet/decoders.ts": {
|
||||||
|
"bytesInOutput": 768
|
||||||
|
},
|
||||||
|
"src/posenet/decodeMultiple.ts": {
|
||||||
|
"bytesInOutput": 557
|
||||||
|
},
|
||||||
|
"src/posenet/util.ts": {
|
||||||
|
"bytesInOutput": 354
|
||||||
|
},
|
||||||
|
"src/handpose/handpose.ts": {
|
||||||
|
"bytesInOutput": 1263
|
||||||
|
},
|
||||||
|
"src/handpose/box.ts": {
|
||||||
"bytesInOutput": 938
|
"bytesInOutput": 938
|
||||||
},
|
},
|
||||||
"src/handpose/util.js": {
|
"src/handpose/handdetector.ts": {
|
||||||
|
"bytesInOutput": 1668
|
||||||
|
},
|
||||||
|
"src/handpose/util.ts": {
|
||||||
"bytesInOutput": 816
|
"bytesInOutput": 816
|
||||||
},
|
},
|
||||||
|
"src/handpose/handpipeline.ts": {
|
||||||
|
"bytesInOutput": 2449
|
||||||
|
},
|
||||||
|
"src/handpose/anchors.ts": {
|
||||||
|
"bytesInOutput": 126985
|
||||||
|
},
|
||||||
|
"src/gesture/gesture.ts": {
|
||||||
|
"bytesInOutput": 2391
|
||||||
|
},
|
||||||
|
"src/image.ts": {
|
||||||
|
"bytesInOutput": 2454
|
||||||
|
},
|
||||||
"config.js": {
|
"config.js": {
|
||||||
"bytesInOutput": 1426
|
"bytesInOutput": 1426
|
||||||
},
|
},
|
||||||
"src/sample.js": {
|
"src/sample.ts": {
|
||||||
"bytesInOutput": 55295
|
"bytesInOutput": 55295
|
||||||
},
|
},
|
||||||
"package.json": {
|
"package.json": {
|
||||||
"bytesInOutput": 16
|
"bytesInOutput": 16
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bytes": 1349045
|
"bytes": 1343047
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -25407,7 +25407,7 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/tfjs/tf-browser.js": {
|
"src/tfjs/tf-browser.ts": {
|
||||||
"bytes": 1784,
|
"bytes": 1784,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
|
@ -28613,7 +28613,7 @@
|
||||||
"node_modules/@tensorflow/tfjs-backend-wasm/dist/index.js": {
|
"node_modules/@tensorflow/tfjs-backend-wasm/dist/index.js": {
|
||||||
"bytesInOutput": 0
|
"bytesInOutput": 0
|
||||||
},
|
},
|
||||||
"src/tfjs/tf-browser.js": {
|
"src/tfjs/tf-browser.ts": {
|
||||||
"bytesInOutput": 154
|
"bytesInOutput": 154
|
||||||
},
|
},
|
||||||
"node_modules/@tensorflow/tfjs-core/dist/public/chained_ops/abs.js": {
|
"node_modules/@tensorflow/tfjs-core/dist/public/chained_ops/abs.js": {
|
||||||
|
@ -29739,7 +29739,7 @@
|
||||||
"bytesInOutput": 15
|
"bytesInOutput": 15
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bytes": 1071833
|
"bytes": 1071825
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -821,9 +821,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"esbuild": {
|
"esbuild": {
|
||||||
"version": "0.8.42",
|
"version": "0.8.43",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.8.42.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.8.43.tgz",
|
||||||
"integrity": "sha512-zUtj5RMqROCCCH0vV/a7cd8YQg8I0GWBhV3A3PklWRT+oM/YwVbnrtFnITzE1otGdnXplWHWdZ4OcYiV0PN+JQ==",
|
"integrity": "sha512-ZVE2CpootS4jtnfV0bbtJdgRsHEXcMP0P7ZXGfTmNzzhBr2e5ag7Vp3ry0jmw8zduJz4iHzxg4m5jtPxWERz1w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"escalade": {
|
"escalade": {
|
||||||
|
@ -2285,9 +2285,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"simple-git": {
|
"simple-git": {
|
||||||
"version": "2.32.0",
|
"version": "2.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.34.2.tgz",
|
||||||
"integrity": "sha512-swz7avV2JADYgTmvs+j/eDBt+gPx3SAyh2MxlDVvxqHzHLkKr6kLr4N62qZCv5LBxc9Wx8TIXVeJKmTTY8UdSQ==",
|
"integrity": "sha512-/EX4FtcpAj5L/Bs5zgaBGYDrnkrKflFVNppNLH9VXpIjZBLHx5cZ6/mOYJCoKXKlLRuk3iTvzrIsHo7v42zWHg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@kwsites/file-exists": "^1.1.1",
|
"@kwsites/file-exists": "^1.1.1",
|
||||||
|
@ -2505,6 +2505,12 @@
|
||||||
"strip-bom": "^3.0.0"
|
"strip-bom": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"tslib": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"type-check": {
|
"type-check": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||||
|
@ -2520,6 +2526,12 @@
|
||||||
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
|
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"typescript": {
|
||||||
|
"version": "4.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz",
|
||||||
|
"integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"uri-js": {
|
"uri-js": {
|
||||||
"version": "4.4.1",
|
"version": "4.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
"@vladmandic/pilogger": "^0.2.14",
|
"@vladmandic/pilogger": "^0.2.14",
|
||||||
"chokidar": "^3.5.1",
|
"chokidar": "^3.5.1",
|
||||||
"dayjs": "^1.10.4",
|
"dayjs": "^1.10.4",
|
||||||
"esbuild": "^0.8.42",
|
"esbuild": "^0.8.43",
|
||||||
"eslint": "^7.19.0",
|
"eslint": "^7.19.0",
|
||||||
"eslint-config-airbnb-base": "^14.2.1",
|
"eslint-config-airbnb-base": "^14.2.1",
|
||||||
"eslint-plugin-import": "^2.22.1",
|
"eslint-plugin-import": "^2.22.1",
|
||||||
|
@ -44,7 +44,9 @@
|
||||||
"eslint-plugin-promise": "^4.2.1",
|
"eslint-plugin-promise": "^4.2.1",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"seedrandom": "^3.0.5",
|
"seedrandom": "^3.0.5",
|
||||||
"simple-git": "^2.32.0"
|
"simple-git": "^2.34.2",
|
||||||
|
"tslib": "^2.1.0",
|
||||||
|
"typescript": "^4.1.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation src/node.js",
|
"start": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation src/node.js",
|
||||||
|
|
|
@ -6,6 +6,7 @@ const log = require('@vladmandic/pilogger');
|
||||||
|
|
||||||
// keeps esbuild service instance cached
|
// keeps esbuild service instance cached
|
||||||
let es;
|
let es;
|
||||||
|
let busy = false;
|
||||||
const banner = `
|
const banner = `
|
||||||
/*
|
/*
|
||||||
Human library
|
Human library
|
||||||
|
@ -33,7 +34,7 @@ const targets = {
|
||||||
platform: 'node',
|
platform: 'node',
|
||||||
format: 'cjs',
|
format: 'cjs',
|
||||||
metafile: 'dist/tfjs.esm.json',
|
metafile: 'dist/tfjs.esm.json',
|
||||||
entryPoints: ['src/tfjs/tf-node.js'],
|
entryPoints: ['src/tfjs/tf-node.ts'],
|
||||||
outfile: 'dist/tfjs.esm.js',
|
outfile: 'dist/tfjs.esm.js',
|
||||||
external: ['@tensorflow'],
|
external: ['@tensorflow'],
|
||||||
},
|
},
|
||||||
|
@ -41,7 +42,7 @@ const targets = {
|
||||||
platform: 'node',
|
platform: 'node',
|
||||||
format: 'cjs',
|
format: 'cjs',
|
||||||
metafile: 'dist/human.node.json',
|
metafile: 'dist/human.node.json',
|
||||||
entryPoints: ['src/human.js'],
|
entryPoints: ['src/human.ts'],
|
||||||
outfile: 'dist/human.node.js',
|
outfile: 'dist/human.node.js',
|
||||||
external: ['@tensorflow'],
|
external: ['@tensorflow'],
|
||||||
},
|
},
|
||||||
|
@ -51,7 +52,7 @@ const targets = {
|
||||||
platform: 'node',
|
platform: 'node',
|
||||||
format: 'cjs',
|
format: 'cjs',
|
||||||
metafile: 'dist/tfjs.esm.json',
|
metafile: 'dist/tfjs.esm.json',
|
||||||
entryPoints: ['src/tfjs/tf-node-gpu.js'],
|
entryPoints: ['src/tfjs/tf-node-gpu.ts'],
|
||||||
outfile: 'dist/tfjs.esm.js',
|
outfile: 'dist/tfjs.esm.js',
|
||||||
external: ['@tensorflow'],
|
external: ['@tensorflow'],
|
||||||
},
|
},
|
||||||
|
@ -59,7 +60,7 @@ const targets = {
|
||||||
platform: 'node',
|
platform: 'node',
|
||||||
format: 'cjs',
|
format: 'cjs',
|
||||||
metafile: 'dist/human.node.json',
|
metafile: 'dist/human.node.json',
|
||||||
entryPoints: ['src/human.js'],
|
entryPoints: ['src/human.ts'],
|
||||||
outfile: 'dist/human.node-gpu.js',
|
outfile: 'dist/human.node-gpu.js',
|
||||||
external: ['@tensorflow'],
|
external: ['@tensorflow'],
|
||||||
},
|
},
|
||||||
|
@ -69,7 +70,7 @@ const targets = {
|
||||||
platform: 'browser',
|
platform: 'browser',
|
||||||
format: 'esm',
|
format: 'esm',
|
||||||
metafile: 'dist/tfjs.esm.json',
|
metafile: 'dist/tfjs.esm.json',
|
||||||
entryPoints: ['src/tfjs/tf-browser.js'],
|
entryPoints: ['src/tfjs/tf-browser.ts'],
|
||||||
outfile: 'dist/tfjs.esm.js',
|
outfile: 'dist/tfjs.esm.js',
|
||||||
external: ['fs', 'buffer', 'util', '@tensorflow'],
|
external: ['fs', 'buffer', 'util', '@tensorflow'],
|
||||||
},
|
},
|
||||||
|
@ -77,7 +78,7 @@ const targets = {
|
||||||
platform: 'browser',
|
platform: 'browser',
|
||||||
format: 'esm',
|
format: 'esm',
|
||||||
metafile: 'dist/human.esm.json',
|
metafile: 'dist/human.esm.json',
|
||||||
entryPoints: ['src/human.js'],
|
entryPoints: ['src/human.ts'],
|
||||||
outfile: 'dist/human.esm-nobundle.js',
|
outfile: 'dist/human.esm-nobundle.js',
|
||||||
external: ['fs', 'buffer', 'util', '@tensorflow'],
|
external: ['fs', 'buffer', 'util', '@tensorflow'],
|
||||||
},
|
},
|
||||||
|
@ -87,7 +88,7 @@ const targets = {
|
||||||
platform: 'browser',
|
platform: 'browser',
|
||||||
format: 'esm',
|
format: 'esm',
|
||||||
metafile: 'dist/tfjs.esm.json',
|
metafile: 'dist/tfjs.esm.json',
|
||||||
entryPoints: ['src/tfjs/tf-browser.js'],
|
entryPoints: ['src/tfjs/tf-browser.ts'],
|
||||||
outfile: 'dist/tfjs.esm.js',
|
outfile: 'dist/tfjs.esm.js',
|
||||||
external: ['fs', 'buffer', 'util'],
|
external: ['fs', 'buffer', 'util'],
|
||||||
},
|
},
|
||||||
|
@ -95,16 +96,16 @@ const targets = {
|
||||||
platform: 'browser',
|
platform: 'browser',
|
||||||
format: 'iife',
|
format: 'iife',
|
||||||
globalName: 'Human',
|
globalName: 'Human',
|
||||||
metafile: 'dist/human.json',
|
metafile: 'dist/human.tson',
|
||||||
entryPoints: ['src/human.js'],
|
entryPoints: ['src/human.ts'],
|
||||||
outfile: 'dist/human.js',
|
outfile: 'dist/human.ts',
|
||||||
external: ['fs', 'buffer', 'util'],
|
external: ['fs', 'buffer', 'util'],
|
||||||
},
|
},
|
||||||
esm: {
|
esm: {
|
||||||
platform: 'browser',
|
platform: 'browser',
|
||||||
format: 'esm',
|
format: 'esm',
|
||||||
metafile: 'dist/human.esm.json',
|
metafile: 'dist/human.esm.json',
|
||||||
entryPoints: ['src/human.js'],
|
entryPoints: ['src/human.ts'],
|
||||||
outfile: 'dist/human.esm.js',
|
outfile: 'dist/human.esm.js',
|
||||||
external: ['fs', 'buffer', 'util'],
|
external: ['fs', 'buffer', 'util'],
|
||||||
},
|
},
|
||||||
|
@ -148,6 +149,12 @@ async function getStats(metafile) {
|
||||||
|
|
||||||
// rebuild on file change
|
// rebuild on file change
|
||||||
async function build(f, msg) {
|
async function build(f, msg) {
|
||||||
|
if (busy) {
|
||||||
|
log.state('Build: busy...');
|
||||||
|
setTimeout(() => build(f, msg), 500);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
busy = true;
|
||||||
log.info('Build: file', msg, f, 'target:', common.target);
|
log.info('Build: file', msg, f, 'target:', common.target);
|
||||||
if (!es) es = await esbuild.startService();
|
if (!es) es = await esbuild.startService();
|
||||||
// common build options
|
// common build options
|
||||||
|
@ -168,6 +175,7 @@ async function build(f, msg) {
|
||||||
log.error('Build error', JSON.stringify(err.errors || err, null, 2));
|
log.error('Build error', JSON.stringify(err.errors || err, null, 2));
|
||||||
if (require.main === module) process.exit(1);
|
if (require.main === module) process.exit(1);
|
||||||
}
|
}
|
||||||
|
busy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
|
|
|
@ -21,9 +21,9 @@ Repository: **<${app.repository.url}>**
|
||||||
`;
|
`;
|
||||||
|
|
||||||
async function update(f) {
|
async function update(f) {
|
||||||
const all = await git.log();
|
const gitLog = await git.log();
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const log = all.all.sort((a, b) => (new Date(b.date).getTime() - new Date(a.date).getTime()));
|
const log = gitLog.all.sort((a, b) => (new Date(b.date).getTime() - new Date(a.date).getTime()));
|
||||||
|
|
||||||
let previous = '';
|
let previous = '';
|
||||||
for (const l of log) {
|
for (const l of log) {
|
||||||
|
|
|
@ -52,6 +52,14 @@ const mime = {
|
||||||
'.wasm': 'application/wasm',
|
'.wasm': 'application/wasm',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let last = Date.now();
|
||||||
|
async function buildAll(evt, msg) {
|
||||||
|
const now = Date.now();
|
||||||
|
if ((now - last) > 2) build.build(evt, msg);
|
||||||
|
else log.state('Build: merge event file', msg, evt);
|
||||||
|
last = now;
|
||||||
|
}
|
||||||
|
|
||||||
// watch filesystem for any changes and notify build when needed
|
// watch filesystem for any changes and notify build when needed
|
||||||
async function watch() {
|
async function watch() {
|
||||||
const watcher = chokidar.watch(options.monitor, {
|
const watcher = chokidar.watch(options.monitor, {
|
||||||
|
@ -66,9 +74,9 @@ async function watch() {
|
||||||
});
|
});
|
||||||
// single event handler for file add/change/delete
|
// single event handler for file add/change/delete
|
||||||
watcher
|
watcher
|
||||||
.on('add', (evt) => build.build(evt, 'add'))
|
.on('add', (evt) => buildAll(evt, 'add'))
|
||||||
.on('change', (evt) => build.build(evt, 'modify'))
|
.on('change', (evt) => buildAll(evt, 'modify'))
|
||||||
.on('unlink', (evt) => build.build(evt, 'remove'))
|
.on('unlink', (evt) => buildAll(evt, 'remove'))
|
||||||
.on('error', (err) => log.error(`Client watcher error: ${err}`))
|
.on('error', (err) => log.error(`Client watcher error: ${err}`))
|
||||||
.on('ready', () => log.state('Monitoring:', options.monitor));
|
.on('ready', () => log.state('Monitoring:', options.monitor));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { log } from '../log.js';
|
import { log } from '../log';
|
||||||
import * as tf from '../../dist/tfjs.esm.js';
|
import * as tf from '../../dist/tfjs.esm.js';
|
||||||
import * as profile from '../profile.js';
|
import * as profile from '../profile.js';
|
||||||
|
|
||||||
const models = {};
|
const models = { age: null };
|
||||||
let last = { age: 0 };
|
let last = { age: 0 };
|
||||||
let skipped = Number.MAX_SAFE_INTEGER;
|
let skipped = Number.MAX_SAFE_INTEGER;
|
||||||
|
|
||||||
async function load(config) {
|
export async function load(config) {
|
||||||
if (!models.age) {
|
if (!models.age) {
|
||||||
models.age = await tf.loadGraphModel(config.face.age.modelPath);
|
models.age = await tf.loadGraphModel(config.face.age.modelPath);
|
||||||
log(`load model: ${config.face.age.modelPath.match(/\/(.*)\./)[1]}`);
|
log(`load model: ${config.face.age.modelPath.match(/\/(.*)\./)[1]}`);
|
||||||
|
@ -14,7 +14,7 @@ async function load(config) {
|
||||||
return models.age;
|
return models.age;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function predict(image, config) {
|
export async function predict(image, config) {
|
||||||
if (!models.age) return null;
|
if (!models.age) return null;
|
||||||
if ((skipped < config.face.age.skipFrames) && config.videoOptimized && last.age && (last.age > 0)) {
|
if ((skipped < config.face.age.skipFrames) && config.videoOptimized && last.age && (last.age > 0)) {
|
||||||
skipped++;
|
skipped++;
|
||||||
|
@ -38,15 +38,15 @@ async function predict(image, config) {
|
||||||
tf.dispose(resize);
|
tf.dispose(resize);
|
||||||
|
|
||||||
let ageT;
|
let ageT;
|
||||||
const obj = {};
|
const obj = { age: undefined };
|
||||||
|
|
||||||
|
if (models.age) {
|
||||||
if (!config.profile) {
|
if (!config.profile) {
|
||||||
if (config.face.age.enabled) ageT = await models.age.predict(enhance);
|
if (config.face.age.enabled) ageT = await models.age.predict(enhance);
|
||||||
} else {
|
} else {
|
||||||
const profileAge = config.face.age.enabled ? await tf.profile(() => models.age.predict(enhance)) : {};
|
const profileAge = config.face.age.enabled ? await tf.profile(() => models.age.predict(enhance)) : {};
|
||||||
ageT = profileAge.result.clone();
|
ageT = profileAge.result.clone();
|
||||||
profileAge.result.dispose();
|
profileAge.result.dispose();
|
||||||
// @ts-ignore
|
|
||||||
profile.run('age', profileAge);
|
profile.run('age', profileAge);
|
||||||
}
|
}
|
||||||
enhance.dispose();
|
enhance.dispose();
|
||||||
|
@ -58,9 +58,7 @@ async function predict(image, config) {
|
||||||
ageT.dispose();
|
ageT.dispose();
|
||||||
|
|
||||||
last = obj;
|
last = obj;
|
||||||
|
}
|
||||||
resolve(obj);
|
resolve(obj);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.predict = predict;
|
|
||||||
exports.load = load;
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { log } from '../log.js';
|
import { log } from '../log';
|
||||||
import * as tf from '../../dist/tfjs.esm.js';
|
import * as tf from '../../dist/tfjs.esm.js';
|
||||||
|
|
||||||
const NUM_LANDMARKS = 6;
|
const NUM_LANDMARKS = 6;
|
||||||
|
@ -24,7 +24,7 @@ function generateAnchors(inputSize) {
|
||||||
return anchors;
|
return anchors;
|
||||||
}
|
}
|
||||||
|
|
||||||
const disposeBox = (box) => {
|
export const disposeBox = (box) => {
|
||||||
box.startEndTensor.dispose();
|
box.startEndTensor.dispose();
|
||||||
box.startPoint.dispose();
|
box.startPoint.dispose();
|
||||||
box.endPoint.dispose();
|
box.endPoint.dispose();
|
||||||
|
@ -65,7 +65,16 @@ function scaleBoxFromPrediction(face, scaleFactor) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class BlazeFaceModel {
|
export class BlazeFaceModel {
|
||||||
|
blazeFaceModel: any;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
anchorsData: any;
|
||||||
|
anchors: any;
|
||||||
|
inputSize: number;
|
||||||
|
config: any;
|
||||||
|
scaleFaces: number;
|
||||||
|
|
||||||
constructor(model, config) {
|
constructor(model, config) {
|
||||||
this.blazeFaceModel = model;
|
this.blazeFaceModel = model;
|
||||||
this.width = config.face.detector.inputSize;
|
this.width = config.face.detector.inputSize;
|
||||||
|
@ -132,47 +141,11 @@ class BlazeFaceModel {
|
||||||
scaleFactor: [inputImage.shape[2] / this.width, inputImage.shape[1] / this.height],
|
scaleFactor: [inputImage.shape[2] / this.width, inputImage.shape[1] / this.height],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async estimateFaces(input) {
|
|
||||||
// @ts-ignore
|
|
||||||
const { boxes, scaleFactor } = await this.getBoundingBoxes(input);
|
|
||||||
const faces = [];
|
|
||||||
for (const face of boxes) {
|
|
||||||
const landmarkData = face.landmarks.arraySync();
|
|
||||||
const scaledBox = scaleBoxFromPrediction(face, scaleFactor);
|
|
||||||
// @ts-ignore
|
|
||||||
const boxData = scaleBox.arraySync();
|
|
||||||
const probabilityData = face.probability.arraySync();
|
|
||||||
const anchor = face.anchor;
|
|
||||||
const [scaleFactorX, scaleFactorY] = scaleFactor;
|
|
||||||
const scaledLandmarks = landmarkData
|
|
||||||
.map((landmark) => ([
|
|
||||||
(landmark[0] + anchor[0]) * scaleFactorX,
|
|
||||||
(landmark[1] + anchor[1]) * scaleFactorY,
|
|
||||||
]));
|
|
||||||
const normalizedFace = {
|
|
||||||
topLeft: boxData.slice(0, 2),
|
|
||||||
bottomRight: boxData.slice(2),
|
|
||||||
landmarks: scaledLandmarks,
|
|
||||||
probability: probabilityData,
|
|
||||||
};
|
|
||||||
disposeBox(face.box);
|
|
||||||
face.landmarks.dispose();
|
|
||||||
face.probability.dispose();
|
|
||||||
scaledBox.dispose();
|
|
||||||
faces.push(normalizedFace);
|
|
||||||
}
|
|
||||||
return faces;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function load(config) {
|
export async function load(config) {
|
||||||
const blazeface = await tf.loadGraphModel(config.face.detector.modelPath, { fromTFHub: config.face.detector.modelPath.includes('tfhub.dev') });
|
const blazeface = await tf.loadGraphModel(config.face.detector.modelPath, { fromTFHub: config.face.detector.modelPath.includes('tfhub.dev') });
|
||||||
const model = new BlazeFaceModel(blazeface, config);
|
const model = new BlazeFaceModel(blazeface, config);
|
||||||
log(`load model: ${config.face.detector.modelPath.match(/\/(.*)\./)[1]}`);
|
log(`load model: ${config.face.detector.modelPath.match(/\/(.*)\./)[1]}`);
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.load = load;
|
|
||||||
exports.BlazeFaceModel = BlazeFaceModel;
|
|
||||||
exports.disposeBox = disposeBox;
|
|
|
@ -1,29 +1,26 @@
|
||||||
import * as tf from '../../dist/tfjs.esm.js';
|
import * as tf from '../../dist/tfjs.esm.js';
|
||||||
|
|
||||||
function scaleBoxCoordinates(box, factor) {
|
export function scaleBoxCoordinates(box, factor) {
|
||||||
const startPoint = [box.startPoint[0] * factor[0], box.startPoint[1] * factor[1]];
|
const startPoint = [box.startPoint[0] * factor[0], box.startPoint[1] * factor[1]];
|
||||||
const endPoint = [box.endPoint[0] * factor[0], box.endPoint[1] * factor[1]];
|
const endPoint = [box.endPoint[0] * factor[0], box.endPoint[1] * factor[1]];
|
||||||
return { startPoint, endPoint };
|
return { startPoint, endPoint };
|
||||||
}
|
}
|
||||||
exports.scaleBoxCoordinates = scaleBoxCoordinates;
|
|
||||||
|
|
||||||
function getBoxSize(box) {
|
export function getBoxSize(box) {
|
||||||
return [
|
return [
|
||||||
Math.abs(box.endPoint[0] - box.startPoint[0]),
|
Math.abs(box.endPoint[0] - box.startPoint[0]),
|
||||||
Math.abs(box.endPoint[1] - box.startPoint[1]),
|
Math.abs(box.endPoint[1] - box.startPoint[1]),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
exports.getBoxSize = getBoxSize;
|
|
||||||
|
|
||||||
function getBoxCenter(box) {
|
export function getBoxCenter(box) {
|
||||||
return [
|
return [
|
||||||
box.startPoint[0] + (box.endPoint[0] - box.startPoint[0]) / 2,
|
box.startPoint[0] + (box.endPoint[0] - box.startPoint[0]) / 2,
|
||||||
box.startPoint[1] + (box.endPoint[1] - box.startPoint[1]) / 2,
|
box.startPoint[1] + (box.endPoint[1] - box.startPoint[1]) / 2,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
exports.getBoxCenter = getBoxCenter;
|
|
||||||
|
|
||||||
function cutBoxFromImageAndResize(box, image, cropSize) {
|
export function cutBoxFromImageAndResize(box, image, cropSize) {
|
||||||
const h = image.shape[1];
|
const h = image.shape[1];
|
||||||
const w = image.shape[2];
|
const w = image.shape[2];
|
||||||
const boxes = [[
|
const boxes = [[
|
||||||
|
@ -32,9 +29,8 @@ function cutBoxFromImageAndResize(box, image, cropSize) {
|
||||||
]];
|
]];
|
||||||
return tf.image.cropAndResize(image, boxes, [0], cropSize);
|
return tf.image.cropAndResize(image, boxes, [0], cropSize);
|
||||||
}
|
}
|
||||||
exports.cutBoxFromImageAndResize = cutBoxFromImageAndResize;
|
|
||||||
|
|
||||||
function enlargeBox(box, factor = 1.5) {
|
export function enlargeBox(box, factor = 1.5) {
|
||||||
const center = getBoxCenter(box);
|
const center = getBoxCenter(box);
|
||||||
const size = getBoxSize(box);
|
const size = getBoxSize(box);
|
||||||
const newHalfSize = [factor * size[0] / 2, factor * size[1] / 2];
|
const newHalfSize = [factor * size[0] / 2, factor * size[1] / 2];
|
||||||
|
@ -42,9 +38,8 @@ function enlargeBox(box, factor = 1.5) {
|
||||||
const endPoint = [center[0] + newHalfSize[0], center[1] + newHalfSize[1]];
|
const endPoint = [center[0] + newHalfSize[0], center[1] + newHalfSize[1]];
|
||||||
return { startPoint, endPoint, landmarks: box.landmarks };
|
return { startPoint, endPoint, landmarks: box.landmarks };
|
||||||
}
|
}
|
||||||
exports.enlargeBox = enlargeBox;
|
|
||||||
|
|
||||||
function squarifyBox(box) {
|
export function squarifyBox(box) {
|
||||||
const centers = getBoxCenter(box);
|
const centers = getBoxCenter(box);
|
||||||
const size = getBoxSize(box);
|
const size = getBoxSize(box);
|
||||||
const maxEdge = Math.max(...size);
|
const maxEdge = Math.max(...size);
|
||||||
|
@ -53,4 +48,3 @@ function squarifyBox(box) {
|
||||||
const endPoint = [centers[0] + halfSize, centers[1] + halfSize];
|
const endPoint = [centers[0] + halfSize, centers[1] + halfSize];
|
||||||
return { startPoint, endPoint, landmarks: box.landmarks };
|
return { startPoint, endPoint, landmarks: box.landmarks };
|
||||||
}
|
}
|
||||||
exports.squarifyBox = squarifyBox;
|
|
|
@ -1,4 +1,4 @@
|
||||||
const MESH_ANNOTATIONS = {
|
export const MESH_ANNOTATIONS = {
|
||||||
silhouette: [
|
silhouette: [
|
||||||
10, 338, 297, 332, 284, 251, 389, 356, 454, 323, 361, 288,
|
10, 338, 297, 332, 284, 251, 389, 356, 454, 323, 361, 288,
|
||||||
397, 365, 379, 378, 400, 377, 152, 148, 176, 149, 150, 136,
|
397, 365, 379, 378, 400, 377, 152, 148, 176, 149, 150, 136,
|
||||||
|
@ -37,7 +37,7 @@ const MESH_ANNOTATIONS = {
|
||||||
leftCheek: [425],
|
leftCheek: [425],
|
||||||
};
|
};
|
||||||
|
|
||||||
const MESH_TO_IRIS_INDICES_MAP = [ // A mapping from facemesh model keypoints to iris model keypoints.
|
export const MESH_TO_IRIS_INDICES_MAP = [ // A mapping from facemesh model keypoints to iris model keypoints.
|
||||||
{ key: 'EyeUpper0', indices: [9, 10, 11, 12, 13, 14, 15] },
|
{ key: 'EyeUpper0', indices: [9, 10, 11, 12, 13, 14, 15] },
|
||||||
{ key: 'EyeUpper1', indices: [25, 26, 27, 28, 29, 30, 31] },
|
{ key: 'EyeUpper1', indices: [25, 26, 27, 28, 29, 30, 31] },
|
||||||
{ key: 'EyeUpper2', indices: [41, 42, 43, 44, 45, 46, 47] },
|
{ key: 'EyeUpper2', indices: [41, 42, 43, 44, 45, 46, 47] },
|
||||||
|
@ -49,7 +49,7 @@ const MESH_TO_IRIS_INDICES_MAP = [ // A mapping from facemesh model keypoints to
|
||||||
// { key: 'EyebrowLower', indices: [48, 49, 50, 51, 52, 53] },
|
// { key: 'EyebrowLower', indices: [48, 49, 50, 51, 52, 53] },
|
||||||
];
|
];
|
||||||
|
|
||||||
const UV468 = [
|
export const UV468 = [
|
||||||
[0.499976992607117, 0.652534008026123],
|
[0.499976992607117, 0.652534008026123],
|
||||||
[0.500025987625122, 0.547487020492554],
|
[0.500025987625122, 0.547487020492554],
|
||||||
[0.499974012374878, 0.602371990680695],
|
[0.499974012374878, 0.602371990680695],
|
||||||
|
@ -520,7 +520,7 @@ const UV468 = [
|
||||||
[0.723330020904541, 0.363372981548309],
|
[0.723330020904541, 0.363372981548309],
|
||||||
];
|
];
|
||||||
|
|
||||||
const TRI468 = [
|
export const TRI468 = [
|
||||||
127, 34, 139, 11, 0, 37, 232, 231, 120, 72, 37, 39, 128, 121, 47, 232, 121, 128, 104, 69, 67, 175, 171, 148, 157, 154, 155, 118, 50, 101, 73, 39, 40, 9,
|
127, 34, 139, 11, 0, 37, 232, 231, 120, 72, 37, 39, 128, 121, 47, 232, 121, 128, 104, 69, 67, 175, 171, 148, 157, 154, 155, 118, 50, 101, 73, 39, 40, 9,
|
||||||
151, 108, 48, 115, 131, 194, 204, 211, 74, 40, 185, 80, 42, 183, 40, 92, 186, 230, 229, 118, 202, 212, 214, 83, 18, 17, 76, 61, 146, 160, 29, 30, 56,
|
151, 108, 48, 115, 131, 194, 204, 211, 74, 40, 185, 80, 42, 183, 40, 92, 186, 230, 229, 118, 202, 212, 214, 83, 18, 17, 76, 61, 146, 160, 29, 30, 56,
|
||||||
157, 173, 106, 204, 194, 135, 214, 192, 203, 165, 98, 21, 71, 68, 51, 45, 4, 144, 24, 23, 77, 146, 91, 205, 50, 187, 201, 200, 18, 91, 106, 182, 90, 91,
|
157, 173, 106, 204, 194, 135, 214, 192, 203, 165, 98, 21, 71, 68, 51, 45, 4, 144, 24, 23, 77, 146, 91, 205, 50, 187, 201, 200, 18, 91, 106, 182, 90, 91,
|
||||||
|
@ -606,7 +606,7 @@ const TRI468 = [
|
||||||
259, 443, 259, 260, 444, 260, 467, 445, 309, 459, 250, 305, 289, 290, 305, 290, 460, 401, 376, 435, 309, 250, 392, 376, 411, 433, 453, 341, 464, 357,
|
259, 443, 259, 260, 444, 260, 467, 445, 309, 459, 250, 305, 289, 290, 305, 290, 460, 401, 376, 435, 309, 250, 392, 376, 411, 433, 453, 341, 464, 357,
|
||||||
453, 465, 343, 357, 412, 437, 343, 399, 344, 360, 440, 420, 437, 456, 360, 420, 363, 361, 401, 288, 265, 372, 353, 390, 339, 249, 339, 448, 255];
|
453, 465, 343, 357, 412, 437, 343, 399, 344, 360, 440, 420, 437, 456, 360, 420, 363, 361, 401, 288, 265, 372, 353, 390, 339, 249, 339, 448, 255];
|
||||||
|
|
||||||
const TRI68 = [0, 1, 36, 0, 36, 17, 1, 2, 41, 1, 41, 36, 2, 3, 31, 2, 31, 41, 3, 4, 48, 3, 48, 31, 4, 5, 48, 5, 6, 48, 6, 7, 59, 6, 59, 48, 7, 8, 58, 7, 58, 59,
|
export const TRI68 = [0, 1, 36, 0, 36, 17, 1, 2, 41, 1, 41, 36, 2, 3, 31, 2, 31, 41, 3, 4, 48, 3, 48, 31, 4, 5, 48, 5, 6, 48, 6, 7, 59, 6, 59, 48, 7, 8, 58, 7, 58, 59,
|
||||||
8, 9, 56, 8, 56, 57, 8, 57, 58, 9, 10, 55, 9, 55, 56, 10, 11, 54, 10, 54, 55, 11, 12, 54, 12, 13, 54, 13, 14, 35, 13, 35, 54, 14, 15, 46, 14, 46, 35, 15, 16,
|
8, 9, 56, 8, 56, 57, 8, 57, 58, 9, 10, 55, 9, 55, 56, 10, 11, 54, 10, 54, 55, 11, 12, 54, 12, 13, 54, 13, 14, 35, 13, 35, 54, 14, 15, 46, 14, 46, 35, 15, 16,
|
||||||
45, 15, 45, 46, 16, 26, 45, 17, 36, 18, 18, 37, 19, 18, 36, 37, 19, 38, 20, 19, 37, 38, 20, 39, 21, 20, 38, 39, 21, 39, 27, 22, 42, 23, 22, 27, 42, 23, 43, 24,
|
45, 15, 45, 46, 16, 26, 45, 17, 36, 18, 18, 37, 19, 18, 36, 37, 19, 38, 20, 19, 37, 38, 20, 39, 21, 20, 38, 39, 21, 39, 27, 22, 42, 23, 22, 27, 42, 23, 43, 24,
|
||||||
23, 42, 43, 24, 44, 25, 24, 43, 44, 25, 45, 26, 25, 44, 45, 27, 39, 28, 27, 28, 42, 28, 39, 29, 28, 29, 42, 29, 31, 30, 29, 30, 35, 29, 40, 31, 29, 35, 47, 29,
|
23, 42, 43, 24, 44, 25, 24, 43, 44, 25, 45, 26, 25, 44, 45, 27, 39, 28, 27, 28, 42, 28, 39, 29, 28, 29, 42, 29, 31, 30, 29, 30, 35, 29, 40, 31, 29, 35, 47, 29,
|
||||||
|
@ -614,7 +614,8 @@ const TRI68 = [0, 1, 36, 0, 36, 17, 1, 2, 41, 1, 41, 36, 2, 3, 31, 2, 31, 41, 3,
|
||||||
35, 34, 51, 52, 35, 46, 47, 35, 52, 53, 35, 53, 54, 36, 41, 37, 37, 40, 38, 37, 41, 40, 38, 40, 39, 42, 47, 43, 43, 47, 44, 44, 46, 45, 44, 47, 46, 48, 60, 49,
|
35, 34, 51, 52, 35, 46, 47, 35, 52, 53, 35, 53, 54, 36, 41, 37, 37, 40, 38, 37, 41, 40, 38, 40, 39, 42, 47, 43, 43, 47, 44, 44, 46, 45, 44, 47, 46, 48, 60, 49,
|
||||||
48, 59, 60, 49, 61, 50, 49, 60, 61, 50, 62, 51, 50, 61, 62, 51, 62, 52, 52, 63, 53, 52, 62, 63, 53, 64, 54, 53, 63, 64, 54, 64, 55, 55, 65, 56, 55, 64, 65, 56,
|
48, 59, 60, 49, 61, 50, 49, 60, 61, 50, 62, 51, 50, 61, 62, 51, 62, 52, 52, 63, 53, 52, 62, 63, 53, 64, 54, 53, 63, 64, 54, 64, 55, 55, 65, 56, 55, 64, 65, 56,
|
||||||
66, 57, 56, 65, 66, 57, 66, 58, 58, 67, 59, 58, 66, 67, 59, 67, 60, 60, 67, 61, 61, 66, 62, 61, 67, 66, 62, 66, 63, 63, 65, 64, 63, 66, 65, 21, 27, 22];
|
66, 57, 56, 65, 66, 57, 66, 58, 58, 67, 59, 58, 66, 67, 59, 67, 60, 60, 67, 61, 61, 66, 62, 61, 67, 66, 62, 66, 63, 63, 65, 64, 63, 66, 65, 21, 27, 22];
|
||||||
const TRI33 = [
|
|
||||||
|
export const TRI33 = [
|
||||||
/* eyes */ 0, 8, 7, 7, 8, 1, 2, 10, 9, 9, 10, 3,
|
/* eyes */ 0, 8, 7, 7, 8, 1, 2, 10, 9, 9, 10, 3,
|
||||||
/* brows */ 17, 0, 18, 18, 0, 7, 18, 7, 19, 19, 7, 1, 19, 1, 11, 19, 11, 20, 21, 3, 22, 21, 9, 3, 20, 9, 21, 20, 2, 9, 20, 11, 2,
|
/* brows */ 17, 0, 18, 18, 0, 7, 18, 7, 19, 19, 7, 1, 19, 1, 11, 19, 11, 20, 21, 3, 22, 21, 9, 3, 20, 9, 21, 20, 2, 9, 20, 11, 2,
|
||||||
/* 4head */ 23, 17, 18, 25, 21, 22, 24, 19, 20, 24, 18, 19, 24, 20, 21, 24, 23, 18, 24, 21, 25,
|
/* 4head */ 23, 17, 18, 25, 21, 22, 24, 19, 20, 24, 18, 19, 24, 20, 21, 24, 23, 18, 24, 21, 25,
|
||||||
|
@ -624,9 +625,10 @@ const TRI33 = [
|
||||||
/* chin */ 5, 32, 16, 16, 32, 6, 5, 30, 32, 6, 32, 31,
|
/* chin */ 5, 32, 16, 16, 32, 6, 5, 30, 32, 6, 32, 31,
|
||||||
/* cont */ 26, 30, 5, 27, 6, 31, 0, 28, 26, 3, 27, 29, 17, 28, 0, 3, 29, 22, 23, 28, 17, 22, 29, 25, 28, 30, 26, 27, 31, 29,
|
/* cont */ 26, 30, 5, 27, 6, 31, 0, 28, 26, 3, 27, 29, 17, 28, 0, 3, 29, 22, 23, 28, 17, 22, 29, 25, 28, 30, 26, 27, 31, 29,
|
||||||
];
|
];
|
||||||
const TRI7 = [0, 4, 1, 2, 4, 3, 4, 5, 6];
|
|
||||||
|
|
||||||
const VTX68 = [
|
export const TRI7 = [0, 4, 1, 2, 4, 3, 4, 5, 6];
|
||||||
|
|
||||||
|
export const VTX68 = [
|
||||||
/* cont */ 127, 234, 132, 58, 172, 150, 149, 148, 152, 377, 378, 379, 397, 288, 361, 454, 356,
|
/* cont */ 127, 234, 132, 58, 172, 150, 149, 148, 152, 377, 378, 379, 397, 288, 361, 454, 356,
|
||||||
/* brows */ 70, 63, 105, 66, 107, 336, 296, 334, 293, 300,
|
/* brows */ 70, 63, 105, 66, 107, 336, 296, 334, 293, 300,
|
||||||
/* nose */ 168, 6, 195, 4, 98, 97, 2, 326, 327,
|
/* nose */ 168, 6, 195, 4, 98, 97, 2, 326, 327,
|
||||||
|
@ -634,18 +636,13 @@ const VTX68 = [
|
||||||
/* lip */ 57, 40, 37, 0, 267, 270, 287, 321, 314, 17, 84, 91,
|
/* lip */ 57, 40, 37, 0, 267, 270, 287, 321, 314, 17, 84, 91,
|
||||||
/* mouth */ 78, 81, 13, 311, 308, 402, 14, 178,
|
/* mouth */ 78, 81, 13, 311, 308, 402, 14, 178,
|
||||||
];
|
];
|
||||||
const VTX33 = [33, 133, 362, 263, 1, 62, 308, 159, 145, 386, 374, 6, 102, 331, 2, 13, 14, 70, 105, 107, 336, 334, 300, 54, 10, 284, 50, 280, 234, 454, 58, 288, 152];
|
|
||||||
const VTX7 = [33, 133, 362, 263, 1, 78, 308];
|
|
||||||
|
|
||||||
exports.MESH_ANNOTATIONS = MESH_ANNOTATIONS;
|
export const VTX33 = [33, 133, 362, 263, 1, 62, 308, 159, 145, 386, 374, 6, 102, 331, 2, 13, 14, 70, 105, 107, 336, 334, 300, 54, 10, 284, 50, 280, 234, 454, 58, 288, 152];
|
||||||
exports.MESH_TO_IRIS_INDICES_MAP = MESH_TO_IRIS_INDICES_MAP;
|
|
||||||
|
|
||||||
exports.TRI468 = TRI468;
|
export const VTX7 = [33, 133, 362, 263, 1, 78, 308];
|
||||||
exports.TRI68 = TRI68;
|
|
||||||
exports.TRI33 = TRI33;
|
|
||||||
exports.TRI7 = TRI7;
|
|
||||||
|
|
||||||
exports.UV468 = UV468;
|
export const UV68 = VTX68.map((x) => UV468[x]);
|
||||||
exports.UV68 = VTX68.map((x) => UV468[x]);
|
|
||||||
exports.UV33 = VTX33.map((x) => UV468[x]);
|
export const UV33 = VTX33.map((x) => UV468[x]);
|
||||||
exports.UV7 = VTX7.map((x) => UV468[x]);
|
|
||||||
|
export const UV7 = VTX7.map((x) => UV468[x]);
|
|
@ -1,12 +1,14 @@
|
||||||
import { log } from '../log.js';
|
import { log } from '../log';
|
||||||
import * as tf from '../../dist/tfjs.esm.js';
|
import * as tf from '../../dist/tfjs.esm.js';
|
||||||
import * as blazeface from './blazeface.js';
|
import * as blazeface from './blazeface.js';
|
||||||
import * as facepipeline from './facepipeline.js';
|
import * as facepipeline from './facepipeline.js';
|
||||||
import * as coords from './coords.js';
|
import * as coords from './coords.js';
|
||||||
|
|
||||||
class MediaPipeFaceMesh {
|
export class MediaPipeFaceMesh {
|
||||||
|
facePipeline: any;
|
||||||
|
config: any;
|
||||||
|
|
||||||
constructor(blazeFace, blazeMeshModel, irisModel, config) {
|
constructor(blazeFace, blazeMeshModel, irisModel, config) {
|
||||||
// @ts-ignore
|
|
||||||
this.facePipeline = new facepipeline.Pipeline(blazeFace, blazeMeshModel, irisModel, config);
|
this.facePipeline = new facepipeline.Pipeline(blazeFace, blazeMeshModel, irisModel, config);
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +50,7 @@ class MediaPipeFaceMesh {
|
||||||
}
|
}
|
||||||
|
|
||||||
let faceModels = [null, null, null];
|
let faceModels = [null, null, null];
|
||||||
async function load(config) {
|
export async function load(config) {
|
||||||
faceModels = await Promise.all([
|
faceModels = await Promise.all([
|
||||||
(!faceModels[0] && config.face.enabled) ? blazeface.load(config) : null,
|
(!faceModels[0] && config.face.enabled) ? blazeface.load(config) : null,
|
||||||
(!faceModels[1] && config.face.mesh.enabled) ? tf.loadGraphModel(config.face.mesh.modelPath, { fromTFHub: config.face.mesh.modelPath.includes('tfhub.dev') }) : null,
|
(!faceModels[1] && config.face.mesh.enabled) ? tf.loadGraphModel(config.face.mesh.modelPath, { fromTFHub: config.face.mesh.modelPath.includes('tfhub.dev') }) : null,
|
||||||
|
@ -60,6 +62,4 @@ async function load(config) {
|
||||||
return faceMesh;
|
return faceMesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.load = load;
|
|
||||||
exports.MediaPipeFaceMesh = MediaPipeFaceMesh;
|
|
||||||
exports.triangulation = coords.TRI468;
|
exports.triangulation = coords.TRI468;
|
|
@ -4,7 +4,7 @@ import * as bounding from './box';
|
||||||
import * as util from './util';
|
import * as util from './util';
|
||||||
import * as coords from './coords.js';
|
import * as coords from './coords.js';
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
import { log } from '../log.js';
|
import { log } from '../log';
|
||||||
|
|
||||||
const LANDMARKS_COUNT = 468;
|
const LANDMARKS_COUNT = 468;
|
||||||
const MESH_MOUTH_INDEX = 13;
|
const MESH_MOUTH_INDEX = 13;
|
||||||
|
@ -22,11 +22,11 @@ const IRIS_IRIS_INDEX = 71;
|
||||||
const IRIS_NUM_COORDINATES = 76;
|
const IRIS_NUM_COORDINATES = 76;
|
||||||
|
|
||||||
// Replace the raw coordinates returned by facemesh with refined iris model coordinates. Update the z coordinate to be an average of the original and the new. This produces the best visual effect.
|
// Replace the raw coordinates returned by facemesh with refined iris model coordinates. Update the z coordinate to be an average of the original and the new. This produces the best visual effect.
|
||||||
function replaceRawCoordinates(rawCoords, newCoords, prefix, keys) {
|
function replaceRawCoordinates(rawCoords, newCoords, prefix, keys = null) {
|
||||||
for (let i = 0; i < coords.MESH_TO_IRIS_INDICES_MAP.length; i++) {
|
for (let i = 0; i < coords.MESH_TO_IRIS_INDICES_MAP.length; i++) {
|
||||||
const { key, indices } = coords.MESH_TO_IRIS_INDICES_MAP[i];
|
const { key, indices } = coords.MESH_TO_IRIS_INDICES_MAP[i];
|
||||||
const originalIndices = coords.MESH_ANNOTATIONS[`${prefix}${key}`];
|
const originalIndices = coords.MESH_ANNOTATIONS[`${prefix}${key}`];
|
||||||
const shouldReplaceAllKeys = keys == null;
|
const shouldReplaceAllKeys = keys === null;
|
||||||
if (shouldReplaceAllKeys || keys.includes(key)) {
|
if (shouldReplaceAllKeys || keys.includes(key)) {
|
||||||
for (let j = 0; j < indices.length; j++) {
|
for (let j = 0; j < indices.length; j++) {
|
||||||
const index = indices[j];
|
const index = indices[j];
|
||||||
|
@ -39,7 +39,19 @@ function replaceRawCoordinates(rawCoords, newCoords, prefix, keys) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The Pipeline coordinates between the bounding box and skeleton models.
|
// The Pipeline coordinates between the bounding box and skeleton models.
|
||||||
class Pipeline {
|
export class Pipeline {
|
||||||
|
storedBoxes: any;
|
||||||
|
runsWithoutFaceDetector: number;
|
||||||
|
boundingBoxDetector: any;
|
||||||
|
meshDetector: any;
|
||||||
|
irisModel: any;
|
||||||
|
meshWidth: number;
|
||||||
|
meshHeight: number;
|
||||||
|
irisSize: number;
|
||||||
|
irisEnlarge: number;
|
||||||
|
skipped: number;
|
||||||
|
detectedFaces: number;
|
||||||
|
|
||||||
constructor(boundingBoxDetector, meshDetector, irisModel, config) {
|
constructor(boundingBoxDetector, meshDetector, irisModel, config) {
|
||||||
// An array of facial bounding boxes.
|
// An array of facial bounding boxes.
|
||||||
this.storedBoxes = [];
|
this.storedBoxes = [];
|
||||||
|
@ -56,7 +68,6 @@ class Pipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
transformRawCoords(rawCoords, box, angle, rotationMatrix) {
|
transformRawCoords(rawCoords, box, angle, rotationMatrix) {
|
||||||
// @ts-ignore
|
|
||||||
const boxSize = bounding.getBoxSize({ startPoint: box.startPoint, endPoint: box.endPoint });
|
const boxSize = bounding.getBoxSize({ startPoint: box.startPoint, endPoint: box.endPoint });
|
||||||
const scaleFactor = [boxSize[0] / this.meshWidth, boxSize[1] / this.meshHeight];
|
const scaleFactor = [boxSize[0] / this.meshWidth, boxSize[1] / this.meshHeight];
|
||||||
const coordsScaled = rawCoords.map((coord) => ([
|
const coordsScaled = rawCoords.map((coord) => ([
|
||||||
|
@ -66,7 +77,6 @@ class Pipeline {
|
||||||
const coordsRotationMatrix = (angle !== 0) ? util.buildRotationMatrix(angle, [0, 0]) : util.IDENTITY_MATRIX;
|
const coordsRotationMatrix = (angle !== 0) ? util.buildRotationMatrix(angle, [0, 0]) : util.IDENTITY_MATRIX;
|
||||||
const coordsRotated = (angle !== 0) ? coordsScaled.map((coord) => ([...util.rotatePoint(coord, coordsRotationMatrix), coord[2]])) : coordsScaled;
|
const coordsRotated = (angle !== 0) ? coordsScaled.map((coord) => ([...util.rotatePoint(coord, coordsRotationMatrix), coord[2]])) : coordsScaled;
|
||||||
const inverseRotationMatrix = (angle !== 0) ? util.invertTransformMatrix(rotationMatrix) : util.IDENTITY_MATRIX;
|
const inverseRotationMatrix = (angle !== 0) ? util.invertTransformMatrix(rotationMatrix) : util.IDENTITY_MATRIX;
|
||||||
// @ts-ignore
|
|
||||||
const boxCenter = [...bounding.getBoxCenter({ startPoint: box.startPoint, endPoint: box.endPoint }), 1];
|
const boxCenter = [...bounding.getBoxCenter({ startPoint: box.startPoint, endPoint: box.endPoint }), 1];
|
||||||
return coordsRotated.map((coord) => ([
|
return coordsRotated.map((coord) => ([
|
||||||
coord[0] + util.dot(boxCenter, inverseRotationMatrix[0]),
|
coord[0] + util.dot(boxCenter, inverseRotationMatrix[0]),
|
||||||
|
@ -83,9 +93,7 @@ class Pipeline {
|
||||||
|
|
||||||
// Returns a box describing a cropped region around the eye fit for passing to the iris model.
|
// Returns a box describing a cropped region around the eye fit for passing to the iris model.
|
||||||
getEyeBox(rawCoords, face, eyeInnerCornerIndex, eyeOuterCornerIndex, flip = false) {
|
getEyeBox(rawCoords, face, eyeInnerCornerIndex, eyeOuterCornerIndex, flip = false) {
|
||||||
// @ts-ignore
|
|
||||||
const box = bounding.squarifyBox(bounding.enlargeBox(this.calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), this.irisEnlarge));
|
const box = bounding.squarifyBox(bounding.enlargeBox(this.calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), this.irisEnlarge));
|
||||||
// @ts-ignore
|
|
||||||
const boxSize = bounding.getBoxSize(box);
|
const boxSize = bounding.getBoxSize(box);
|
||||||
let crop = tf.image.cropAndResize(face, [[
|
let crop = tf.image.cropAndResize(face, [[
|
||||||
box.startPoint[1] / this.meshHeight,
|
box.startPoint[1] / this.meshHeight,
|
||||||
|
@ -159,11 +167,8 @@ class Pipeline {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
for (let i = 0; i < this.storedBoxes.length; i++) {
|
for (let i = 0; i < this.storedBoxes.length; i++) {
|
||||||
// @ts-ignore
|
|
||||||
const scaledBox = bounding.scaleBoxCoordinates({ startPoint: this.storedBoxes[i].startPoint, endPoint: this.storedBoxes[i].endPoint }, detector.scaleFactor);
|
const scaledBox = bounding.scaleBoxCoordinates({ startPoint: this.storedBoxes[i].startPoint, endPoint: this.storedBoxes[i].endPoint }, detector.scaleFactor);
|
||||||
// @ts-ignore
|
|
||||||
const enlargedBox = bounding.enlargeBox(scaledBox);
|
const enlargedBox = bounding.enlargeBox(scaledBox);
|
||||||
// @ts-ignore
|
|
||||||
const squarifiedBox = bounding.squarifyBox(enlargedBox);
|
const squarifiedBox = bounding.squarifyBox(enlargedBox);
|
||||||
const landmarks = this.storedBoxes[i].landmarks.arraySync();
|
const landmarks = this.storedBoxes[i].landmarks.arraySync();
|
||||||
const confidence = this.storedBoxes[i].confidence;
|
const confidence = this.storedBoxes[i].confidence;
|
||||||
|
@ -188,17 +193,14 @@ class Pipeline {
|
||||||
if (config.face.detector.rotation) {
|
if (config.face.detector.rotation) {
|
||||||
const [indexOfMouth, indexOfForehead] = (box.landmarks.length >= LANDMARKS_COUNT) ? MESH_KEYPOINTS_LINE_OF_SYMMETRY_INDICES : BLAZEFACE_KEYPOINTS_LINE_OF_SYMMETRY_INDICES;
|
const [indexOfMouth, indexOfForehead] = (box.landmarks.length >= LANDMARKS_COUNT) ? MESH_KEYPOINTS_LINE_OF_SYMMETRY_INDICES : BLAZEFACE_KEYPOINTS_LINE_OF_SYMMETRY_INDICES;
|
||||||
angle = util.computeRotation(box.landmarks[indexOfMouth], box.landmarks[indexOfForehead]);
|
angle = util.computeRotation(box.landmarks[indexOfMouth], box.landmarks[indexOfForehead]);
|
||||||
// @ts-ignore
|
|
||||||
const faceCenter = bounding.getBoxCenter({ startPoint: box.startPoint, endPoint: box.endPoint });
|
const faceCenter = bounding.getBoxCenter({ startPoint: box.startPoint, endPoint: box.endPoint });
|
||||||
const faceCenterNormalized = [faceCenter[0] / input.shape[2], faceCenter[1] / input.shape[1]];
|
const faceCenterNormalized = [faceCenter[0] / input.shape[2], faceCenter[1] / input.shape[1]];
|
||||||
const rotatedImage = tf.image.rotateWithOffset(input, angle, 0, faceCenterNormalized);
|
const rotatedImage = tf.image.rotateWithOffset(input, angle, 0, faceCenterNormalized);
|
||||||
rotationMatrix = util.buildRotationMatrix(-angle, faceCenter);
|
rotationMatrix = util.buildRotationMatrix(-angle, faceCenter);
|
||||||
// @ts-ignore
|
|
||||||
face = bounding.cutBoxFromImageAndResize({ startPoint: box.startPoint, endPoint: box.endPoint }, rotatedImage, [this.meshHeight, this.meshWidth]).div(255);
|
face = bounding.cutBoxFromImageAndResize({ startPoint: box.startPoint, endPoint: box.endPoint }, rotatedImage, [this.meshHeight, this.meshWidth]).div(255);
|
||||||
} else {
|
} else {
|
||||||
rotationMatrix = util.IDENTITY_MATRIX;
|
rotationMatrix = util.IDENTITY_MATRIX;
|
||||||
const cloned = input.clone();
|
const cloned = input.clone();
|
||||||
// @ts-ignore
|
|
||||||
face = bounding.cutBoxFromImageAndResize({ startPoint: box.startPoint, endPoint: box.endPoint }, cloned, [this.meshHeight, this.meshWidth]).div(255);
|
face = bounding.cutBoxFromImageAndResize({ startPoint: box.startPoint, endPoint: box.endPoint }, cloned, [this.meshHeight, this.meshWidth]).div(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,8 +217,8 @@ class Pipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
const [, confidence, contourCoords] = this.meshDetector.predict(face); // The first returned tensor represents facial contours, which are included in the coordinates.
|
const [, confidence, contourCoords] = this.meshDetector.predict(face); // The first returned tensor represents facial contours, which are included in the coordinates.
|
||||||
const confidenceVal = confidence.dataSync()[0];
|
const faceConfidence = confidence.dataSync()[0];
|
||||||
if (confidenceVal < config.face.detector.minConfidence) return null; // if below confidence just exit
|
if (faceConfidence < config.face.detector.minConfidence) return null; // if below confidence just exit
|
||||||
const coordsReshaped = tf.reshape(contourCoords, [-1, 3]);
|
const coordsReshaped = tf.reshape(contourCoords, [-1, 3]);
|
||||||
let rawCoords = coordsReshaped.arraySync();
|
let rawCoords = coordsReshaped.arraySync();
|
||||||
|
|
||||||
|
@ -245,20 +247,19 @@ class Pipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
const transformedCoordsData = this.transformRawCoords(rawCoords, box, angle, rotationMatrix);
|
const transformedCoordsData = this.transformRawCoords(rawCoords, box, angle, rotationMatrix);
|
||||||
// @ts-ignore
|
|
||||||
const landmarksBox = bounding.enlargeBox(this.calculateLandmarksBoundingBox(transformedCoordsData));
|
const landmarksBox = bounding.enlargeBox(this.calculateLandmarksBoundingBox(transformedCoordsData));
|
||||||
// @ts-ignore
|
|
||||||
const squarifiedLandmarksBox = bounding.squarifyBox(landmarksBox);
|
const squarifiedLandmarksBox = bounding.squarifyBox(landmarksBox);
|
||||||
const transformedCoords = tf.tensor2d(transformedCoordsData);
|
const transformedCoords = tf.tensor2d(transformedCoordsData);
|
||||||
const prediction = {
|
const prediction = {
|
||||||
coords: transformedCoords,
|
coords: transformedCoords,
|
||||||
box: landmarksBox,
|
box: landmarksBox,
|
||||||
faceConfidence: confidenceVal,
|
faceConfidence,
|
||||||
confidence: box.confidence,
|
confidence: box.confidence,
|
||||||
image: face,
|
image: face,
|
||||||
|
rawCoords,
|
||||||
};
|
};
|
||||||
if (config.face.mesh.returnRawData) prediction.rawCoords = rawCoords;
|
if (!config.face.mesh.returnRawData) delete prediction.rawCoords;
|
||||||
this.storedBoxes[i] = { ...squarifiedLandmarksBox, landmarks: transformedCoords.arraySync(), confidence: box.confidence, faceConfidence: confidenceVal };
|
this.storedBoxes[i] = { ...squarifiedLandmarksBox, landmarks: transformedCoords.arraySync(), confidence: box.confidence, faceConfidence };
|
||||||
|
|
||||||
return prediction;
|
return prediction;
|
||||||
}));
|
}));
|
||||||
|
@ -275,4 +276,3 @@ class Pipeline {
|
||||||
return { startPoint, endPoint, landmarks };
|
return { startPoint, endPoint, landmarks };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.Pipeline = Pipeline;
|
|
|
@ -1,52 +1,47 @@
|
||||||
exports.IDENTITY_MATRIX = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];
|
export const IDENTITY_MATRIX = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];
|
||||||
/**
|
/**
|
||||||
* Normalizes the provided angle to the range -pi to pi.
|
* Normalizes the provided angle to the range -pi to pi.
|
||||||
* @param angle The angle in radians to be normalized.
|
* @param angle The angle in radians to be normalized.
|
||||||
*/
|
*/
|
||||||
function normalizeRadians(angle) {
|
export function normalizeRadians(angle) {
|
||||||
return angle - 2 * Math.PI * Math.floor((angle + Math.PI) / (2 * Math.PI));
|
return angle - 2 * Math.PI * Math.floor((angle + Math.PI) / (2 * Math.PI));
|
||||||
}
|
}
|
||||||
exports.normalizeRadians = normalizeRadians;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the angle of rotation between two anchor points.
|
* Computes the angle of rotation between two anchor points.
|
||||||
* @param point1 First anchor point
|
* @param point1 First anchor point
|
||||||
* @param point2 Second anchor point
|
* @param point2 Second anchor point
|
||||||
*/
|
*/
|
||||||
function computeRotation(point1, point2) {
|
export function computeRotation(point1, point2) {
|
||||||
const radians = Math.PI / 2 - Math.atan2(-(point2[1] - point1[1]), point2[0] - point1[0]);
|
const radians = Math.PI / 2 - Math.atan2(-(point2[1] - point1[1]), point2[0] - point1[0]);
|
||||||
return normalizeRadians(radians);
|
return normalizeRadians(radians);
|
||||||
}
|
}
|
||||||
exports.computeRotation = computeRotation;
|
|
||||||
|
|
||||||
function radToDegrees(rad) {
|
export function radToDegrees(rad) {
|
||||||
return rad * 180 / Math.PI;
|
return rad * 180 / Math.PI;
|
||||||
}
|
}
|
||||||
exports.radToDegrees = radToDegrees;
|
|
||||||
|
|
||||||
function buildTranslationMatrix(x, y) {
|
export function buildTranslationMatrix(x, y) {
|
||||||
return [[1, 0, x], [0, 1, y], [0, 0, 1]];
|
return [[1, 0, x], [0, 1, y], [0, 0, 1]];
|
||||||
}
|
}
|
||||||
|
|
||||||
function dot(v1, v2) {
|
export function dot(v1, v2) {
|
||||||
let product = 0;
|
let product = 0;
|
||||||
for (let i = 0; i < v1.length; i++) {
|
for (let i = 0; i < v1.length; i++) {
|
||||||
product += v1[i] * v2[i];
|
product += v1[i] * v2[i];
|
||||||
}
|
}
|
||||||
return product;
|
return product;
|
||||||
}
|
}
|
||||||
exports.dot = dot;
|
|
||||||
|
|
||||||
function getColumnFrom2DArr(arr, columnIndex) {
|
export function getColumnFrom2DArr(arr, columnIndex) {
|
||||||
const column = [];
|
const column = [];
|
||||||
for (let i = 0; i < arr.length; i++) {
|
for (let i = 0; i < arr.length; i++) {
|
||||||
column.push(arr[i][columnIndex]);
|
column.push(arr[i][columnIndex]);
|
||||||
}
|
}
|
||||||
return column;
|
return column;
|
||||||
}
|
}
|
||||||
exports.getColumnFrom2DArr = getColumnFrom2DArr;
|
|
||||||
|
|
||||||
function multiplyTransformMatrices(mat1, mat2) {
|
export function multiplyTransformMatrices(mat1, mat2) {
|
||||||
const product = [];
|
const product = [];
|
||||||
const size = mat1.length;
|
const size = mat1.length;
|
||||||
for (let row = 0; row < size; row++) {
|
for (let row = 0; row < size; row++) {
|
||||||
|
@ -57,7 +52,8 @@ function multiplyTransformMatrices(mat1, mat2) {
|
||||||
}
|
}
|
||||||
return product;
|
return product;
|
||||||
}
|
}
|
||||||
function buildRotationMatrix(rotation, center) {
|
|
||||||
|
export function buildRotationMatrix(rotation, center) {
|
||||||
const cosA = Math.cos(rotation);
|
const cosA = Math.cos(rotation);
|
||||||
const sinA = Math.sin(rotation);
|
const sinA = Math.sin(rotation);
|
||||||
const rotationMatrix = [[cosA, -sinA, 0], [sinA, cosA, 0], [0, 0, 1]];
|
const rotationMatrix = [[cosA, -sinA, 0], [sinA, cosA, 0], [0, 0, 1]];
|
||||||
|
@ -66,9 +62,8 @@ function buildRotationMatrix(rotation, center) {
|
||||||
const negativeTranslationMatrix = buildTranslationMatrix(-center[0], -center[1]);
|
const negativeTranslationMatrix = buildTranslationMatrix(-center[0], -center[1]);
|
||||||
return multiplyTransformMatrices(translationTimesRotation, negativeTranslationMatrix);
|
return multiplyTransformMatrices(translationTimesRotation, negativeTranslationMatrix);
|
||||||
}
|
}
|
||||||
exports.buildRotationMatrix = buildRotationMatrix;
|
|
||||||
|
|
||||||
function invertTransformMatrix(matrix) {
|
export function invertTransformMatrix(matrix) {
|
||||||
const rotationComponent = [[matrix[0][0], matrix[1][0]], [matrix[0][1], matrix[1][1]]];
|
const rotationComponent = [[matrix[0][0], matrix[1][0]], [matrix[0][1], matrix[1][1]]];
|
||||||
const translationComponent = [matrix[0][2], matrix[1][2]];
|
const translationComponent = [matrix[0][2], matrix[1][2]];
|
||||||
const invertedTranslation = [
|
const invertedTranslation = [
|
||||||
|
@ -81,17 +76,14 @@ function invertTransformMatrix(matrix) {
|
||||||
[0, 0, 1],
|
[0, 0, 1],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
exports.invertTransformMatrix = invertTransformMatrix;
|
|
||||||
|
|
||||||
function rotatePoint(homogeneousCoordinate, rotationMatrix) {
|
export function rotatePoint(homogeneousCoordinate, rotationMatrix) {
|
||||||
return [
|
return [
|
||||||
dot(homogeneousCoordinate, rotationMatrix[0]),
|
dot(homogeneousCoordinate, rotationMatrix[0]),
|
||||||
dot(homogeneousCoordinate, rotationMatrix[1]),
|
dot(homogeneousCoordinate, rotationMatrix[1]),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
exports.rotatePoint = rotatePoint;
|
|
||||||
|
|
||||||
function xyDistanceBetweenPoints(a, b) {
|
export function xyDistanceBetweenPoints(a, b) {
|
||||||
return Math.sqrt(((a[0] - b[0]) ** 2) + ((a[1] - b[1]) ** 2));
|
return Math.sqrt(((a[0] - b[0]) ** 2) + ((a[1] - b[1]) ** 2));
|
||||||
}
|
}
|
||||||
exports.xyDistanceBetweenPoints = xyDistanceBetweenPoints;
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { log } from '../log.js';
|
import { log } from '../log';
|
||||||
import * as tf from '../../dist/tfjs.esm.js';
|
import * as tf from '../../dist/tfjs.esm.js';
|
||||||
import * as profile from '../profile.js';
|
import * as profile from '../profile.js';
|
||||||
|
|
||||||
// based on https://github.com/sirius-ai/MobileFaceNet_TF
|
// based on https://github.com/sirius-ai/MobileFaceNet_TF
|
||||||
// model converted from https://github.com/sirius-ai/MobileFaceNet_TF/files/3551493/FaceMobileNet192_train_false.zip
|
// model converted from https://github.com/sirius-ai/MobileFaceNet_TF/files/3551493/FaceMobileNet192_train_false.zip
|
||||||
|
|
||||||
const models = {};
|
const models = { embedding: null };
|
||||||
|
|
||||||
async function load(config) {
|
export async function load(config) {
|
||||||
if (!models.embedding) {
|
if (!models.embedding) {
|
||||||
models.embedding = await tf.loadGraphModel(config.face.embedding.modelPath);
|
models.embedding = await tf.loadGraphModel(config.face.embedding.modelPath);
|
||||||
log(`load model: ${config.face.embedding.modelPath.match(/\/(.*)\./)[1]}`);
|
log(`load model: ${config.face.embedding.modelPath.match(/\/(.*)\./)[1]}`);
|
||||||
|
@ -15,7 +15,7 @@ async function load(config) {
|
||||||
return models.embedding;
|
return models.embedding;
|
||||||
}
|
}
|
||||||
|
|
||||||
function simmilarity(embedding1, embedding2) {
|
export function simmilarity(embedding1, embedding2) {
|
||||||
if (embedding1?.length !== embedding2?.length) return 0;
|
if (embedding1?.length !== embedding2?.length) return 0;
|
||||||
// general minkowski distance
|
// general minkowski distance
|
||||||
// euclidean distance is limited case where order is 2
|
// euclidean distance is limited case where order is 2
|
||||||
|
@ -24,7 +24,7 @@ function simmilarity(embedding1, embedding2) {
|
||||||
return (Math.trunc(1000 * (1 - distance)) / 1000);
|
return (Math.trunc(1000 * (1 - distance)) / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function predict(image, config) {
|
export async function predict(image, config) {
|
||||||
if (!models.embedding) return null;
|
if (!models.embedding) return null;
|
||||||
return new Promise(async (resolve) => {
|
return new Promise(async (resolve) => {
|
||||||
const resize = tf.image.resizeBilinear(image, [config.face.embedding.inputSize, config.face.embedding.inputSize], false);
|
const resize = tf.image.resizeBilinear(image, [config.face.embedding.inputSize, config.face.embedding.inputSize], false);
|
||||||
|
@ -39,7 +39,6 @@ async function predict(image, config) {
|
||||||
const profileData = await tf.profile(() => models.embedding.predict({ img_inputs: resize }));
|
const profileData = await tf.profile(() => models.embedding.predict({ img_inputs: resize }));
|
||||||
data = [...profileData.result.dataSync()];
|
data = [...profileData.result.dataSync()];
|
||||||
profileData.result.dispose();
|
profileData.result.dispose();
|
||||||
// @ts-ignore
|
|
||||||
profile.run('emotion', profileData);
|
profile.run('emotion', profileData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +47,3 @@ async function predict(image, config) {
|
||||||
resolve(data);
|
resolve(data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.predict = predict;
|
|
||||||
exports.simmilarity = simmilarity;
|
|
||||||
exports.load = load;
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { log } from '../log.js';
|
import { log } from '../log';
|
||||||
import * as tf from '../../dist/tfjs.esm.js';
|
import * as tf from '../../dist/tfjs.esm.js';
|
||||||
import * as profile from '../profile.js';
|
import * as profile from '../profile.js';
|
||||||
|
|
||||||
const annotations = ['angry', 'disgust', 'fear', 'happy', 'sad', 'surprise', 'neutral'];
|
const annotations = ['angry', 'disgust', 'fear', 'happy', 'sad', 'surprise', 'neutral'];
|
||||||
const models = {};
|
const models = { emotion: null };
|
||||||
let last = [];
|
let last = [];
|
||||||
let skipped = Number.MAX_SAFE_INTEGER;
|
let skipped = Number.MAX_SAFE_INTEGER;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ let skipped = Number.MAX_SAFE_INTEGER;
|
||||||
const rgb = [0.2989, 0.5870, 0.1140]; // factors for red/green/blue colors when converting to grayscale
|
const rgb = [0.2989, 0.5870, 0.1140]; // factors for red/green/blue colors when converting to grayscale
|
||||||
const scale = 1; // score multiplication factor
|
const scale = 1; // score multiplication factor
|
||||||
|
|
||||||
async function load(config) {
|
export async function load(config) {
|
||||||
if (!models.emotion) {
|
if (!models.emotion) {
|
||||||
models.emotion = await tf.loadGraphModel(config.face.emotion.modelPath);
|
models.emotion = await tf.loadGraphModel(config.face.emotion.modelPath);
|
||||||
log(`load model: ${config.face.emotion.modelPath.match(/\/(.*)\./)[1]}`);
|
log(`load model: ${config.face.emotion.modelPath.match(/\/(.*)\./)[1]}`);
|
||||||
|
@ -19,7 +19,7 @@ async function load(config) {
|
||||||
return models.emotion;
|
return models.emotion;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function predict(image, config) {
|
export async function predict(image, config) {
|
||||||
if (!models.emotion) return null;
|
if (!models.emotion) return null;
|
||||||
if ((skipped < config.face.emotion.skipFrames) && config.videoOptimized && (last.length > 0)) {
|
if ((skipped < config.face.emotion.skipFrames) && config.videoOptimized && (last.length > 0)) {
|
||||||
skipped++;
|
skipped++;
|
||||||
|
@ -77,6 +77,3 @@ async function predict(image, config) {
|
||||||
resolve(obj);
|
resolve(obj);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.predict = predict;
|
|
||||||
exports.load = load;
|
|
|
@ -1,9 +1,14 @@
|
||||||
import { log } from '../log.js';
|
import { log } from '../log';
|
||||||
import * as tf from '../../dist/tfjs.esm.js';
|
import * as tf from '../../dist/tfjs.esm.js';
|
||||||
import * as profile from '../profile.js';
|
import * as profile from '../profile.js';
|
||||||
|
|
||||||
class FaceBoxes {
|
export class FaceBoxes {
|
||||||
|
enlarge: number;
|
||||||
|
model: any;
|
||||||
|
config: any;
|
||||||
|
|
||||||
constructor(model, config) {
|
constructor(model, config) {
|
||||||
|
this.enlarge = 1.1;
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
@ -36,15 +41,20 @@ class FaceBoxes {
|
||||||
resizeT.dispose();
|
resizeT.dispose();
|
||||||
for (const i in boxes) {
|
for (const i in boxes) {
|
||||||
if (scores[i] && scores[i] > this.config.face.detector.minConfidence) {
|
if (scores[i] && scores[i] > this.config.face.detector.minConfidence) {
|
||||||
const enlarge = 1.05;
|
const crop = [boxes[i][0] / this.enlarge, boxes[i][1] / this.enlarge, boxes[i][2] * this.enlarge, boxes[i][3] * this.enlarge];
|
||||||
const crop = [boxes[i][0] / enlarge, boxes[i][1] / enlarge, boxes[i][2] * enlarge, boxes[i][3] * enlarge];
|
|
||||||
const boxRaw = [crop[1], crop[0], (crop[3]) - (crop[1]), (crop[2]) - (crop[0])];
|
const boxRaw = [crop[1], crop[0], (crop[3]) - (crop[1]), (crop[2]) - (crop[0])];
|
||||||
const box = [parseInt(boxRaw[0] * input.shape[2]), parseInt(boxRaw[1] * input.shape[1]), parseInt(boxRaw[2] * input.shape[2]), parseInt(boxRaw[3] * input.shape[1])];
|
const box = [
|
||||||
const image = tf.image.cropAndResize(input, [crop], [0], [this.config.face.detector.inputSize, this.config.face.detector.inputSize]);
|
parseInt((boxRaw[0] * input.shape[2]).toString()),
|
||||||
|
parseInt((boxRaw[1] * input.shape[1]).toString()),
|
||||||
|
parseInt((boxRaw[2] * input.shape[2]).toString()),
|
||||||
|
parseInt((boxRaw[3] * input.shape[1]).toString())];
|
||||||
|
const resized = tf.image.cropAndResize(input, [crop], [0], [this.config.face.detector.inputSize, this.config.face.detector.inputSize]);
|
||||||
|
const image = resized.div([255]);
|
||||||
|
resized.dispose();
|
||||||
results.push({
|
results.push({
|
||||||
confidence: scores[i],
|
confidence: scores[i],
|
||||||
box,
|
box,
|
||||||
boxRaw,
|
boxRaw: this.config.face.mesh.returnRawData ? boxRaw : null,
|
||||||
image,
|
image,
|
||||||
// mesh,
|
// mesh,
|
||||||
// meshRaw,
|
// meshRaw,
|
||||||
|
@ -56,7 +66,7 @@ class FaceBoxes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function load(config) {
|
export async function load(config) {
|
||||||
const model = await tf.loadGraphModel(config.face.detector.modelPath);
|
const model = await tf.loadGraphModel(config.face.detector.modelPath);
|
||||||
log(`load model: ${config.face.detector.modelPath.match(/\/(.*)\./)[1]}`);
|
log(`load model: ${config.face.detector.modelPath.match(/\/(.*)\./)[1]}`);
|
||||||
const faceboxes = new FaceBoxes(model, config);
|
const faceboxes = new FaceBoxes(model, config);
|
||||||
|
@ -64,6 +74,3 @@ async function load(config) {
|
||||||
if (config.face.iris.enabled) log(`load model: ${config.face.iris.modelPath.match(/\/(.*)\./)[1]}`);
|
if (config.face.iris.enabled) log(`load model: ${config.face.iris.modelPath.match(/\/(.*)\./)[1]}`);
|
||||||
return faceboxes;
|
return faceboxes;
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.load = load;
|
|
||||||
exports.FaceBoxes = FaceBoxes;
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { log } from '../log.js';
|
import { log } from '../log';
|
||||||
import * as tf from '../../dist/tfjs.esm.js';
|
import * as tf from '../../dist/tfjs.esm.js';
|
||||||
import * as profile from '../profile.js';
|
import * as profile from '../profile.js';
|
||||||
|
|
||||||
const models = {};
|
const models = { gender: null };
|
||||||
let last = { gender: '' };
|
let last = { gender: '' };
|
||||||
let skipped = Number.MAX_SAFE_INTEGER;
|
let skipped = Number.MAX_SAFE_INTEGER;
|
||||||
let alternative = false;
|
let alternative = false;
|
||||||
|
@ -10,7 +10,7 @@ let alternative = false;
|
||||||
// tuning values
|
// tuning values
|
||||||
const rgb = [0.2989, 0.5870, 0.1140]; // factors for red/green/blue colors when converting to grayscale
|
const rgb = [0.2989, 0.5870, 0.1140]; // factors for red/green/blue colors when converting to grayscale
|
||||||
|
|
||||||
async function load(config) {
|
export async function load(config) {
|
||||||
if (!models.gender) {
|
if (!models.gender) {
|
||||||
models.gender = await tf.loadGraphModel(config.face.gender.modelPath);
|
models.gender = await tf.loadGraphModel(config.face.gender.modelPath);
|
||||||
alternative = models.gender.inputs[0].shape[3] === 1;
|
alternative = models.gender.inputs[0].shape[3] === 1;
|
||||||
|
@ -19,7 +19,7 @@ async function load(config) {
|
||||||
return models.gender;
|
return models.gender;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function predict(image, config) {
|
export async function predict(image, config) {
|
||||||
if (!models.gender) return null;
|
if (!models.gender) return null;
|
||||||
if ((skipped < config.face.gender.skipFrames) && config.videoOptimized && last.gender !== '') {
|
if ((skipped < config.face.gender.skipFrames) && config.videoOptimized && last.gender !== '') {
|
||||||
skipped++;
|
skipped++;
|
||||||
|
@ -45,7 +45,7 @@ async function predict(image, config) {
|
||||||
tf.dispose(resize);
|
tf.dispose(resize);
|
||||||
|
|
||||||
let genderT;
|
let genderT;
|
||||||
const obj = {};
|
const obj = { gender: undefined, confidence: undefined };
|
||||||
|
|
||||||
if (!config.profile) {
|
if (!config.profile) {
|
||||||
if (config.face.gender.enabled) genderT = await models.gender.predict(enhance);
|
if (config.face.gender.enabled) genderT = await models.gender.predict(enhance);
|
||||||
|
@ -53,7 +53,6 @@ async function predict(image, config) {
|
||||||
const profileGender = config.face.gender.enabled ? await tf.profile(() => models.gender.predict(enhance)) : {};
|
const profileGender = config.face.gender.enabled ? await tf.profile(() => models.gender.predict(enhance)) : {};
|
||||||
genderT = profileGender.result.clone();
|
genderT = profileGender.result.clone();
|
||||||
profileGender.result.dispose();
|
profileGender.result.dispose();
|
||||||
// @ts-ignore
|
|
||||||
profile.run('gender', profileGender);
|
profile.run('gender', profileGender);
|
||||||
}
|
}
|
||||||
enhance.dispose();
|
enhance.dispose();
|
||||||
|
@ -82,6 +81,3 @@ async function predict(image, config) {
|
||||||
resolve(obj);
|
resolve(obj);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.predict = predict;
|
|
||||||
exports.load = load;
|
|
|
@ -1,4 +1,4 @@
|
||||||
exports.body = (res) => {
|
export const body = (res) => {
|
||||||
if (!res) return [];
|
if (!res) return [];
|
||||||
const gestures = [];
|
const gestures = [];
|
||||||
for (let i = 0; i < res.length; i++) {
|
for (let i = 0; i < res.length; i++) {
|
||||||
|
@ -18,7 +18,7 @@ exports.body = (res) => {
|
||||||
return gestures;
|
return gestures;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.face = (res) => {
|
export const face = (res) => {
|
||||||
if (!res) return [];
|
if (!res) return [];
|
||||||
const gestures = [];
|
const gestures = [];
|
||||||
for (let i = 0; i < res.length; i++) {
|
for (let i = 0; i < res.length; i++) {
|
||||||
|
@ -39,7 +39,7 @@ exports.face = (res) => {
|
||||||
return gestures;
|
return gestures;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.iris = (res) => {
|
export const iris = (res) => {
|
||||||
if (!res) return [];
|
if (!res) return [];
|
||||||
const gestures = [];
|
const gestures = [];
|
||||||
for (let i = 0; i < res.length; i++) {
|
for (let i = 0; i < res.length; i++) {
|
||||||
|
@ -58,7 +58,7 @@ exports.iris = (res) => {
|
||||||
return gestures;
|
return gestures;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.hand = (res) => {
|
export const hand = (res) => {
|
||||||
if (!res) return [];
|
if (!res) return [];
|
||||||
const gestures = [];
|
const gestures = [];
|
||||||
for (let i = 0; i < res.length; i++) {
|
for (let i = 0; i < res.length; i++) {
|
|
@ -1,4 +1,4 @@
|
||||||
exports.anchors = [
|
export const anchors = [
|
||||||
{
|
{
|
||||||
w: 1,
|
w: 1,
|
||||||
h: 1,
|
h: 1,
|
|
@ -1,18 +1,20 @@
|
||||||
import * as tf from '../../dist/tfjs.esm.js';
|
import * as tf from '../../dist/tfjs.esm.js';
|
||||||
|
|
||||||
function getBoxSize(box) {
|
export function getBoxSize(box) {
|
||||||
return [
|
return [
|
||||||
Math.abs(box.endPoint[0] - box.startPoint[0]),
|
Math.abs(box.endPoint[0] - box.startPoint[0]),
|
||||||
Math.abs(box.endPoint[1] - box.startPoint[1]),
|
Math.abs(box.endPoint[1] - box.startPoint[1]),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
function getBoxCenter(box) {
|
|
||||||
|
export function getBoxCenter(box) {
|
||||||
return [
|
return [
|
||||||
box.startPoint[0] + (box.endPoint[0] - box.startPoint[0]) / 2,
|
box.startPoint[0] + (box.endPoint[0] - box.startPoint[0]) / 2,
|
||||||
box.startPoint[1] + (box.endPoint[1] - box.startPoint[1]) / 2,
|
box.startPoint[1] + (box.endPoint[1] - box.startPoint[1]) / 2,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
function cutBoxFromImageAndResize(box, image, cropSize) {
|
|
||||||
|
export function cutBoxFromImageAndResize(box, image, cropSize) {
|
||||||
const h = image.shape[1];
|
const h = image.shape[1];
|
||||||
const w = image.shape[2];
|
const w = image.shape[2];
|
||||||
const boxes = [[
|
const boxes = [[
|
||||||
|
@ -23,7 +25,8 @@ function cutBoxFromImageAndResize(box, image, cropSize) {
|
||||||
]];
|
]];
|
||||||
return tf.image.cropAndResize(image, boxes, [0], cropSize);
|
return tf.image.cropAndResize(image, boxes, [0], cropSize);
|
||||||
}
|
}
|
||||||
function scaleBoxCoordinates(box, factor) {
|
|
||||||
|
export function scaleBoxCoordinates(box, factor) {
|
||||||
const startPoint = [box.startPoint[0] * factor[0], box.startPoint[1] * factor[1]];
|
const startPoint = [box.startPoint[0] * factor[0], box.startPoint[1] * factor[1]];
|
||||||
const endPoint = [box.endPoint[0] * factor[0], box.endPoint[1] * factor[1]];
|
const endPoint = [box.endPoint[0] * factor[0], box.endPoint[1] * factor[1]];
|
||||||
const palmLandmarks = box.palmLandmarks.map((coord) => {
|
const palmLandmarks = box.palmLandmarks.map((coord) => {
|
||||||
|
@ -32,7 +35,8 @@ function scaleBoxCoordinates(box, factor) {
|
||||||
});
|
});
|
||||||
return { startPoint, endPoint, palmLandmarks, confidence: box.confidence };
|
return { startPoint, endPoint, palmLandmarks, confidence: box.confidence };
|
||||||
}
|
}
|
||||||
function enlargeBox(box, factor = 1.5) {
|
|
||||||
|
export function enlargeBox(box, factor = 1.5) {
|
||||||
const center = getBoxCenter(box);
|
const center = getBoxCenter(box);
|
||||||
const size = getBoxSize(box);
|
const size = getBoxSize(box);
|
||||||
const newHalfSize = [factor * size[0] / 2, factor * size[1] / 2];
|
const newHalfSize = [factor * size[0] / 2, factor * size[1] / 2];
|
||||||
|
@ -40,7 +44,8 @@ function enlargeBox(box, factor = 1.5) {
|
||||||
const endPoint = [center[0] + newHalfSize[0], center[1] + newHalfSize[1]];
|
const endPoint = [center[0] + newHalfSize[0], center[1] + newHalfSize[1]];
|
||||||
return { startPoint, endPoint, palmLandmarks: box.palmLandmarks };
|
return { startPoint, endPoint, palmLandmarks: box.palmLandmarks };
|
||||||
}
|
}
|
||||||
function squarifyBox(box) {
|
|
||||||
|
export function squarifyBox(box) {
|
||||||
const centers = getBoxCenter(box);
|
const centers = getBoxCenter(box);
|
||||||
const size = getBoxSize(box);
|
const size = getBoxSize(box);
|
||||||
const maxEdge = Math.max(...size);
|
const maxEdge = Math.max(...size);
|
||||||
|
@ -49,7 +54,8 @@ function squarifyBox(box) {
|
||||||
const endPoint = [centers[0] + halfSize, centers[1] + halfSize];
|
const endPoint = [centers[0] + halfSize, centers[1] + halfSize];
|
||||||
return { startPoint, endPoint, palmLandmarks: box.palmLandmarks };
|
return { startPoint, endPoint, palmLandmarks: box.palmLandmarks };
|
||||||
}
|
}
|
||||||
function shiftBox(box, shiftFactor) {
|
|
||||||
|
export function shiftBox(box, shiftFactor) {
|
||||||
const boxSize = [
|
const boxSize = [
|
||||||
box.endPoint[0] - box.startPoint[0],
|
box.endPoint[0] - box.startPoint[0],
|
||||||
box.endPoint[1] - box.startPoint[1],
|
box.endPoint[1] - box.startPoint[1],
|
||||||
|
@ -59,12 +65,3 @@ function shiftBox(box, shiftFactor) {
|
||||||
const endPoint = [box.endPoint[0] + shiftVector[0], box.endPoint[1] + shiftVector[1]];
|
const endPoint = [box.endPoint[0] + shiftVector[0], box.endPoint[1] + shiftVector[1]];
|
||||||
return { startPoint, endPoint, palmLandmarks: box.palmLandmarks };
|
return { startPoint, endPoint, palmLandmarks: box.palmLandmarks };
|
||||||
}
|
}
|
||||||
export {
|
|
||||||
cutBoxFromImageAndResize,
|
|
||||||
enlargeBox,
|
|
||||||
getBoxCenter,
|
|
||||||
getBoxSize,
|
|
||||||
scaleBoxCoordinates,
|
|
||||||
shiftBox,
|
|
||||||
squarifyBox,
|
|
||||||
};
|
|
|
@ -1,7 +1,13 @@
|
||||||
import * as tf from '../../dist/tfjs.esm.js';
|
import * as tf from '../../dist/tfjs.esm.js';
|
||||||
import * as box from './box';
|
import * as box from './box';
|
||||||
|
|
||||||
class HandDetector {
|
export class HandDetector {
|
||||||
|
model: any;
|
||||||
|
anchors: any;
|
||||||
|
anchorsTensor: any;
|
||||||
|
inputSizeTensor: any;
|
||||||
|
doubleInputSizeTensor: any;
|
||||||
|
|
||||||
constructor(model, inputSize, anchorsAnnotated) {
|
constructor(model, inputSize, anchorsAnnotated) {
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.anchors = anchorsAnnotated.map((anchor) => [anchor.x_center, anchor.y_center]);
|
this.anchors = anchorsAnnotated.map((anchor) => [anchor.x_center, anchor.y_center]);
|
||||||
|
@ -78,4 +84,3 @@ class HandDetector {
|
||||||
return hands;
|
return hands;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.HandDetector = HandDetector;
|
|
|
@ -2,7 +2,7 @@ import * as tf from '../../dist/tfjs.esm.js';
|
||||||
import * as box from './box';
|
import * as box from './box';
|
||||||
import * as util from './util';
|
import * as util from './util';
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
import { log } from '../log.js';
|
import { log } from '../log';
|
||||||
|
|
||||||
// const PALM_BOX_SHIFT_VECTOR = [0, -0.4];
|
// const PALM_BOX_SHIFT_VECTOR = [0, -0.4];
|
||||||
const PALM_BOX_ENLARGE_FACTOR = 5; // default 3
|
const PALM_BOX_ENLARGE_FACTOR = 5; // default 3
|
||||||
|
@ -12,7 +12,14 @@ const PALM_LANDMARK_IDS = [0, 5, 9, 13, 17, 1, 2];
|
||||||
const PALM_LANDMARKS_INDEX_OF_PALM_BASE = 0;
|
const PALM_LANDMARKS_INDEX_OF_PALM_BASE = 0;
|
||||||
const PALM_LANDMARKS_INDEX_OF_MIDDLE_FINGER_BASE = 2;
|
const PALM_LANDMARKS_INDEX_OF_MIDDLE_FINGER_BASE = 2;
|
||||||
|
|
||||||
class HandPipeline {
|
export class HandPipeline {
|
||||||
|
handDetector: any;
|
||||||
|
landmarkDetector: any;
|
||||||
|
inputSize: number;
|
||||||
|
storedBoxes: any;
|
||||||
|
skipped: number;
|
||||||
|
detectedHands: number;
|
||||||
|
|
||||||
constructor(handDetector, landmarkDetector, inputSize) {
|
constructor(handDetector, landmarkDetector, inputSize) {
|
||||||
this.handDetector = handDetector;
|
this.handDetector = handDetector;
|
||||||
this.landmarkDetector = landmarkDetector;
|
this.landmarkDetector = landmarkDetector;
|
||||||
|
@ -154,5 +161,3 @@ class HandPipeline {
|
||||||
return { startPoint, endPoint };
|
return { startPoint, endPoint };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.HandPipeline = HandPipeline;
|
|
|
@ -1,6 +1,6 @@
|
||||||
// https://storage.googleapis.com/tfjs-models/demos/handpose/index.html
|
// https://storage.googleapis.com/tfjs-models/demos/handpose/index.html
|
||||||
|
|
||||||
import { log } from '../log.js';
|
import { log } from '../log';
|
||||||
import * as tf from '../../dist/tfjs.esm.js';
|
import * as tf from '../../dist/tfjs.esm.js';
|
||||||
import * as handdetector from './handdetector';
|
import * as handdetector from './handdetector';
|
||||||
import * as handpipeline from './handpipeline';
|
import * as handpipeline from './handpipeline';
|
||||||
|
@ -15,7 +15,9 @@ const MESH_ANNOTATIONS = {
|
||||||
palmBase: [0],
|
palmBase: [0],
|
||||||
};
|
};
|
||||||
|
|
||||||
class HandPose {
|
export class HandPose {
|
||||||
|
handPipeline: any;
|
||||||
|
|
||||||
constructor(handPipeline) {
|
constructor(handPipeline) {
|
||||||
this.handPipeline = handPipeline;
|
this.handPipeline = handPipeline;
|
||||||
}
|
}
|
||||||
|
@ -51,20 +53,16 @@ class HandPose {
|
||||||
return hands;
|
return hands;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.HandPose = HandPose;
|
|
||||||
|
|
||||||
async function load(config) {
|
export async function load(config) {
|
||||||
const [handDetectorModel, handPoseModel] = await Promise.all([
|
const [handDetectorModel, handPoseModel] = await Promise.all([
|
||||||
config.hand.enabled ? tf.loadGraphModel(config.hand.detector.modelPath, { fromTFHub: config.hand.detector.modelPath.includes('tfhub.dev') }) : null,
|
config.hand.enabled ? tf.loadGraphModel(config.hand.detector.modelPath, { fromTFHub: config.hand.detector.modelPath.includes('tfhub.dev') }) : null,
|
||||||
config.hand.landmarks ? tf.loadGraphModel(config.hand.skeleton.modelPath, { fromTFHub: config.hand.skeleton.modelPath.includes('tfhub.dev') }) : null,
|
config.hand.landmarks ? tf.loadGraphModel(config.hand.skeleton.modelPath, { fromTFHub: config.hand.skeleton.modelPath.includes('tfhub.dev') }) : null,
|
||||||
]);
|
]);
|
||||||
// @ts-ignore
|
|
||||||
const handDetector = new handdetector.HandDetector(handDetectorModel, config.hand.inputSize, anchors.anchors);
|
const handDetector = new handdetector.HandDetector(handDetectorModel, config.hand.inputSize, anchors.anchors);
|
||||||
// @ts-ignore
|
|
||||||
const handPipeline = new handpipeline.HandPipeline(handDetector, handPoseModel, config.hand.inputSize);
|
const handPipeline = new handpipeline.HandPipeline(handDetector, handPoseModel, config.hand.inputSize);
|
||||||
const handPose = new HandPose(handPipeline);
|
const handPose = new HandPose(handPipeline);
|
||||||
if (config.hand.enabled) log(`load model: ${config.hand.detector.modelPath.match(/\/(.*)\./)[1]}`);
|
if (config.hand.enabled) log(`load model: ${config.hand.detector.modelPath.match(/\/(.*)\./)[1]}`);
|
||||||
if (config.hand.landmarks) log(`load model: ${config.hand.skeleton.modelPath.match(/\/(.*)\./)[1]}`);
|
if (config.hand.landmarks) log(`load model: ${config.hand.skeleton.modelPath.match(/\/(.*)\./)[1]}`);
|
||||||
return handPose;
|
return handPose;
|
||||||
}
|
}
|
||||||
exports.load = load;
|
|
|
@ -1,38 +1,43 @@
|
||||||
function normalizeRadians(angle) {
|
export function normalizeRadians(angle) {
|
||||||
return angle - 2 * Math.PI * Math.floor((angle + Math.PI) / (2 * Math.PI));
|
return angle - 2 * Math.PI * Math.floor((angle + Math.PI) / (2 * Math.PI));
|
||||||
}
|
}
|
||||||
function computeRotation(point1, point2) {
|
|
||||||
|
export function computeRotation(point1, point2) {
|
||||||
const radians = Math.PI / 2 - Math.atan2(-(point2[1] - point1[1]), point2[0] - point1[0]);
|
const radians = Math.PI / 2 - Math.atan2(-(point2[1] - point1[1]), point2[0] - point1[0]);
|
||||||
return normalizeRadians(radians);
|
return normalizeRadians(radians);
|
||||||
}
|
}
|
||||||
const buildTranslationMatrix = (x, y) => [[1, 0, x], [0, 1, y], [0, 0, 1]];
|
|
||||||
function dot(v1, v2) {
|
export const buildTranslationMatrix = (x, y) => [[1, 0, x], [0, 1, y], [0, 0, 1]];
|
||||||
|
|
||||||
|
export function dot(v1, v2) {
|
||||||
let product = 0;
|
let product = 0;
|
||||||
for (let i = 0; i < v1.length; i++) {
|
for (let i = 0; i < v1.length; i++) {
|
||||||
product += v1[i] * v2[i];
|
product += v1[i] * v2[i];
|
||||||
}
|
}
|
||||||
return product;
|
return product;
|
||||||
}
|
}
|
||||||
function getColumnFrom2DArr(arr, columnIndex) {
|
|
||||||
|
export function getColumnFrom2DArr(arr, columnIndex) {
|
||||||
const column = [];
|
const column = [];
|
||||||
for (let i = 0; i < arr.length; i++) {
|
for (let i = 0; i < arr.length; i++) {
|
||||||
column.push(arr[i][columnIndex]);
|
column.push(arr[i][columnIndex]);
|
||||||
}
|
}
|
||||||
return column;
|
return column;
|
||||||
}
|
}
|
||||||
function multiplyTransformMatrices(mat1, mat2) {
|
|
||||||
|
export function multiplyTransformMatrices(mat1, mat2) {
|
||||||
const product = [];
|
const product = [];
|
||||||
const size = mat1.length;
|
const size = mat1.length;
|
||||||
for (let row = 0; row < size; row++) {
|
for (let row = 0; row < size; row++) {
|
||||||
product.push([]);
|
product.push([]);
|
||||||
for (let col = 0; col < size; col++) {
|
for (let col = 0; col < size; col++) {
|
||||||
// @ts-ignore
|
|
||||||
product[row].push(dot(mat1[row], getColumnFrom2DArr(mat2, col)));
|
product[row].push(dot(mat1[row], getColumnFrom2DArr(mat2, col)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return product;
|
return product;
|
||||||
}
|
}
|
||||||
function buildRotationMatrix(rotation, center) {
|
|
||||||
|
export function buildRotationMatrix(rotation, center) {
|
||||||
const cosA = Math.cos(rotation);
|
const cosA = Math.cos(rotation);
|
||||||
const sinA = Math.sin(rotation);
|
const sinA = Math.sin(rotation);
|
||||||
const rotationMatrix = [[cosA, -sinA, 0], [sinA, cosA, 0], [0, 0, 1]];
|
const rotationMatrix = [[cosA, -sinA, 0], [sinA, cosA, 0], [0, 0, 1]];
|
||||||
|
@ -41,7 +46,8 @@ function buildRotationMatrix(rotation, center) {
|
||||||
const negativeTranslationMatrix = buildTranslationMatrix(-center[0], -center[1]);
|
const negativeTranslationMatrix = buildTranslationMatrix(-center[0], -center[1]);
|
||||||
return multiplyTransformMatrices(translationTimesRotation, negativeTranslationMatrix);
|
return multiplyTransformMatrices(translationTimesRotation, negativeTranslationMatrix);
|
||||||
}
|
}
|
||||||
function invertTransformMatrix(matrix) {
|
|
||||||
|
export function invertTransformMatrix(matrix) {
|
||||||
const rotationComponent = [[matrix[0][0], matrix[1][0]], [matrix[0][1], matrix[1][1]]];
|
const rotationComponent = [[matrix[0][0], matrix[1][0]], [matrix[0][1], matrix[1][1]]];
|
||||||
const translationComponent = [matrix[0][2], matrix[1][2]];
|
const translationComponent = [matrix[0][2], matrix[1][2]];
|
||||||
const invertedTranslation = [
|
const invertedTranslation = [
|
||||||
|
@ -54,18 +60,10 @@ function invertTransformMatrix(matrix) {
|
||||||
[0, 0, 1],
|
[0, 0, 1],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
function rotatePoint(homogeneousCoordinate, rotationMatrix) {
|
|
||||||
|
export function rotatePoint(homogeneousCoordinate, rotationMatrix) {
|
||||||
return [
|
return [
|
||||||
dot(homogeneousCoordinate, rotationMatrix[0]),
|
dot(homogeneousCoordinate, rotationMatrix[0]),
|
||||||
dot(homogeneousCoordinate, rotationMatrix[1]),
|
dot(homogeneousCoordinate, rotationMatrix[1]),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
export {
|
|
||||||
buildRotationMatrix,
|
|
||||||
computeRotation,
|
|
||||||
dot,
|
|
||||||
getColumnFrom2DArr,
|
|
||||||
invertTransformMatrix,
|
|
||||||
normalizeRadians,
|
|
||||||
rotatePoint,
|
|
||||||
};
|
|
|
@ -1,25 +1,26 @@
|
||||||
import { log } from './log.js';
|
import { log } from './log';
|
||||||
import * as tf from '../dist/tfjs.esm.js';
|
import * as tf from '../dist/tfjs.esm.js';
|
||||||
import * as backend from './tfjs/backend.js';
|
import * as backend from './tfjs/backend';
|
||||||
import * as facemesh from './blazeface/facemesh.js';
|
import * as facemesh from './blazeface/facemesh';
|
||||||
import * as faceboxes from './faceboxes/faceboxes.js';
|
import * as faceboxes from './faceboxes/faceboxes';
|
||||||
import * as age from './age/age.js';
|
import * as age from './age/age';
|
||||||
import * as gender from './gender/gender.js';
|
import * as gender from './gender/gender';
|
||||||
import * as emotion from './emotion/emotion.js';
|
import * as emotion from './emotion/emotion';
|
||||||
import * as embedding from './embedding/embedding.js';
|
import * as embedding from './embedding/embedding';
|
||||||
import * as posenet from './posenet/posenet.js';
|
import * as posenet from './posenet/posenet';
|
||||||
import * as handpose from './handpose/handpose.js';
|
import * as handpose from './handpose/handpose';
|
||||||
import * as gesture from './gesture/gesture.js';
|
import * as gesture from './gesture/gesture';
|
||||||
import * as image from './image.js';
|
import * as image from './image';
|
||||||
import * as profile from './profile.js';
|
import * as profile from './profile';
|
||||||
import * as config from '../config.js';
|
import * as config from '../config';
|
||||||
import * as sample from './sample.js';
|
import * as sample from './sample';
|
||||||
import * as app from '../package.json';
|
import * as app from '../package.json';
|
||||||
|
import { NodeFileSystem } from '@tensorflow/tfjs-node/dist/io/file_system';
|
||||||
|
|
||||||
// helper function: gets elapsed time on both browser and nodejs
|
// helper function: gets elapsed time on both browser and nodejs
|
||||||
const now = () => {
|
const now = () => {
|
||||||
if (typeof performance !== 'undefined') return performance.now();
|
if (typeof performance !== 'undefined') return performance.now();
|
||||||
return parseInt(Number(process.hrtime.bigint()) / 1000 / 1000);
|
return parseInt((Number(process.hrtime.bigint()) / 1000 / 1000).toString());
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper function: perform deep merge of multiple objects so it allows full inheriance with overrides
|
// helper function: perform deep merge of multiple objects so it allows full inheriance with overrides
|
||||||
|
@ -42,6 +43,25 @@ function mergeDeep(...objects) {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Human {
|
class Human {
|
||||||
|
tf: any;
|
||||||
|
version: string;
|
||||||
|
config: any;
|
||||||
|
fx: any;
|
||||||
|
state: string;
|
||||||
|
numTensors: number;
|
||||||
|
analyzeMemoryLeaks: boolean;
|
||||||
|
checkSanity: boolean;
|
||||||
|
firstRun: boolean;
|
||||||
|
perf: any;
|
||||||
|
models: any;
|
||||||
|
// models
|
||||||
|
facemesh: any;
|
||||||
|
age: any;
|
||||||
|
gender: any;
|
||||||
|
emotion: any;
|
||||||
|
body: any;
|
||||||
|
hand: any;
|
||||||
|
|
||||||
constructor(userConfig = {}) {
|
constructor(userConfig = {}) {
|
||||||
this.tf = tf;
|
this.tf = tf;
|
||||||
this.version = app.version;
|
this.version = app.version;
|
||||||
|
@ -108,7 +128,7 @@ class Human {
|
||||||
}
|
}
|
||||||
|
|
||||||
// preload models, not explicitly required as it's done automatically on first use
|
// preload models, not explicitly required as it's done automatically on first use
|
||||||
async load(userConfig) {
|
async load(userConfig = null) {
|
||||||
this.state = 'load';
|
this.state = 'load';
|
||||||
const timeStamp = now();
|
const timeStamp = now();
|
||||||
if (userConfig) this.config = mergeDeep(this.config, userConfig);
|
if (userConfig) this.config = mergeDeep(this.config, userConfig);
|
||||||
|
@ -160,7 +180,7 @@ class Human {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if backend needs initialization if it changed
|
// check if backend needs initialization if it changed
|
||||||
async checkBackend(force) {
|
async checkBackend(force = false) {
|
||||||
if (this.config.backend && (this.config.backend !== '') && force || (tf.getBackend() !== this.config.backend)) {
|
if (this.config.backend && (this.config.backend !== '') && force || (tf.getBackend() !== this.config.backend)) {
|
||||||
const timeStamp = now();
|
const timeStamp = now();
|
||||||
this.state = 'backend';
|
this.state = 'backend';
|
||||||
|
@ -308,7 +328,7 @@ class Human {
|
||||||
emotion: emotionRes,
|
emotion: emotionRes,
|
||||||
embedding: embeddingRes,
|
embedding: embeddingRes,
|
||||||
iris: (irisSize !== 0) ? Math.trunc(irisSize) / 100 : 0,
|
iris: (irisSize !== 0) ? Math.trunc(irisSize) / 100 : 0,
|
||||||
image: face.image.toInt().squeeze(),
|
// image: face.image.toInt().squeeze(),
|
||||||
});
|
});
|
||||||
|
|
||||||
// dont need face anymore
|
// dont need face anymore
|
||||||
|
@ -487,7 +507,8 @@ class Human {
|
||||||
async warmupNode() {
|
async warmupNode() {
|
||||||
const atob = (str) => Buffer.from(str, 'base64');
|
const atob = (str) => Buffer.from(str, 'base64');
|
||||||
const img = this.config.warmup === 'face' ? atob(sample.face) : atob(sample.body);
|
const img = this.config.warmup === 'face' ? atob(sample.face) : atob(sample.body);
|
||||||
const data = tf.node.decodeJpeg(img);
|
// @ts-ignore
|
||||||
|
const data = tf.node.decodeJpeg(img); // tf.node is only defined when compiling for nodejs
|
||||||
const expanded = data.expandDims(0);
|
const expanded = data.expandDims(0);
|
||||||
tf.dispose(data);
|
tf.dispose(data);
|
||||||
// log('Input:', expanded);
|
// log('Input:', expanded);
|
|
@ -1,6 +1,6 @@
|
||||||
import { log } from './log.js';
|
import { log } from './log';
|
||||||
import * as tf from '../dist/tfjs.esm.js';
|
import * as tf from '../dist/tfjs.esm.js';
|
||||||
import * as fxImage from './imagefx.js';
|
import * as fxImage from './imagefx';
|
||||||
|
|
||||||
// internal temp canvases
|
// internal temp canvases
|
||||||
let inCanvas = null;
|
let inCanvas = null;
|
||||||
|
@ -9,7 +9,7 @@ let outCanvas = null;
|
||||||
// process input image and return tensor
|
// process input image and return tensor
|
||||||
// input can be tensor, imagedata, htmlimageelement, htmlvideoelement
|
// input can be tensor, imagedata, htmlimageelement, htmlvideoelement
|
||||||
// input is resized and run through imagefx filter
|
// input is resized and run through imagefx filter
|
||||||
function process(input, config) {
|
export function process(input, config) {
|
||||||
let tensor;
|
let tensor;
|
||||||
if (input instanceof tf.Tensor) {
|
if (input instanceof tf.Tensor) {
|
||||||
tensor = tf.clone(input);
|
tensor = tf.clone(input);
|
||||||
|
@ -39,7 +39,7 @@ function process(input, config) {
|
||||||
outCanvas = (typeof OffscreenCanvas !== 'undefined') ? new OffscreenCanvas(inCanvas.width, inCanvas.height) : document.createElement('canvas');
|
outCanvas = (typeof OffscreenCanvas !== 'undefined') ? new OffscreenCanvas(inCanvas.width, inCanvas.height) : document.createElement('canvas');
|
||||||
if (outCanvas.width !== inCanvas.width) outCanvas.width = inCanvas.width;
|
if (outCanvas.width !== inCanvas.width) outCanvas.width = inCanvas.width;
|
||||||
if (outCanvas.height !== inCanvas.height) outCanvas.height = inCanvas.height;
|
if (outCanvas.height !== inCanvas.height) outCanvas.height = inCanvas.height;
|
||||||
this.fx = tf.ENV.flags.IS_BROWSER ? new fxImage.Canvas({ canvas: outCanvas }) : null; // && (typeof document !== 'undefined')
|
this.fx = tf.ENV.flags.IS_BROWSER ? new fxImage.GLImageFilter({ canvas: outCanvas }) : null; // && (typeof document !== 'undefined')
|
||||||
}
|
}
|
||||||
if (!this.fx) return inCanvas;
|
if (!this.fx) return inCanvas;
|
||||||
this.fx.reset();
|
this.fx.reset();
|
||||||
|
@ -106,5 +106,3 @@ function process(input, config) {
|
||||||
}
|
}
|
||||||
return { tensor, canvas: config.filter.return ? outCanvas : null };
|
return { tensor, canvas: config.filter.return ? outCanvas : null };
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.process = process;
|
|
|
@ -5,7 +5,7 @@ WebGLImageFilter - MIT Licensed
|
||||||
<https://github.com/phoboslab/WebGLImageFilter>
|
<https://github.com/phoboslab/WebGLImageFilter>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const WebGLProgram = function (gl, vertexSource, fragmentSource) {
|
const GLProgram = function (gl, vertexSource, fragmentSource) {
|
||||||
const _collect = function (source, prefix, collection) {
|
const _collect = function (source, prefix, collection) {
|
||||||
const r = new RegExp('\\b' + prefix + ' \\w+ (\\w+)', 'ig');
|
const r = new RegExp('\\b' + prefix + ' \\w+ (\\w+)', 'ig');
|
||||||
source.replace(r, (match, name) => {
|
source.replace(r, (match, name) => {
|
||||||
|
@ -58,7 +58,7 @@ const WebGLProgram = function (gl, vertexSource, fragmentSource) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const WebGLImageFilter = function (params) {
|
const GLImageFilter = function (params) {
|
||||||
if (!params) params = { };
|
if (!params) params = { };
|
||||||
let _drawCount = 0;
|
let _drawCount = 0;
|
||||||
let _sourceTexture = null;
|
let _sourceTexture = null;
|
||||||
|
@ -180,7 +180,7 @@ const WebGLImageFilter = function (params) {
|
||||||
return { fbo, texture };
|
return { fbo, texture };
|
||||||
};
|
};
|
||||||
|
|
||||||
const _draw = function (flags) {
|
const _draw = function (flags = null) {
|
||||||
let source = null;
|
let source = null;
|
||||||
let target = null;
|
let target = null;
|
||||||
let flipY = false;
|
let flipY = false;
|
||||||
|
@ -225,7 +225,7 @@ const WebGLImageFilter = function (params) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile shaders
|
// Compile shaders
|
||||||
_currentProgram = new WebGLProgram(gl, SHADER.VERTEX_IDENTITY, fragmentSource);
|
_currentProgram = new GLProgram(gl, SHADER.VERTEX_IDENTITY, fragmentSource);
|
||||||
|
|
||||||
const floatSize = Float32Array.BYTES_PER_ELEMENT;
|
const floatSize = Float32Array.BYTES_PER_ELEMENT;
|
||||||
const vertSize = 4 * floatSize;
|
const vertSize = 4 * floatSize;
|
||||||
|
@ -606,4 +606,4 @@ const WebGLImageFilter = function (params) {
|
||||||
].join('\n');
|
].join('\n');
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.Canvas = WebGLImageFilter;
|
exports.GLImageFilter = GLImageFilter;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const console = require('console');
|
const console = require('console');
|
||||||
const tf = require('@tensorflow/tfjs-node');
|
const tf = require('@tensorflow/tfjs-node');
|
||||||
const Human = require('..').default; // this resolves to project root which is '@vladmandic/human'
|
const Human = require('../dist/human.node').default; // this resolves to project root which is '@vladmandic/human'
|
||||||
|
|
||||||
const logger = new console.Console({
|
const logger = new console.Console({
|
||||||
stdout: process.stdout,
|
stdout: process.stdout,
|
||||||
|
|
|
@ -19,7 +19,7 @@ function scoreIsMaximumInLocalWindow(keypointId, score, heatmapY, heatmapX, loca
|
||||||
return localMaximum;
|
return localMaximum;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildPartWithScoreQueue(scoreThreshold, localMaximumRadius, scores) {
|
export function buildPartWithScoreQueue(scoreThreshold, localMaximumRadius, scores) {
|
||||||
const [height, width, numKeypoints] = scores.shape;
|
const [height, width, numKeypoints] = scores.shape;
|
||||||
const queue = new heapSort.MaxHeap(height * width * numKeypoints, ({ score }) => score);
|
const queue = new heapSort.MaxHeap(height * width * numKeypoints, ({ score }) => score);
|
||||||
for (let heatmapY = 0; heatmapY < height; ++heatmapY) {
|
for (let heatmapY = 0; heatmapY < height; ++heatmapY) {
|
||||||
|
@ -37,4 +37,3 @@ function buildPartWithScoreQueue(scoreThreshold, localMaximumRadius, scores) {
|
||||||
}
|
}
|
||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
exports.buildPartWithScoreQueue = buildPartWithScoreQueue;
|
|
|
@ -7,7 +7,6 @@ const kLocalMaximumRadius = 1;
|
||||||
function withinNmsRadiusOfCorrespondingPoint(poses, squaredNmsRadius, { x, y }, keypointId) {
|
function withinNmsRadiusOfCorrespondingPoint(poses, squaredNmsRadius, { x, y }, keypointId) {
|
||||||
return poses.some(({ keypoints }) => {
|
return poses.some(({ keypoints }) => {
|
||||||
const correspondingKeypoint = keypoints[keypointId].position;
|
const correspondingKeypoint = keypoints[keypointId].position;
|
||||||
// @ts-ignore
|
|
||||||
return vectors.squaredDistance(y, x, correspondingKeypoint.y, correspondingKeypoint.x) <= squaredNmsRadius;
|
return vectors.squaredDistance(y, x, correspondingKeypoint.y, correspondingKeypoint.x) <= squaredNmsRadius;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -20,9 +19,8 @@ function getInstanceScore(existingPoses, squaredNmsRadius, instanceKeypoints) {
|
||||||
return notOverlappedKeypointScores / instanceKeypoints.length;
|
return notOverlappedKeypointScores / instanceKeypoints.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
function decodeMultiplePoses(scoresBuffer, offsetsBuffer, displacementsFwdBuffer, displacementsBwdBuffer, config) {
|
export function decodeMultiplePoses(scoresBuffer, offsetsBuffer, displacementsFwdBuffer, displacementsBwdBuffer, config) {
|
||||||
const poses = [];
|
const poses = [];
|
||||||
// @ts-ignore
|
|
||||||
const queue = buildParts.buildPartWithScoreQueue(config.body.scoreThreshold, kLocalMaximumRadius, scoresBuffer);
|
const queue = buildParts.buildPartWithScoreQueue(config.body.scoreThreshold, kLocalMaximumRadius, scoresBuffer);
|
||||||
const squaredNmsRadius = config.body.nmsRadius ^ 2;
|
const squaredNmsRadius = config.body.nmsRadius ^ 2;
|
||||||
// Generate at most maxDetections object instances per image in decreasing root part score order.
|
// Generate at most maxDetections object instances per image in decreasing root part score order.
|
||||||
|
@ -30,15 +28,12 @@ function decodeMultiplePoses(scoresBuffer, offsetsBuffer, displacementsFwdBuffer
|
||||||
// The top element in the queue is the next root candidate.
|
// The top element in the queue is the next root candidate.
|
||||||
const root = queue.dequeue();
|
const root = queue.dequeue();
|
||||||
// Part-based non-maximum suppression: We reject a root candidate if it is within a disk of `nmsRadius` pixels from the corresponding part of a previously detected instance.
|
// Part-based non-maximum suppression: We reject a root candidate if it is within a disk of `nmsRadius` pixels from the corresponding part of a previously detected instance.
|
||||||
// @ts-ignore
|
|
||||||
const rootImageCoords = vectors.getImageCoords(root.part, config.body.outputStride, offsetsBuffer);
|
const rootImageCoords = vectors.getImageCoords(root.part, config.body.outputStride, offsetsBuffer);
|
||||||
if (withinNmsRadiusOfCorrespondingPoint(poses, squaredNmsRadius, rootImageCoords, root.part.id)) continue;
|
if (withinNmsRadiusOfCorrespondingPoint(poses, squaredNmsRadius, rootImageCoords, root.part.id)) continue;
|
||||||
// Else start a new detection instance at the position of the root.
|
// Else start a new detection instance at the position of the root.
|
||||||
// @ts-ignore
|
|
||||||
const keypoints = decodePose.decodePose(root, scoresBuffer, offsetsBuffer, config.body.outputStride, displacementsFwdBuffer, displacementsBwdBuffer);
|
const keypoints = decodePose.decodePose(root, scoresBuffer, offsetsBuffer, config.body.outputStride, displacementsFwdBuffer, displacementsBwdBuffer);
|
||||||
const score = getInstanceScore(poses, squaredNmsRadius, keypoints);
|
const score = getInstanceScore(poses, squaredNmsRadius, keypoints);
|
||||||
if (score > config.body.scoreThreshold) poses.push({ keypoints, score });
|
if (score > config.body.scoreThreshold) poses.push({ keypoints, score });
|
||||||
}
|
}
|
||||||
return poses;
|
return poses;
|
||||||
}
|
}
|
||||||
exports.decodeMultiplePoses = decodeMultiplePoses;
|
|
|
@ -14,9 +14,7 @@ function getDisplacement(edgeId, point, displacements) {
|
||||||
}
|
}
|
||||||
function getStridedIndexNearPoint(point, outputStride, height, width) {
|
function getStridedIndexNearPoint(point, outputStride, height, width) {
|
||||||
return {
|
return {
|
||||||
// @ts-ignore
|
|
||||||
y: vectors.clamp(Math.round(point.y / outputStride), 0, height - 1),
|
y: vectors.clamp(Math.round(point.y / outputStride), 0, height - 1),
|
||||||
// @ts-ignore
|
|
||||||
x: vectors.clamp(Math.round(point.x / outputStride), 0, width - 1),
|
x: vectors.clamp(Math.round(point.x / outputStride), 0, width - 1),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -26,14 +24,11 @@ function traverseToTargetKeypoint(edgeId, sourceKeypoint, targetKeypointId, scor
|
||||||
// Nearest neighbor interpolation for the source->target displacements.
|
// Nearest neighbor interpolation for the source->target displacements.
|
||||||
const sourceKeypointIndices = getStridedIndexNearPoint(sourceKeypoint.position, outputStride, height, width);
|
const sourceKeypointIndices = getStridedIndexNearPoint(sourceKeypoint.position, outputStride, height, width);
|
||||||
const displacement = getDisplacement(edgeId, sourceKeypointIndices, displacements);
|
const displacement = getDisplacement(edgeId, sourceKeypointIndices, displacements);
|
||||||
// @ts-ignore
|
|
||||||
const displacedPoint = vectors.addVectors(sourceKeypoint.position, displacement);
|
const displacedPoint = vectors.addVectors(sourceKeypoint.position, displacement);
|
||||||
let targetKeypoint = displacedPoint;
|
let targetKeypoint = displacedPoint;
|
||||||
for (let i = 0; i < offsetRefineStep; i++) {
|
for (let i = 0; i < offsetRefineStep; i++) {
|
||||||
const targetKeypointIndices = getStridedIndexNearPoint(targetKeypoint, outputStride, height, width);
|
const targetKeypointIndices = getStridedIndexNearPoint(targetKeypoint, outputStride, height, width);
|
||||||
// @ts-ignore
|
|
||||||
const offsetPoint = vectors.getOffsetPoint(targetKeypointIndices.y, targetKeypointIndices.x, targetKeypointId, offsets);
|
const offsetPoint = vectors.getOffsetPoint(targetKeypointIndices.y, targetKeypointIndices.x, targetKeypointId, offsets);
|
||||||
// @ts-ignore
|
|
||||||
targetKeypoint = vectors.addVectors({
|
targetKeypoint = vectors.addVectors({
|
||||||
x: targetKeypointIndices.x * outputStride,
|
x: targetKeypointIndices.x * outputStride,
|
||||||
y: targetKeypointIndices.y * outputStride,
|
y: targetKeypointIndices.y * outputStride,
|
||||||
|
@ -44,13 +39,12 @@ function traverseToTargetKeypoint(edgeId, sourceKeypoint, targetKeypointId, scor
|
||||||
return { position: targetKeypoint, part: keypoints.partNames[targetKeypointId], score };
|
return { position: targetKeypoint, part: keypoints.partNames[targetKeypointId], score };
|
||||||
}
|
}
|
||||||
|
|
||||||
function decodePose(root, scores, offsets, outputStride, displacementsFwd, displacementsBwd) {
|
export function decodePose(root, scores, offsets, outputStride, displacementsFwd, displacementsBwd) {
|
||||||
const numParts = scores.shape[2];
|
const numParts = scores.shape[2];
|
||||||
const numEdges = parentToChildEdges.length;
|
const numEdges = parentToChildEdges.length;
|
||||||
const instanceKeypoints = new Array(numParts);
|
const instanceKeypoints = new Array(numParts);
|
||||||
// Start a new detection instance at the position of the root.
|
// Start a new detection instance at the position of the root.
|
||||||
const { part: rootPart, score: rootScore } = root;
|
const { part: rootPart, score: rootScore } = root;
|
||||||
// @ts-ignore
|
|
||||||
const rootPoint = vectors.getImageCoords(rootPart, outputStride, offsets);
|
const rootPoint = vectors.getImageCoords(rootPart, outputStride, offsets);
|
||||||
instanceKeypoints[rootPart.id] = {
|
instanceKeypoints[rootPart.id] = {
|
||||||
score: rootScore,
|
score: rootScore,
|
||||||
|
@ -75,20 +69,16 @@ function decodePose(root, scores, offsets, outputStride, displacementsFwd, displ
|
||||||
}
|
}
|
||||||
return instanceKeypoints;
|
return instanceKeypoints;
|
||||||
}
|
}
|
||||||
exports.decodePose = decodePose;
|
|
||||||
|
|
||||||
async function decodeSinglePose(heatmapScores, offsets, config) {
|
export async function decodeSinglePose(heatmapScores, offsets, config) {
|
||||||
let totalScore = 0.0;
|
let totalScore = 0.0;
|
||||||
// @ts-ignore
|
|
||||||
const heatmapValues = decoders.argmax2d(heatmapScores);
|
const heatmapValues = decoders.argmax2d(heatmapScores);
|
||||||
const allTensorBuffers = await Promise.all([heatmapScores.buffer(), offsets.buffer(), heatmapValues.buffer()]);
|
const allTensorBuffers = await Promise.all([heatmapScores.buffer(), offsets.buffer(), heatmapValues.buffer()]);
|
||||||
const scoresBuffer = allTensorBuffers[0];
|
const scoresBuffer = allTensorBuffers[0];
|
||||||
const offsetsBuffer = allTensorBuffers[1];
|
const offsetsBuffer = allTensorBuffers[1];
|
||||||
const heatmapValuesBuffer = allTensorBuffers[2];
|
const heatmapValuesBuffer = allTensorBuffers[2];
|
||||||
// @ts-ignore
|
|
||||||
const offsetPoints = decoders.getOffsetPoints(heatmapValuesBuffer, config.body.outputStride, offsetsBuffer);
|
const offsetPoints = decoders.getOffsetPoints(heatmapValuesBuffer, config.body.outputStride, offsetsBuffer);
|
||||||
const offsetPointsBuffer = await offsetPoints.buffer();
|
const offsetPointsBuffer = await offsetPoints.buffer();
|
||||||
// @ts-ignore
|
|
||||||
const keypointConfidence = Array.from(decoders.getPointsConfidence(scoresBuffer, heatmapValuesBuffer));
|
const keypointConfidence = Array.from(decoders.getPointsConfidence(scoresBuffer, heatmapValuesBuffer));
|
||||||
const instanceKeypoints = keypointConfidence.map((score, i) => {
|
const instanceKeypoints = keypointConfidence.map((score, i) => {
|
||||||
totalScore += score;
|
totalScore += score;
|
||||||
|
@ -106,4 +96,3 @@ async function decodeSinglePose(heatmapScores, offsets, config) {
|
||||||
offsetPoints.dispose();
|
offsetPoints.dispose();
|
||||||
return { keypoints: filteredKeypoints, score: totalScore / instanceKeypoints.length };
|
return { keypoints: filteredKeypoints, score: totalScore / instanceKeypoints.length };
|
||||||
}
|
}
|
||||||
exports.decodeSinglePose = decodeSinglePose;
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as tf from '../../dist/tfjs.esm.js';
|
import * as tf from '../../dist/tfjs.esm.js';
|
||||||
import * as kpt from './keypoints';
|
import * as kpt from './keypoints';
|
||||||
|
|
||||||
function getPointsConfidence(heatmapScores, heatMapCoords) {
|
export function getPointsConfidence(heatmapScores, heatMapCoords) {
|
||||||
const numKeypoints = heatMapCoords.shape[0];
|
const numKeypoints = heatMapCoords.shape[0];
|
||||||
const result = new Float32Array(numKeypoints);
|
const result = new Float32Array(numKeypoints);
|
||||||
for (let keypoint = 0; keypoint < numKeypoints; keypoint++) {
|
for (let keypoint = 0; keypoint < numKeypoints; keypoint++) {
|
||||||
|
@ -11,7 +11,6 @@ function getPointsConfidence(heatmapScores, heatMapCoords) {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
exports.getPointsConfidence = getPointsConfidence;
|
|
||||||
|
|
||||||
function getOffsetPoint(y, x, keypoint, offsetsBuffer) {
|
function getOffsetPoint(y, x, keypoint, offsetsBuffer) {
|
||||||
return {
|
return {
|
||||||
|
@ -20,7 +19,7 @@ function getOffsetPoint(y, x, keypoint, offsetsBuffer) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOffsetVectors(heatMapCoordsBuffer, offsetsBuffer) {
|
export function getOffsetVectors(heatMapCoordsBuffer, offsetsBuffer) {
|
||||||
const result = [];
|
const result = [];
|
||||||
for (let keypoint = 0; keypoint < kpt.NUM_KEYPOINTS; keypoint++) {
|
for (let keypoint = 0; keypoint < kpt.NUM_KEYPOINTS; keypoint++) {
|
||||||
const heatmapY = heatMapCoordsBuffer.get(keypoint, 0).valueOf();
|
const heatmapY = heatMapCoordsBuffer.get(keypoint, 0).valueOf();
|
||||||
|
@ -31,12 +30,10 @@ function getOffsetVectors(heatMapCoordsBuffer, offsetsBuffer) {
|
||||||
}
|
}
|
||||||
return tf.tensor2d(result, [kpt.NUM_KEYPOINTS, 2]);
|
return tf.tensor2d(result, [kpt.NUM_KEYPOINTS, 2]);
|
||||||
}
|
}
|
||||||
exports.getOffsetVectors = getOffsetVectors;
|
|
||||||
|
|
||||||
function getOffsetPoints(heatMapCoordsBuffer, outputStride, offsetsBuffer) {
|
export function getOffsetPoints(heatMapCoordsBuffer, outputStride, offsetsBuffer) {
|
||||||
return tf.tidy(() => heatMapCoordsBuffer.toTensor().mul(tf.scalar(outputStride, 'int32')).toFloat().add(getOffsetVectors(heatMapCoordsBuffer, offsetsBuffer)));
|
return tf.tidy(() => heatMapCoordsBuffer.toTensor().mul(tf.scalar(outputStride, 'int32')).toFloat().add(getOffsetVectors(heatMapCoordsBuffer, offsetsBuffer)));
|
||||||
}
|
}
|
||||||
exports.getOffsetPoints = getOffsetPoints;
|
|
||||||
|
|
||||||
function mod(a, b) {
|
function mod(a, b) {
|
||||||
return tf.tidy(() => {
|
return tf.tidy(() => {
|
||||||
|
@ -45,7 +42,7 @@ function mod(a, b) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function argmax2d(inputs) {
|
export function argmax2d(inputs) {
|
||||||
const [height, width, depth] = inputs.shape;
|
const [height, width, depth] = inputs.shape;
|
||||||
return tf.tidy(() => {
|
return tf.tidy(() => {
|
||||||
const reshaped = inputs.reshape([height * width, depth]);
|
const reshaped = inputs.reshape([height * width, depth]);
|
||||||
|
@ -55,4 +52,3 @@ function argmax2d(inputs) {
|
||||||
return tf.concat([yCoords, xCoords], 1);
|
return tf.concat([yCoords, xCoords], 1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.argmax2d = argmax2d;
|
|
|
@ -2,7 +2,11 @@
|
||||||
function half(k) {
|
function half(k) {
|
||||||
return Math.floor(k / 2);
|
return Math.floor(k / 2);
|
||||||
}
|
}
|
||||||
class MaxHeap {
|
export class MaxHeap {
|
||||||
|
priorityQueue: any;
|
||||||
|
numberOfElements: number;
|
||||||
|
getElementValue: any;
|
||||||
|
|
||||||
constructor(maxSize, getElementValue) {
|
constructor(maxSize, getElementValue) {
|
||||||
this.priorityQueue = new Array(maxSize);
|
this.priorityQueue = new Array(maxSize);
|
||||||
this.numberOfElements = -1;
|
this.numberOfElements = -1;
|
||||||
|
@ -69,4 +73,3 @@ class MaxHeap {
|
||||||
this.priorityQueue[j] = t;
|
this.priorityQueue[j] = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.MaxHeap = MaxHeap;
|
|
|
@ -1,12 +1,12 @@
|
||||||
exports.partNames = [
|
export const partNames = [
|
||||||
'nose', 'leftEye', 'rightEye', 'leftEar', 'rightEar', 'leftShoulder',
|
'nose', 'leftEye', 'rightEye', 'leftEar', 'rightEar', 'leftShoulder',
|
||||||
'rightShoulder', 'leftElbow', 'rightElbow', 'leftWrist', 'rightWrist',
|
'rightShoulder', 'leftElbow', 'rightElbow', 'leftWrist', 'rightWrist',
|
||||||
'leftHip', 'rightHip', 'leftKnee', 'rightKnee', 'leftAnkle', 'rightAnkle',
|
'leftHip', 'rightHip', 'leftKnee', 'rightKnee', 'leftAnkle', 'rightAnkle',
|
||||||
];
|
];
|
||||||
|
|
||||||
exports.NUM_KEYPOINTS = exports.partNames.length;
|
export const NUM_KEYPOINTS = exports.partNames.length;
|
||||||
|
|
||||||
exports.partIds = exports.partNames.reduce((result, jointName, i) => {
|
export const partIds = exports.partNames.reduce((result, jointName, i) => {
|
||||||
result[jointName] = i;
|
result[jointName] = i;
|
||||||
return result;
|
return result;
|
||||||
}, {});
|
}, {});
|
||||||
|
@ -19,9 +19,9 @@ const connectedPartNames = [
|
||||||
['rightHip', 'rightKnee'], ['rightKnee', 'rightAnkle'],
|
['rightHip', 'rightKnee'], ['rightKnee', 'rightAnkle'],
|
||||||
['leftShoulder', 'rightShoulder'], ['leftHip', 'rightHip'],
|
['leftShoulder', 'rightShoulder'], ['leftHip', 'rightHip'],
|
||||||
];
|
];
|
||||||
exports.connectedPartIndices = connectedPartNames.map(([jointNameA, jointNameB]) => ([exports.partIds[jointNameA], exports.partIds[jointNameB]]));
|
export const connectedPartIndices = connectedPartNames.map(([jointNameA, jointNameB]) => ([partIds[jointNameA], partIds[jointNameB]]));
|
||||||
|
|
||||||
exports.poseChain = [
|
export const poseChain = [
|
||||||
['nose', 'leftEye'], ['leftEye', 'leftEar'], ['nose', 'rightEye'],
|
['nose', 'leftEye'], ['leftEye', 'leftEar'], ['nose', 'rightEye'],
|
||||||
['rightEye', 'rightEar'], ['nose', 'leftShoulder'],
|
['rightEye', 'rightEar'], ['nose', 'leftShoulder'],
|
||||||
['leftShoulder', 'leftElbow'], ['leftElbow', 'leftWrist'],
|
['leftShoulder', 'leftElbow'], ['leftElbow', 'leftWrist'],
|
||||||
|
@ -32,7 +32,7 @@ exports.poseChain = [
|
||||||
['rightKnee', 'rightAnkle'],
|
['rightKnee', 'rightAnkle'],
|
||||||
];
|
];
|
||||||
|
|
||||||
exports.partChannels = [
|
export const partChannels = [
|
||||||
'left_face',
|
'left_face',
|
||||||
'right_face',
|
'right_face',
|
||||||
'right_upper_leg_front',
|
'right_upper_leg_front',
|
|
@ -12,7 +12,8 @@ function nameOutputResultsResNet(results) {
|
||||||
return { offsets, heatmap, displacementFwd, displacementBwd };
|
return { offsets, heatmap, displacementFwd, displacementBwd };
|
||||||
}
|
}
|
||||||
|
|
||||||
class BaseModel {
|
export class BaseModel {
|
||||||
|
model: any;
|
||||||
constructor(model) {
|
constructor(model) {
|
||||||
this.model = model;
|
this.model = model;
|
||||||
}
|
}
|
||||||
|
@ -37,4 +38,3 @@ class BaseModel {
|
||||||
this.model.dispose();
|
this.model.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.BaseModel = BaseModel;
|
|
|
@ -1,4 +1,5 @@
|
||||||
class ModelWeights {
|
export class ModelWeights {
|
||||||
|
variables: any;
|
||||||
constructor(variables) {
|
constructor(variables) {
|
||||||
this.variables = variables;
|
this.variables = variables;
|
||||||
}
|
}
|
||||||
|
@ -23,4 +24,3 @@ class ModelWeights {
|
||||||
for (let i = 0; i < this.variables.length; i++) this.variables[i].dispose();
|
for (let i = 0; i < this.variables.length; i++) this.variables[i].dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.ModelWeights = ModelWeights;
|
|
|
@ -1,23 +0,0 @@
|
||||||
import * as modelPoseNet from './modelPoseNet';
|
|
||||||
import * as keypoints from './keypoints';
|
|
||||||
import * as util from './util';
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
exports.load = modelPoseNet.load;
|
|
||||||
// @ts-ignore
|
|
||||||
exports.PoseNet = modelPoseNet.PoseNet;
|
|
||||||
|
|
||||||
exports.partChannels = keypoints.partChannels;
|
|
||||||
exports.partIds = keypoints.partIds;
|
|
||||||
exports.partNames = keypoints.partNames;
|
|
||||||
exports.poseChain = keypoints.poseChain;
|
|
||||||
// @ts-ignore
|
|
||||||
exports.getAdjacentKeyPoints = util.getAdjacentKeyPoints;
|
|
||||||
// @ts-ignore
|
|
||||||
exports.getBoundingBox = util.getBoundingBox;
|
|
||||||
// @ts-ignore
|
|
||||||
exports.getBoundingBoxPoints = util.getBoundingBoxPoints;
|
|
||||||
// @ts-ignore
|
|
||||||
exports.scaleAndFlipPoses = util.scaleAndFlipPoses;
|
|
||||||
// @ts-ignore
|
|
||||||
exports.scalePose = util.scalePose;
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { log } from '../log.js';
|
import { log } from '../log';
|
||||||
import * as tf from '../../dist/tfjs.esm.js';
|
import * as tf from '../../dist/tfjs.esm.js';
|
||||||
import * as modelBase from './modelBase';
|
import * as modelBase from './modelBase';
|
||||||
import * as decodeMultiple from './decodeMultiple';
|
import * as decodeMultiple from './decodeMultiple';
|
||||||
|
@ -9,15 +9,12 @@ async function estimateMultiple(input, res, config) {
|
||||||
return new Promise(async (resolve) => {
|
return new Promise(async (resolve) => {
|
||||||
const height = input.shape[1];
|
const height = input.shape[1];
|
||||||
const width = input.shape[2];
|
const width = input.shape[2];
|
||||||
// @ts-ignore
|
|
||||||
const allTensorBuffers = await util.toTensorBuffers3D([res.heatmapScores, res.offsets, res.displacementFwd, res.displacementBwd]);
|
const allTensorBuffers = await util.toTensorBuffers3D([res.heatmapScores, res.offsets, res.displacementFwd, res.displacementBwd]);
|
||||||
const scoresBuffer = allTensorBuffers[0];
|
const scoresBuffer = allTensorBuffers[0];
|
||||||
const offsetsBuffer = allTensorBuffers[1];
|
const offsetsBuffer = allTensorBuffers[1];
|
||||||
const displacementsFwdBuffer = allTensorBuffers[2];
|
const displacementsFwdBuffer = allTensorBuffers[2];
|
||||||
const displacementsBwdBuffer = allTensorBuffers[3];
|
const displacementsBwdBuffer = allTensorBuffers[3];
|
||||||
// @ts-ignore
|
|
||||||
const poses = await decodeMultiple.decodeMultiplePoses(scoresBuffer, offsetsBuffer, displacementsFwdBuffer, displacementsBwdBuffer, config);
|
const poses = await decodeMultiple.decodeMultiplePoses(scoresBuffer, offsetsBuffer, displacementsFwdBuffer, displacementsBwdBuffer, config);
|
||||||
// @ts-ignore
|
|
||||||
const scaled = util.scaleAndFlipPoses(poses, [height, width], [config.body.inputSize, config.body.inputSize]);
|
const scaled = util.scaleAndFlipPoses(poses, [height, width], [config.body.inputSize, config.body.inputSize]);
|
||||||
resolve(scaled);
|
resolve(scaled);
|
||||||
});
|
});
|
||||||
|
@ -27,22 +24,20 @@ async function estimateSingle(input, res, config) {
|
||||||
return new Promise(async (resolve) => {
|
return new Promise(async (resolve) => {
|
||||||
const height = input.shape[1];
|
const height = input.shape[1];
|
||||||
const width = input.shape[2];
|
const width = input.shape[2];
|
||||||
// @ts-ignore
|
|
||||||
const pose = await decodePose.decodeSinglePose(res.heatmapScores, res.offsets, config);
|
const pose = await decodePose.decodeSinglePose(res.heatmapScores, res.offsets, config);
|
||||||
const poses = [pose];
|
const poses = [pose];
|
||||||
// @ts-ignore
|
|
||||||
const scaled = util.scaleAndFlipPoses(poses, [height, width], [config.body.inputSize, config.body.inputSize]);
|
const scaled = util.scaleAndFlipPoses(poses, [height, width], [config.body.inputSize, config.body.inputSize]);
|
||||||
resolve(scaled);
|
resolve(scaled);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class PoseNet {
|
export class PoseNet {
|
||||||
|
baseModel: any;
|
||||||
constructor(model) {
|
constructor(model) {
|
||||||
this.baseModel = model;
|
this.baseModel = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
async estimatePoses(input, config) {
|
async estimatePoses(input, config) {
|
||||||
// @ts-ignore
|
|
||||||
const resized = util.resizeTo(input, [config.body.inputSize, config.body.inputSize]);
|
const resized = util.resizeTo(input, [config.body.inputSize, config.body.inputSize]);
|
||||||
const res = this.baseModel.predict(resized, config);
|
const res = this.baseModel.predict(resized, config);
|
||||||
|
|
||||||
|
@ -61,13 +56,10 @@ class PoseNet {
|
||||||
this.baseModel.dispose();
|
this.baseModel.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.PoseNet = PoseNet;
|
|
||||||
|
|
||||||
async function load(config) {
|
export async function load(config) {
|
||||||
const model = await tf.loadGraphModel(config.body.modelPath);
|
const model = await tf.loadGraphModel(config.body.modelPath);
|
||||||
// @ts-ignore
|
|
||||||
const mobilenet = new modelBase.BaseModel(model);
|
const mobilenet = new modelBase.BaseModel(model);
|
||||||
log(`load model: ${config.body.modelPath.match(/\/(.*)\./)[1]}`);
|
log(`load model: ${config.body.modelPath.match(/\/(.*)\./)[1]}`);
|
||||||
return new PoseNet(mobilenet);
|
return new PoseNet(mobilenet);
|
||||||
}
|
}
|
||||||
exports.load = load;
|
|
|
@ -1,10 +1,10 @@
|
||||||
import * as kpt from './keypoints';
|
import * as kpt from './keypoints';
|
||||||
|
|
||||||
function eitherPointDoesntMeetConfidence(a, b, minConfidence) {
|
export function eitherPointDoesntMeetConfidence(a, b, minConfidence) {
|
||||||
return (a < minConfidence || b < minConfidence);
|
return (a < minConfidence || b < minConfidence);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAdjacentKeyPoints(keypoints, minConfidence) {
|
export function getAdjacentKeyPoints(keypoints, minConfidence) {
|
||||||
return kpt.connectedPartIndices.reduce((result, [leftJoint, rightJoint]) => {
|
return kpt.connectedPartIndices.reduce((result, [leftJoint, rightJoint]) => {
|
||||||
if (eitherPointDoesntMeetConfidence(keypoints[leftJoint].score, keypoints[rightJoint].score, minConfidence)) {
|
if (eitherPointDoesntMeetConfidence(keypoints[leftJoint].score, keypoints[rightJoint].score, minConfidence)) {
|
||||||
return result;
|
return result;
|
||||||
|
@ -13,10 +13,9 @@ function getAdjacentKeyPoints(keypoints, minConfidence) {
|
||||||
return result;
|
return result;
|
||||||
}, []);
|
}, []);
|
||||||
}
|
}
|
||||||
exports.getAdjacentKeyPoints = getAdjacentKeyPoints;
|
|
||||||
|
|
||||||
const { NEGATIVE_INFINITY, POSITIVE_INFINITY } = Number;
|
const { NEGATIVE_INFINITY, POSITIVE_INFINITY } = Number;
|
||||||
function getBoundingBox(keypoints) {
|
export function getBoundingBox(keypoints) {
|
||||||
return keypoints.reduce(({ maxX, maxY, minX, minY }, { position: { x, y } }) => ({
|
return keypoints.reduce(({ maxX, maxY, minX, minY }, { position: { x, y } }) => ({
|
||||||
maxX: Math.max(maxX, x),
|
maxX: Math.max(maxX, x),
|
||||||
maxY: Math.max(maxY, y),
|
maxY: Math.max(maxY, y),
|
||||||
|
@ -29,20 +28,17 @@ function getBoundingBox(keypoints) {
|
||||||
minY: POSITIVE_INFINITY,
|
minY: POSITIVE_INFINITY,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.getBoundingBox = getBoundingBox;
|
|
||||||
|
|
||||||
function getBoundingBoxPoints(keypoints) {
|
export function getBoundingBoxPoints(keypoints) {
|
||||||
const { minX, minY, maxX, maxY } = getBoundingBox(keypoints);
|
const { minX, minY, maxX, maxY } = getBoundingBox(keypoints);
|
||||||
return [{ x: minX, y: minY }, { x: maxX, y: minY }, { x: maxX, y: maxY }, { x: minX, y: maxY }];
|
return [{ x: minX, y: minY }, { x: maxX, y: minY }, { x: maxX, y: maxY }, { x: minX, y: maxY }];
|
||||||
}
|
}
|
||||||
exports.getBoundingBoxPoints = getBoundingBoxPoints;
|
|
||||||
|
|
||||||
async function toTensorBuffers3D(tensors) {
|
export async function toTensorBuffers3D(tensors) {
|
||||||
return Promise.all(tensors.map((tensor) => tensor.buffer()));
|
return Promise.all(tensors.map((tensor) => tensor.buffer()));
|
||||||
}
|
}
|
||||||
exports.toTensorBuffers3D = toTensorBuffers3D;
|
|
||||||
|
|
||||||
function scalePose(pose, scaleY, scaleX) {
|
export function scalePose(pose, scaleY, scaleX) {
|
||||||
return {
|
return {
|
||||||
score: pose.score,
|
score: pose.score,
|
||||||
keypoints: pose.keypoints.map(({ score, part, position }) => ({
|
keypoints: pose.keypoints.map(({ score, part, position }) => ({
|
||||||
|
@ -52,18 +48,15 @@ function scalePose(pose, scaleY, scaleX) {
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
exports.scalePose = scalePose;
|
|
||||||
|
|
||||||
function resizeTo(image, [targetH, targetW]) {
|
export function resizeTo(image, [targetH, targetW]) {
|
||||||
const input = image.squeeze(0);
|
const input = image.squeeze(0);
|
||||||
const resized = input.resizeBilinear([targetH, targetW]);
|
const resized = input.resizeBilinear([targetH, targetW]);
|
||||||
input.dispose();
|
input.dispose();
|
||||||
return resized;
|
return resized;
|
||||||
}
|
}
|
||||||
exports.resizeTo = resizeTo;
|
|
||||||
|
|
||||||
function scaleAndFlipPoses(poses, [height, width], [inputResolutionHeight, inputResolutionWidth]) {
|
export function scaleAndFlipPoses(poses, [height, width], [inputResolutionHeight, inputResolutionWidth]) {
|
||||||
const scaledPoses = poses.map((pose) => scalePose(pose, height / inputResolutionHeight, width / inputResolutionWidth));
|
const scaledPoses = poses.map((pose) => scalePose(pose, height / inputResolutionHeight, width / inputResolutionWidth));
|
||||||
return scaledPoses;
|
return scaledPoses;
|
||||||
}
|
}
|
||||||
exports.scaleAndFlipPoses = scaleAndFlipPoses;
|
|
|
@ -1,14 +1,13 @@
|
||||||
import * as kpt from './keypoints';
|
import * as kpt from './keypoints';
|
||||||
|
|
||||||
function getOffsetPoint(y, x, keypoint, offsets) {
|
export function getOffsetPoint(y, x, keypoint, offsets) {
|
||||||
return {
|
return {
|
||||||
y: offsets.get(y, x, keypoint),
|
y: offsets.get(y, x, keypoint),
|
||||||
x: offsets.get(y, x, keypoint + kpt.NUM_KEYPOINTS),
|
x: offsets.get(y, x, keypoint + kpt.NUM_KEYPOINTS),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
exports.getOffsetPoint = getOffsetPoint;
|
|
||||||
|
|
||||||
function getImageCoords(part, outputStride, offsets) {
|
export function getImageCoords(part, outputStride, offsets) {
|
||||||
const { heatmapY, heatmapX, id: keypoint } = part;
|
const { heatmapY, heatmapX, id: keypoint } = part;
|
||||||
const { y, x } = getOffsetPoint(heatmapY, heatmapX, keypoint, offsets);
|
const { y, x } = getOffsetPoint(heatmapY, heatmapX, keypoint, offsets);
|
||||||
return {
|
return {
|
||||||
|
@ -16,37 +15,31 @@ function getImageCoords(part, outputStride, offsets) {
|
||||||
y: part.heatmapY * outputStride + y,
|
y: part.heatmapY * outputStride + y,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
exports.getImageCoords = getImageCoords;
|
|
||||||
|
|
||||||
function fillArray(element, size) {
|
export function fillArray(element, size) {
|
||||||
const result = new Array(size);
|
const result = new Array(size);
|
||||||
for (let i = 0; i < size; i++) {
|
for (let i = 0; i < size; i++) {
|
||||||
result[i] = element;
|
result[i] = element;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
exports.fillArray = fillArray;
|
|
||||||
|
|
||||||
function clamp(a, min, max) {
|
export function clamp(a, min, max) {
|
||||||
if (a < min) return min;
|
if (a < min) return min;
|
||||||
if (a > max) return max;
|
if (a > max) return max;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
exports.clamp = clamp;
|
|
||||||
|
|
||||||
function squaredDistance(y1, x1, y2, x2) {
|
export function squaredDistance(y1, x1, y2, x2) {
|
||||||
const dy = y2 - y1;
|
const dy = y2 - y1;
|
||||||
const dx = x2 - x1;
|
const dx = x2 - x1;
|
||||||
return dy * dy + dx * dx;
|
return dy * dy + dx * dx;
|
||||||
}
|
}
|
||||||
exports.squaredDistance = squaredDistance;
|
|
||||||
|
|
||||||
function addVectors(a, b) {
|
export function addVectors(a, b) {
|
||||||
return { x: a.x + b.x, y: a.y + b.y };
|
return { x: a.x + b.x, y: a.y + b.y };
|
||||||
}
|
}
|
||||||
exports.addVectors = addVectors;
|
|
||||||
|
|
||||||
function clampVector(a, min, max) {
|
export function clampVector(a, min, max) {
|
||||||
return { y: clamp(a.y, min, max), x: clamp(a.x, min, max) };
|
return { y: clamp(a.y, min, max), x: clamp(a.x, min, max) };
|
||||||
}
|
}
|
||||||
exports.clampVector = clampVector;
|
|
|
@ -1,26 +1,24 @@
|
||||||
import { log } from './log.js';
|
import { log } from './log';
|
||||||
|
|
||||||
const profileData = {};
|
export const data = {};
|
||||||
|
|
||||||
function profile(name, data) {
|
export function run(name, raw) {
|
||||||
if (!data || !data.kernels) return;
|
if (!raw || !raw.kernels) return;
|
||||||
const maxResults = 5;
|
const maxResults = 5;
|
||||||
const time = data.kernels
|
const time = raw.kernels
|
||||||
.filter((a) => a.kernelTimeMs > 0)
|
.filter((a) => a.kernelTimeMs > 0)
|
||||||
.reduce((a, b) => a += b.kernelTimeMs, 0);
|
.reduce((a, b) => a += b.kernelTimeMs, 0);
|
||||||
const slowest = data.kernels
|
const slowest = raw.kernels
|
||||||
.map((a, i) => { a.id = i; return a; })
|
.map((a, i) => { a.id = i; return a; })
|
||||||
.filter((a) => a.kernelTimeMs > 0)
|
.filter((a) => a.kernelTimeMs > 0)
|
||||||
.sort((a, b) => b.kernelTimeMs - a.kernelTimeMs);
|
.sort((a, b) => b.kernelTimeMs - a.kernelTimeMs);
|
||||||
const largest = data.kernels
|
const largest = raw.kernels
|
||||||
.map((a, i) => { a.id = i; return a; })
|
.map((a, i) => { a.id = i; return a; })
|
||||||
.filter((a) => a.totalBytesSnapshot > 0)
|
.filter((a) => a.totalBytesSnapshot > 0)
|
||||||
.sort((a, b) => b.totalBytesSnapshot - a.totalBytesSnapshot);
|
.sort((a, b) => b.totalBytesSnapshot - a.totalBytesSnapshot);
|
||||||
if (slowest.length > maxResults) slowest.length = maxResults;
|
if (slowest.length > maxResults) slowest.length = maxResults;
|
||||||
if (largest.length > maxResults) largest.length = maxResults;
|
if (largest.length > maxResults) largest.length = maxResults;
|
||||||
const res = { newBytes: data.newBytes, newTensors: data.newTensors, peakBytes: data.peakBytes, numKernelOps: data.kernels.length, timeKernelOps: time, slowestKernelOps: slowest, largestKernelOps: largest };
|
const res = { newBytes: raw.newBytes, newTensors: raw.newTensors, peakBytes: raw.peakBytes, numKernelOps: raw.kernels.length, timeKernelOps: time, slowestKernelOps: slowest, largestKernelOps: largest };
|
||||||
profileData[name] = res;
|
data[name] = res;
|
||||||
log('Human profiler', name, res);
|
log('Human profiler', name, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.run = profile;
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { log } from '../log.js';
|
import { log } from '../log';
|
||||||
import * as tf from '../../dist/tfjs.esm.js';
|
import * as tf from '../../dist/tfjs.esm.js';
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
Loading…
Reference in New Issue