add extra face rotation prior to mesh

pull/233/head
Vladimir Mandic 2021-11-16 13:07:44 -05:00
parent 57f6262d38
commit be8b532cb9
23 changed files with 1126 additions and 1128 deletions

View File

@ -9,8 +9,9 @@
## Changelog
### **HEAD -> main** 2021/11/14 mandic00@live.com
### **release 2.5.2** 2021/11/15 mandic00@live.com
- improve error handling
### **2.5.2** 2021/11/14 mandic00@live.com

View File

@ -6,9 +6,9 @@
### Exploring
- Optical Flow: <https://docs.opencv.org/3.3.1/db/d7f/tutorial_js_lucas_kanade.html>
- Histogram Equalization: Regular, Adaptive, Contrast Limited, CLAHE
- TFLite Models: <https://js.tensorflow.org/api_tflite/0.0.1-alpha.4/>
- Optical flow: <https://docs.opencv.org/3.3.1/db/d7f/tutorial_js_lucas_kanade.html>
- Advanced histogram equalization: Adaptive, Contrast Limited, CLAHE
- TFLite models: <https://js.tensorflow.org/api_tflite/0.0.1-alpha.4/>
- Body segmentation: `robust-video-matting`
- TFJS incompatibility with latest `long.js` 5.0.0 due to CJS to ESM switch
@ -19,6 +19,7 @@
#### WebGPU
Experimental support only until support is officially added in Chromium
- Performance issues:
<https://github.com/tensorflow/tfjs/issues/5689>
@ -39,7 +40,7 @@ MoveNet MultiPose model does not work with WASM backend due to missing F32 broad
<br><hr><br>
## Pending release notes:
## Pending Release Notes
New:
- new demo `demos/faceid` that utilizes multiple algorithm to validate input before triggering face recognition

View File

@ -32,3 +32,10 @@ designed to serve as a quick check when used together with other indicators:
- Checks if input has obvious artifacts due to recording (e.g. playing back phone recording of a face)
- Configuration: `human.config.face.liveness`.enabled
- Result: `human.result.face[0].live` as score
### Models
**FaceID** is compatible with
- `faceres.json` (default) perfoms combined age/gender/descriptor analysis
- `faceres-deep.json` higher resolution variation of `faceres`
- `mobilefacenet` alternative model for face descriptor analysis

View File

@ -19,10 +19,12 @@ const userConfig = {
filter: {
enabled: true,
equalization: true,
width: 0,
},
face: {
enabled: true,
detector: { rotation: true, return: true, maxDetected: 50 },
// detector: { rotation: false, return: true, maxDetected: 50, iouThreshold: 0.206, minConfidence: 0.122 },
detector: { return: true, rotation: true, maxDetected: 50, iouThreshold: 0.01, minConfidence: 0.2 },
mesh: { enabled: true },
iris: { enabled: false },
emotion: { enabled: true },
@ -138,7 +140,8 @@ async function SelectFaceCanvas(face) {
async function AddFaceCanvas(index, res, fileName) {
all[index] = res.face;
for (const i in res.face) {
if (res.face[i].mesh.length === 0 || !res.face[i].tensor) continue; // did not get valid results
if (!res.face[i].tensor) continue; // did not get valid results
if ((res.face[i].faceScore || 0) < human.config.face.detector.minConfidence) continue; // face analysis score too low
all[index][i].fileName = fileName;
const canvas = document.createElement('canvas');
canvas.tag = { sample: index, face: i, source: fileName };
@ -177,9 +180,9 @@ async function AddImageElement(index, image, length) {
return new Promise((resolve) => {
const img = new Image(128, 128);
img.onload = () => { // must wait until image is loaded
document.getElementById('images').appendChild(img); // and finally we can add it
human.detect(img, userConfig).then((res) => {
AddFaceCanvas(index, res, image); // then wait until image is analyzed
document.getElementById('images').appendChild(img); // and finally we can add it
resolve(true);
});
};
@ -236,12 +239,8 @@ async function main() {
log('Discovered images:', images);
}
// images = ['/samples/in/solvay1927.jpg'];
// images = ['/samples/in/person-lexi.jpg', '/samples/in/person-carolina.jpg', '/samples/in/solvay1927.jpg'];
// download and analyze all images
// const promises = [];
// for (let i = 0; i < images.length; i++) promises.push(AddImageElement(i, images[i], images.length));
// await Promise.all(promises);
const t0 = human.now();
for (let i = 0; i < images.length; i++) await AddImageElement(i, images[i], images.length);
const t1 = human.now();

View File

@ -8,7 +8,7 @@
import { Human } from "../../dist/human.esm.js";
var humanConfig = {
modelBasePath: "../../models",
filter: { equalization: false }
filter: { equalization: true }
};
var human = new Human(humanConfig);
human.env["perfadd"] = false;

File diff suppressed because one or more lines are too long

View File

@ -11,8 +11,8 @@ import { Human } from '../../dist/human.esm.js'; // equivalent of @vladmandic/Hu
const humanConfig = { // user configuration for human, used to fine-tune behavior
modelBasePath: '../../models',
filter: { equalization: false },
// backend: 'webgpu',
filter: { equalization: true },
// backend: 'webgpu' as 'webgpu,
// async: true,
// face: { enabled: false, detector: { rotation: true }, iris: { enabled: false }, description: { enabled: false }, emotion: { enabled: false } },
// body: { enabled: false },

View File

@ -1213,7 +1213,7 @@ async function process2(input, config3, getTensor = true) {
}
async function skip(config3, input) {
let skipFrame = false;
if (config3.cacheSensitivity === 0)
if (config3.cacheSensitivity === 0 || !input.shape || input.shape.length !== 4 || input.shape[1] > 2048 || input.shape[2] > 2048)
return skipFrame;
if (!last.inputTensor) {
last.inputTensor = tfjs_esm_exports.clone(input);
@ -5027,7 +5027,6 @@ function correctFaceRotation(rotate, box4, input, inputSize8) {
// src/face/blazeface.ts
var keypointsCount = 6;
var model5;
var anchorsData = [];
var anchors = null;
var inputSize = 0;
var size = () => inputSize;
@ -5044,10 +5043,7 @@ async function load5(config3) {
} else if (config3.debug)
log("cached model:", model5["modelUrl"]);
inputSize = model5.inputs[0].shape ? model5.inputs[0].shape[2] : 0;
if (inputSize === -1)
inputSize = 64;
anchorsData = generateAnchors(inputSize);
anchors = tfjs_esm_exports.tensor2d(anchorsData);
anchors = tfjs_esm_exports.tensor2d(generateAnchors(inputSize));
return model5;
}
function decodeBounds(boxOutputs) {
@ -5101,12 +5097,11 @@ async function getBoxes(inputImage, config3) {
b.slice = tfjs_esm_exports.slice(t.batch, [nms[i], keypointsCount - 1], [1, -1]);
b.squeeze = tfjs_esm_exports.squeeze(b.slice);
b.landmarks = tfjs_esm_exports.reshape(b.squeeze, [keypointsCount, -1]);
b.startPoint = tfjs_esm_exports.slice(b.bbox, [0, 0], [-1, 2]);
b.endPoint = tfjs_esm_exports.slice(b.bbox, [0, 2], [-1, 2]);
const points = await b.bbox.data();
boxes.push({
box: {
startPoint: await b.startPoint.data(),
endPoint: await b.endPoint.data()
startPoint: [points[0], points[1]],
endPoint: [points[2], points[3]]
},
landmarks: await b.landmarks.array(),
confidence
@ -5879,7 +5874,7 @@ var inputSize5 = 0;
var skipped10 = Number.MAX_SAFE_INTEGER;
var lastTime10 = 0;
async function predict10(input, config3) {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
const skipTime = (((_a = config3.face.detector) == null ? void 0 : _a.skipTime) || 0) > now() - lastTime10;
const skipFrame = skipped10 < (((_b = config3.face.detector) == null ? void 0 : _b.skipFrames) || 0);
if (!config3.skipAllowed || !skipTime || !skipFrame || boxCache.length === 0) {
@ -5893,7 +5888,10 @@ async function predict10(input, config3) {
landmarks: possible.landmarks,
confidence: possible.confidence
};
boxCache.push(squarifyBox(enlargeBox(scaleBoxCoordinates(box4, possibleBoxes.scaleFactor), Math.sqrt(((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6))));
const boxScaled = scaleBoxCoordinates(box4, possibleBoxes.scaleFactor);
const boxEnlarged = enlargeBox(boxScaled, Math.sqrt(((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6));
const boxSquared = squarifyBox(boxEnlarged);
boxCache.push(boxSquared);
}
skipped10 = 0;
} else {
@ -5917,14 +5915,14 @@ async function predict10(input, config3) {
faceScore: 0,
annotations: {}
};
[angle, rotationMatrix, face5.tensor] = correctFaceRotation(!((_d = config3.face.mesh) == null ? void 0 : _d.enabled) && ((_e = config3.face.detector) == null ? void 0 : _e.rotation), box4, input, ((_f = config3.face.mesh) == null ? void 0 : _f.enabled) ? inputSize5 : size());
if ((_g = config3 == null ? void 0 : config3.filter) == null ? void 0 : _g.equalization) {
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_d = config3.face.detector) == null ? void 0 : _d.rotation, box4, input, ((_e = config3.face.mesh) == null ? void 0 : _e.enabled) ? inputSize5 : size());
if ((_f = config3 == null ? void 0 : config3.filter) == null ? void 0 : _f.equalization) {
const equilized = await histogramEqualization(face5.tensor);
tfjs_esm_exports.dispose(face5.tensor);
face5.tensor = equilized;
}
face5.boxScore = Math.round(100 * box4.confidence) / 100;
if (!((_h = config3.face.mesh) == null ? void 0 : _h.enabled)) {
if (!((_g = config3.face.mesh) == null ? void 0 : _g.enabled)) {
face5.box = getClampedBox(box4, input);
face5.boxRaw = getRawBox(box4, input);
face5.score = face5.boxScore;
@ -5945,22 +5943,22 @@ async function predict10(input, config3) {
const coordsReshaped = tfjs_esm_exports.reshape(contourCoords, [-1, 3]);
let rawCoords = await coordsReshaped.array();
tfjs_esm_exports.dispose([contourCoords, coordsReshaped, confidence, contours]);
if (face5.faceScore < (((_i = config3.face.detector) == null ? void 0 : _i.minConfidence) || 1)) {
if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
box4.confidence = face5.faceScore;
} else {
if ((_j = config3.face.iris) == null ? void 0 : _j.enabled)
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize5);
face5.mesh = transformRawCoords(rawCoords, box4, angle, rotationMatrix, inputSize5);
face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize5]);
for (const key of Object.keys(meshAnnotations))
face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]);
box4 = squarifyBox({ ...enlargeBox(calculateLandmarksBoundingBox(face5.mesh), ((_k = config3.face.detector) == null ? void 0 : _k.cropFactor) || 1.6), confidence: box4.confidence });
box4 = squarifyBox({ ...enlargeBox(calculateLandmarksBoundingBox(face5.mesh), ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6), confidence: box4.confidence });
face5.box = getClampedBox(box4, input);
face5.boxRaw = getRawBox(box4, input);
face5.score = face5.faceScore;
newCache.push(box4);
tfjs_esm_exports.dispose(face5.tensor);
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_l = config3.face.detector) == null ? void 0 : _l.rotation, box4, input, inputSize5);
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_k = config3.face.detector) == null ? void 0 : _k.rotation, box4, input, inputSize5);
}
}
faces.push(face5);

File diff suppressed because one or more lines are too long

39
dist/human.esm.js vendored
View File

@ -14194,7 +14194,8 @@ function intersectionOverUnion(boxes, i, j) {
const intersectionYmax = Math.min(ymaxI, ymaxJ);
const intersectionXmax = Math.min(xmaxI, xmaxJ);
const intersectionArea = Math.max(intersectionYmax - intersectionYmin, 0) * Math.max(intersectionXmax - intersectionXmin, 0);
return intersectionArea / (areaI + areaJ - intersectionArea);
const iou = intersectionArea / (areaI + areaJ - intersectionArea);
return iou;
}
function suppressWeight(iouThreshold, scale22, iou) {
const weight = Math.exp(scale22 * iou * iou);
@ -71538,7 +71539,7 @@ async function process2(input2, config3, getTensor2 = true) {
}
async function skip(config3, input2) {
let skipFrame = false;
if (config3.cacheSensitivity === 0)
if (config3.cacheSensitivity === 0 || !input2.shape || input2.shape.length !== 4 || input2.shape[1] > 2048 || input2.shape[2] > 2048)
return skipFrame;
if (!last.inputTensor) {
last.inputTensor = clone(input2);
@ -75352,7 +75353,6 @@ function correctFaceRotation(rotate, box4, input2, inputSize8) {
// src/face/blazeface.ts
var keypointsCount = 6;
var model6;
var anchorsData = [];
var anchors = null;
var inputSize = 0;
var size = () => inputSize;
@ -75369,10 +75369,7 @@ async function load5(config3) {
} else if (config3.debug)
log("cached model:", model6["modelUrl"]);
inputSize = model6.inputs[0].shape ? model6.inputs[0].shape[2] : 0;
if (inputSize === -1)
inputSize = 64;
anchorsData = generateAnchors(inputSize);
anchors = tensor2d(anchorsData);
anchors = tensor2d(generateAnchors(inputSize));
return model6;
}
function decodeBounds(boxOutputs) {
@ -75426,12 +75423,11 @@ async function getBoxes(inputImage, config3) {
b.slice = slice(t.batch, [nms[i], keypointsCount - 1], [1, -1]);
b.squeeze = squeeze(b.slice);
b.landmarks = reshape(b.squeeze, [keypointsCount, -1]);
b.startPoint = slice(b.bbox, [0, 0], [-1, 2]);
b.endPoint = slice(b.bbox, [0, 2], [-1, 2]);
const points = await b.bbox.data();
boxes.push({
box: {
startPoint: await b.startPoint.data(),
endPoint: await b.endPoint.data()
startPoint: [points[0], points[1]],
endPoint: [points[2], points[3]]
},
landmarks: await b.landmarks.array(),
confidence
@ -76204,7 +76200,7 @@ var inputSize5 = 0;
var skipped10 = Number.MAX_SAFE_INTEGER;
var lastTime10 = 0;
async function predict10(input2, config3) {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
const skipTime = (((_a = config3.face.detector) == null ? void 0 : _a.skipTime) || 0) > now() - lastTime10;
const skipFrame = skipped10 < (((_b = config3.face.detector) == null ? void 0 : _b.skipFrames) || 0);
if (!config3.skipAllowed || !skipTime || !skipFrame || boxCache.length === 0) {
@ -76218,7 +76214,10 @@ async function predict10(input2, config3) {
landmarks: possible.landmarks,
confidence: possible.confidence
};
boxCache.push(squarifyBox(enlargeBox(scaleBoxCoordinates(box4, possibleBoxes.scaleFactor), Math.sqrt(((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6))));
const boxScaled = scaleBoxCoordinates(box4, possibleBoxes.scaleFactor);
const boxEnlarged = enlargeBox(boxScaled, Math.sqrt(((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6));
const boxSquared = squarifyBox(boxEnlarged);
boxCache.push(boxSquared);
}
skipped10 = 0;
} else {
@ -76242,14 +76241,14 @@ async function predict10(input2, config3) {
faceScore: 0,
annotations: {}
};
[angle, rotationMatrix, face5.tensor] = correctFaceRotation(!((_d = config3.face.mesh) == null ? void 0 : _d.enabled) && ((_e = config3.face.detector) == null ? void 0 : _e.rotation), box4, input2, ((_f = config3.face.mesh) == null ? void 0 : _f.enabled) ? inputSize5 : size());
if ((_g = config3 == null ? void 0 : config3.filter) == null ? void 0 : _g.equalization) {
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_d = config3.face.detector) == null ? void 0 : _d.rotation, box4, input2, ((_e = config3.face.mesh) == null ? void 0 : _e.enabled) ? inputSize5 : size());
if ((_f = config3 == null ? void 0 : config3.filter) == null ? void 0 : _f.equalization) {
const equilized = await histogramEqualization(face5.tensor);
dispose(face5.tensor);
face5.tensor = equilized;
}
face5.boxScore = Math.round(100 * box4.confidence) / 100;
if (!((_h = config3.face.mesh) == null ? void 0 : _h.enabled)) {
if (!((_g = config3.face.mesh) == null ? void 0 : _g.enabled)) {
face5.box = getClampedBox(box4, input2);
face5.boxRaw = getRawBox(box4, input2);
face5.score = face5.boxScore;
@ -76270,22 +76269,22 @@ async function predict10(input2, config3) {
const coordsReshaped = reshape(contourCoords, [-1, 3]);
let rawCoords = await coordsReshaped.array();
dispose([contourCoords, coordsReshaped, confidence, contours]);
if (face5.faceScore < (((_i = config3.face.detector) == null ? void 0 : _i.minConfidence) || 1)) {
if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
box4.confidence = face5.faceScore;
} else {
if ((_j = config3.face.iris) == null ? void 0 : _j.enabled)
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize5);
face5.mesh = transformRawCoords(rawCoords, box4, angle, rotationMatrix, inputSize5);
face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input2.shape[2] || 0), pt[1] / (input2.shape[1] || 0), (pt[2] || 0) / inputSize5]);
for (const key of Object.keys(meshAnnotations))
face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]);
box4 = squarifyBox({ ...enlargeBox(calculateLandmarksBoundingBox(face5.mesh), ((_k = config3.face.detector) == null ? void 0 : _k.cropFactor) || 1.6), confidence: box4.confidence });
box4 = squarifyBox({ ...enlargeBox(calculateLandmarksBoundingBox(face5.mesh), ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6), confidence: box4.confidence });
face5.box = getClampedBox(box4, input2);
face5.boxRaw = getRawBox(box4, input2);
face5.score = face5.faceScore;
newCache.push(box4);
dispose(face5.tensor);
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_l = config3.face.detector) == null ? void 0 : _l.rotation, box4, input2, inputSize5);
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_k = config3.face.detector) == null ? void 0 : _k.rotation, box4, input2, inputSize5);
}
}
faces.push(face5);

File diff suppressed because one or more lines are too long

584
dist/human.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1223,7 +1223,7 @@ async function process2(input, config3, getTensor = true) {
}
async function skip(config3, input) {
let skipFrame = false;
if (config3.cacheSensitivity === 0)
if (config3.cacheSensitivity === 0 || !input.shape || input.shape.length !== 4 || input.shape[1] > 2048 || input.shape[2] > 2048)
return skipFrame;
if (!last.inputTensor) {
last.inputTensor = tf2.clone(input);
@ -5053,7 +5053,6 @@ function correctFaceRotation(rotate, box4, input, inputSize8) {
// src/face/blazeface.ts
var keypointsCount = 6;
var model5;
var anchorsData = [];
var anchors = null;
var inputSize = 0;
var size = () => inputSize;
@ -5070,10 +5069,7 @@ async function load5(config3) {
} else if (config3.debug)
log("cached model:", model5["modelUrl"]);
inputSize = model5.inputs[0].shape ? model5.inputs[0].shape[2] : 0;
if (inputSize === -1)
inputSize = 64;
anchorsData = generateAnchors(inputSize);
anchors = tf9.tensor2d(anchorsData);
anchors = tf9.tensor2d(generateAnchors(inputSize));
return model5;
}
function decodeBounds(boxOutputs) {
@ -5127,12 +5123,11 @@ async function getBoxes(inputImage, config3) {
b.slice = tf9.slice(t.batch, [nms[i], keypointsCount - 1], [1, -1]);
b.squeeze = tf9.squeeze(b.slice);
b.landmarks = tf9.reshape(b.squeeze, [keypointsCount, -1]);
b.startPoint = tf9.slice(b.bbox, [0, 0], [-1, 2]);
b.endPoint = tf9.slice(b.bbox, [0, 2], [-1, 2]);
const points = await b.bbox.data();
boxes.push({
box: {
startPoint: await b.startPoint.data(),
endPoint: await b.endPoint.data()
startPoint: [points[0], points[1]],
endPoint: [points[2], points[3]]
},
landmarks: await b.landmarks.array(),
confidence
@ -5920,7 +5915,7 @@ var inputSize5 = 0;
var skipped10 = Number.MAX_SAFE_INTEGER;
var lastTime10 = 0;
async function predict10(input, config3) {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
const skipTime = (((_a = config3.face.detector) == null ? void 0 : _a.skipTime) || 0) > now() - lastTime10;
const skipFrame = skipped10 < (((_b = config3.face.detector) == null ? void 0 : _b.skipFrames) || 0);
if (!config3.skipAllowed || !skipTime || !skipFrame || boxCache.length === 0) {
@ -5934,7 +5929,10 @@ async function predict10(input, config3) {
landmarks: possible.landmarks,
confidence: possible.confidence
};
boxCache.push(squarifyBox(enlargeBox(scaleBoxCoordinates(box4, possibleBoxes.scaleFactor), Math.sqrt(((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6))));
const boxScaled = scaleBoxCoordinates(box4, possibleBoxes.scaleFactor);
const boxEnlarged = enlargeBox(boxScaled, Math.sqrt(((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6));
const boxSquared = squarifyBox(boxEnlarged);
boxCache.push(boxSquared);
}
skipped10 = 0;
} else {
@ -5958,14 +5956,14 @@ async function predict10(input, config3) {
faceScore: 0,
annotations: {}
};
[angle, rotationMatrix, face5.tensor] = correctFaceRotation(!((_d = config3.face.mesh) == null ? void 0 : _d.enabled) && ((_e = config3.face.detector) == null ? void 0 : _e.rotation), box4, input, ((_f = config3.face.mesh) == null ? void 0 : _f.enabled) ? inputSize5 : size());
if ((_g = config3 == null ? void 0 : config3.filter) == null ? void 0 : _g.equalization) {
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_d = config3.face.detector) == null ? void 0 : _d.rotation, box4, input, ((_e = config3.face.mesh) == null ? void 0 : _e.enabled) ? inputSize5 : size());
if ((_f = config3 == null ? void 0 : config3.filter) == null ? void 0 : _f.equalization) {
const equilized = await histogramEqualization(face5.tensor);
tf16.dispose(face5.tensor);
face5.tensor = equilized;
}
face5.boxScore = Math.round(100 * box4.confidence) / 100;
if (!((_h = config3.face.mesh) == null ? void 0 : _h.enabled)) {
if (!((_g = config3.face.mesh) == null ? void 0 : _g.enabled)) {
face5.box = getClampedBox(box4, input);
face5.boxRaw = getRawBox(box4, input);
face5.score = face5.boxScore;
@ -5986,22 +5984,22 @@ async function predict10(input, config3) {
const coordsReshaped = tf16.reshape(contourCoords, [-1, 3]);
let rawCoords = await coordsReshaped.array();
tf16.dispose([contourCoords, coordsReshaped, confidence, contours]);
if (face5.faceScore < (((_i = config3.face.detector) == null ? void 0 : _i.minConfidence) || 1)) {
if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
box4.confidence = face5.faceScore;
} else {
if ((_j = config3.face.iris) == null ? void 0 : _j.enabled)
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize5);
face5.mesh = transformRawCoords(rawCoords, box4, angle, rotationMatrix, inputSize5);
face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize5]);
for (const key of Object.keys(meshAnnotations))
face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]);
box4 = squarifyBox({ ...enlargeBox(calculateLandmarksBoundingBox(face5.mesh), ((_k = config3.face.detector) == null ? void 0 : _k.cropFactor) || 1.6), confidence: box4.confidence });
box4 = squarifyBox({ ...enlargeBox(calculateLandmarksBoundingBox(face5.mesh), ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6), confidence: box4.confidence });
face5.box = getClampedBox(box4, input);
face5.boxRaw = getRawBox(box4, input);
face5.score = face5.faceScore;
newCache.push(box4);
tf16.dispose(face5.tensor);
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_l = config3.face.detector) == null ? void 0 : _l.rotation, box4, input, inputSize5);
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_k = config3.face.detector) == null ? void 0 : _k.rotation, box4, input, inputSize5);
}
}
faces.push(face5);

View File

@ -1224,7 +1224,7 @@ async function process2(input, config3, getTensor = true) {
}
async function skip(config3, input) {
let skipFrame = false;
if (config3.cacheSensitivity === 0)
if (config3.cacheSensitivity === 0 || !input.shape || input.shape.length !== 4 || input.shape[1] > 2048 || input.shape[2] > 2048)
return skipFrame;
if (!last.inputTensor) {
last.inputTensor = tf2.clone(input);
@ -5054,7 +5054,6 @@ function correctFaceRotation(rotate, box4, input, inputSize8) {
// src/face/blazeface.ts
var keypointsCount = 6;
var model5;
var anchorsData = [];
var anchors = null;
var inputSize = 0;
var size = () => inputSize;
@ -5071,10 +5070,7 @@ async function load5(config3) {
} else if (config3.debug)
log("cached model:", model5["modelUrl"]);
inputSize = model5.inputs[0].shape ? model5.inputs[0].shape[2] : 0;
if (inputSize === -1)
inputSize = 64;
anchorsData = generateAnchors(inputSize);
anchors = tf9.tensor2d(anchorsData);
anchors = tf9.tensor2d(generateAnchors(inputSize));
return model5;
}
function decodeBounds(boxOutputs) {
@ -5128,12 +5124,11 @@ async function getBoxes(inputImage, config3) {
b.slice = tf9.slice(t.batch, [nms[i], keypointsCount - 1], [1, -1]);
b.squeeze = tf9.squeeze(b.slice);
b.landmarks = tf9.reshape(b.squeeze, [keypointsCount, -1]);
b.startPoint = tf9.slice(b.bbox, [0, 0], [-1, 2]);
b.endPoint = tf9.slice(b.bbox, [0, 2], [-1, 2]);
const points = await b.bbox.data();
boxes.push({
box: {
startPoint: await b.startPoint.data(),
endPoint: await b.endPoint.data()
startPoint: [points[0], points[1]],
endPoint: [points[2], points[3]]
},
landmarks: await b.landmarks.array(),
confidence
@ -5921,7 +5916,7 @@ var inputSize5 = 0;
var skipped10 = Number.MAX_SAFE_INTEGER;
var lastTime10 = 0;
async function predict10(input, config3) {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
const skipTime = (((_a = config3.face.detector) == null ? void 0 : _a.skipTime) || 0) > now() - lastTime10;
const skipFrame = skipped10 < (((_b = config3.face.detector) == null ? void 0 : _b.skipFrames) || 0);
if (!config3.skipAllowed || !skipTime || !skipFrame || boxCache.length === 0) {
@ -5935,7 +5930,10 @@ async function predict10(input, config3) {
landmarks: possible.landmarks,
confidence: possible.confidence
};
boxCache.push(squarifyBox(enlargeBox(scaleBoxCoordinates(box4, possibleBoxes.scaleFactor), Math.sqrt(((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6))));
const boxScaled = scaleBoxCoordinates(box4, possibleBoxes.scaleFactor);
const boxEnlarged = enlargeBox(boxScaled, Math.sqrt(((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6));
const boxSquared = squarifyBox(boxEnlarged);
boxCache.push(boxSquared);
}
skipped10 = 0;
} else {
@ -5959,14 +5957,14 @@ async function predict10(input, config3) {
faceScore: 0,
annotations: {}
};
[angle, rotationMatrix, face5.tensor] = correctFaceRotation(!((_d = config3.face.mesh) == null ? void 0 : _d.enabled) && ((_e = config3.face.detector) == null ? void 0 : _e.rotation), box4, input, ((_f = config3.face.mesh) == null ? void 0 : _f.enabled) ? inputSize5 : size());
if ((_g = config3 == null ? void 0 : config3.filter) == null ? void 0 : _g.equalization) {
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_d = config3.face.detector) == null ? void 0 : _d.rotation, box4, input, ((_e = config3.face.mesh) == null ? void 0 : _e.enabled) ? inputSize5 : size());
if ((_f = config3 == null ? void 0 : config3.filter) == null ? void 0 : _f.equalization) {
const equilized = await histogramEqualization(face5.tensor);
tf16.dispose(face5.tensor);
face5.tensor = equilized;
}
face5.boxScore = Math.round(100 * box4.confidence) / 100;
if (!((_h = config3.face.mesh) == null ? void 0 : _h.enabled)) {
if (!((_g = config3.face.mesh) == null ? void 0 : _g.enabled)) {
face5.box = getClampedBox(box4, input);
face5.boxRaw = getRawBox(box4, input);
face5.score = face5.boxScore;
@ -5987,22 +5985,22 @@ async function predict10(input, config3) {
const coordsReshaped = tf16.reshape(contourCoords, [-1, 3]);
let rawCoords = await coordsReshaped.array();
tf16.dispose([contourCoords, coordsReshaped, confidence, contours]);
if (face5.faceScore < (((_i = config3.face.detector) == null ? void 0 : _i.minConfidence) || 1)) {
if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
box4.confidence = face5.faceScore;
} else {
if ((_j = config3.face.iris) == null ? void 0 : _j.enabled)
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize5);
face5.mesh = transformRawCoords(rawCoords, box4, angle, rotationMatrix, inputSize5);
face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize5]);
for (const key of Object.keys(meshAnnotations))
face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]);
box4 = squarifyBox({ ...enlargeBox(calculateLandmarksBoundingBox(face5.mesh), ((_k = config3.face.detector) == null ? void 0 : _k.cropFactor) || 1.6), confidence: box4.confidence });
box4 = squarifyBox({ ...enlargeBox(calculateLandmarksBoundingBox(face5.mesh), ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6), confidence: box4.confidence });
face5.box = getClampedBox(box4, input);
face5.boxRaw = getRawBox(box4, input);
face5.score = face5.faceScore;
newCache.push(box4);
tf16.dispose(face5.tensor);
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_l = config3.face.detector) == null ? void 0 : _l.rotation, box4, input, inputSize5);
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_k = config3.face.detector) == null ? void 0 : _k.rotation, box4, input, inputSize5);
}
}
faces.push(face5);

36
dist/human.node.js vendored
View File

@ -1223,7 +1223,7 @@ async function process2(input, config3, getTensor = true) {
}
async function skip(config3, input) {
let skipFrame = false;
if (config3.cacheSensitivity === 0)
if (config3.cacheSensitivity === 0 || !input.shape || input.shape.length !== 4 || input.shape[1] > 2048 || input.shape[2] > 2048)
return skipFrame;
if (!last.inputTensor) {
last.inputTensor = tf2.clone(input);
@ -5053,7 +5053,6 @@ function correctFaceRotation(rotate, box4, input, inputSize8) {
// src/face/blazeface.ts
var keypointsCount = 6;
var model5;
var anchorsData = [];
var anchors = null;
var inputSize = 0;
var size = () => inputSize;
@ -5070,10 +5069,7 @@ async function load5(config3) {
} else if (config3.debug)
log("cached model:", model5["modelUrl"]);
inputSize = model5.inputs[0].shape ? model5.inputs[0].shape[2] : 0;
if (inputSize === -1)
inputSize = 64;
anchorsData = generateAnchors(inputSize);
anchors = tf9.tensor2d(anchorsData);
anchors = tf9.tensor2d(generateAnchors(inputSize));
return model5;
}
function decodeBounds(boxOutputs) {
@ -5127,12 +5123,11 @@ async function getBoxes(inputImage, config3) {
b.slice = tf9.slice(t.batch, [nms[i], keypointsCount - 1], [1, -1]);
b.squeeze = tf9.squeeze(b.slice);
b.landmarks = tf9.reshape(b.squeeze, [keypointsCount, -1]);
b.startPoint = tf9.slice(b.bbox, [0, 0], [-1, 2]);
b.endPoint = tf9.slice(b.bbox, [0, 2], [-1, 2]);
const points = await b.bbox.data();
boxes.push({
box: {
startPoint: await b.startPoint.data(),
endPoint: await b.endPoint.data()
startPoint: [points[0], points[1]],
endPoint: [points[2], points[3]]
},
landmarks: await b.landmarks.array(),
confidence
@ -5920,7 +5915,7 @@ var inputSize5 = 0;
var skipped10 = Number.MAX_SAFE_INTEGER;
var lastTime10 = 0;
async function predict10(input, config3) {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
const skipTime = (((_a = config3.face.detector) == null ? void 0 : _a.skipTime) || 0) > now() - lastTime10;
const skipFrame = skipped10 < (((_b = config3.face.detector) == null ? void 0 : _b.skipFrames) || 0);
if (!config3.skipAllowed || !skipTime || !skipFrame || boxCache.length === 0) {
@ -5934,7 +5929,10 @@ async function predict10(input, config3) {
landmarks: possible.landmarks,
confidence: possible.confidence
};
boxCache.push(squarifyBox(enlargeBox(scaleBoxCoordinates(box4, possibleBoxes.scaleFactor), Math.sqrt(((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6))));
const boxScaled = scaleBoxCoordinates(box4, possibleBoxes.scaleFactor);
const boxEnlarged = enlargeBox(boxScaled, Math.sqrt(((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6));
const boxSquared = squarifyBox(boxEnlarged);
boxCache.push(boxSquared);
}
skipped10 = 0;
} else {
@ -5958,14 +5956,14 @@ async function predict10(input, config3) {
faceScore: 0,
annotations: {}
};
[angle, rotationMatrix, face5.tensor] = correctFaceRotation(!((_d = config3.face.mesh) == null ? void 0 : _d.enabled) && ((_e = config3.face.detector) == null ? void 0 : _e.rotation), box4, input, ((_f = config3.face.mesh) == null ? void 0 : _f.enabled) ? inputSize5 : size());
if ((_g = config3 == null ? void 0 : config3.filter) == null ? void 0 : _g.equalization) {
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_d = config3.face.detector) == null ? void 0 : _d.rotation, box4, input, ((_e = config3.face.mesh) == null ? void 0 : _e.enabled) ? inputSize5 : size());
if ((_f = config3 == null ? void 0 : config3.filter) == null ? void 0 : _f.equalization) {
const equilized = await histogramEqualization(face5.tensor);
tf16.dispose(face5.tensor);
face5.tensor = equilized;
}
face5.boxScore = Math.round(100 * box4.confidence) / 100;
if (!((_h = config3.face.mesh) == null ? void 0 : _h.enabled)) {
if (!((_g = config3.face.mesh) == null ? void 0 : _g.enabled)) {
face5.box = getClampedBox(box4, input);
face5.boxRaw = getRawBox(box4, input);
face5.score = face5.boxScore;
@ -5986,22 +5984,22 @@ async function predict10(input, config3) {
const coordsReshaped = tf16.reshape(contourCoords, [-1, 3]);
let rawCoords = await coordsReshaped.array();
tf16.dispose([contourCoords, coordsReshaped, confidence, contours]);
if (face5.faceScore < (((_i = config3.face.detector) == null ? void 0 : _i.minConfidence) || 1)) {
if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
box4.confidence = face5.faceScore;
} else {
if ((_j = config3.face.iris) == null ? void 0 : _j.enabled)
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize5);
face5.mesh = transformRawCoords(rawCoords, box4, angle, rotationMatrix, inputSize5);
face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize5]);
for (const key of Object.keys(meshAnnotations))
face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]);
box4 = squarifyBox({ ...enlargeBox(calculateLandmarksBoundingBox(face5.mesh), ((_k = config3.face.detector) == null ? void 0 : _k.cropFactor) || 1.6), confidence: box4.confidence });
box4 = squarifyBox({ ...enlargeBox(calculateLandmarksBoundingBox(face5.mesh), ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6), confidence: box4.confidence });
face5.box = getClampedBox(box4, input);
face5.boxRaw = getRawBox(box4, input);
face5.score = face5.faceScore;
newCache.push(box4);
tf16.dispose(face5.tensor);
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_l = config3.face.detector) == null ? void 0 : _l.rotation, box4, input, inputSize5);
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_k = config3.face.detector) == null ? void 0 : _k.rotation, box4, input, inputSize5);
}
}
faces.push(face5);

3
dist/tfjs.esm.js vendored
View File

@ -13480,7 +13480,8 @@ function intersectionOverUnion(boxes, i, j) {
const intersectionYmax = Math.min(ymaxI, ymaxJ);
const intersectionXmax = Math.min(xmaxI, xmaxJ);
const intersectionArea = Math.max(intersectionYmax - intersectionYmin, 0) * Math.max(intersectionXmax - intersectionXmin, 0);
return intersectionArea / (areaI + areaJ - intersectionArea);
const iou = intersectionArea / (areaI + areaJ - intersectionArea);
return iou;
}
function suppressWeight(iouThreshold, scale2, iou) {
const weight = Math.exp(scale2 * iou * iou);

View File

@ -13,7 +13,6 @@ import type { Point } from '../result';
const keypointsCount = 6;
let model: GraphModel | null;
let anchorsData: [number, number][] = [];
let anchors: Tensor | null = null;
let inputSize = 0;
@ -27,9 +26,7 @@ export async function load(config: Config): Promise<GraphModel> {
else if (config.debug) log('load model:', model['modelUrl']);
} else if (config.debug) log('cached model:', model['modelUrl']);
inputSize = model.inputs[0].shape ? model.inputs[0].shape[2] : 0;
if (inputSize === -1) inputSize = 64;
anchorsData = util.generateAnchors(inputSize);
anchors = tf.tensor2d(anchorsData);
anchors = tf.tensor2d(util.generateAnchors(inputSize));
return model;
}
@ -73,7 +70,6 @@ export async function getBoxes(inputImage: Tensor, config: Config) {
t.logits = tf.slice(t.batch, [0, 0], [-1, 1]);
t.sigmoid = tf.sigmoid(t.logits);
t.scores = tf.squeeze(t.sigmoid);
t.nms = await tf.image.nonMaxSuppressionAsync(t.boxes, t.scores, (config.face.detector?.maxDetected || 0), (config.face.detector?.iouThreshold || 0), (config.face.detector?.minConfidence || 0));
const nms = await t.nms.array() as number[];
const boxes: Array<{ box: { startPoint: Point, endPoint: Point }, landmarks: Point[], confidence: number }> = [];
@ -86,12 +82,11 @@ export async function getBoxes(inputImage: Tensor, config: Config) {
b.slice = tf.slice(t.batch, [nms[i], keypointsCount - 1], [1, -1]);
b.squeeze = tf.squeeze(b.slice);
b.landmarks = tf.reshape(b.squeeze, [keypointsCount, -1]);
b.startPoint = tf.slice(b.bbox, [0, 0], [-1, 2]);
b.endPoint = tf.slice(b.bbox, [0, 2], [-1, 2]);
const points = await b.bbox.data();
boxes.push({
box: {
startPoint: (await b.startPoint.data()) as unknown as Point,
endPoint: (await b.endPoint.data()) as unknown as Point,
startPoint: [points[0], points[1]] as Point,
endPoint: [points[2], points[3]] as Point,
},
landmarks: (await b.landmarks.array()) as Point[],
confidence,

View File

@ -41,7 +41,10 @@ export async function predict(input: Tensor, config: Config): Promise<FaceResult
landmarks: possible.landmarks,
confidence: possible.confidence,
};
boxCache.push(util.squarifyBox(util.enlargeBox(util.scaleBoxCoordinates(box, possibleBoxes.scaleFactor), Math.sqrt(config.face.detector?.cropFactor || 1.6))));
const boxScaled = util.scaleBoxCoordinates(box, possibleBoxes.scaleFactor);
const boxEnlarged = util.enlargeBox(boxScaled, Math.sqrt(config.face.detector?.cropFactor || 1.6));
const boxSquared = util.squarifyBox(boxEnlarged);
boxCache.push(boxSquared);
}
skipped = 0;
} else {
@ -67,7 +70,7 @@ export async function predict(input: Tensor, config: Config): Promise<FaceResult
};
// optional rotation correction based on detector data only if mesh is disabled otherwise perform it later when we have more accurate mesh data. if no rotation correction this function performs crop
[angle, rotationMatrix, face.tensor] = util.correctFaceRotation(!config.face.mesh?.enabled && config.face.detector?.rotation, box, input, config.face.mesh?.enabled ? inputSize : blazeface.size());
[angle, rotationMatrix, face.tensor] = util.correctFaceRotation(config.face.detector?.rotation, box, input, config.face.mesh?.enabled ? inputSize : blazeface.size());
if (config?.filter?.equalization) {
const equilized = await histogramEqualization(face.tensor as Tensor);
tf.dispose(face.tensor);

View File

@ -31,8 +31,8 @@ export const getRawBox = (box, input): Box => (box ? [
] : [0, 0, 0, 0]);
export const scaleBoxCoordinates = (box, factor) => {
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 startPoint: Point = [box.startPoint[0] * factor[0], box.startPoint[1] * factor[1]];
const endPoint: Point = [box.endPoint[0] * factor[0], box.endPoint[1] * factor[1]];
return { startPoint, endPoint, landmarks: box.landmarks, confidence: box.confidence };
};

View File

@ -262,7 +262,7 @@ const checksum = async (input: Tensor): Promise<number> => { // use tf sum or js
export async function skip(config, input: Tensor) {
let skipFrame = false;
if (config.cacheSensitivity === 0) return skipFrame;
if (config.cacheSensitivity === 0 || !input.shape || input.shape.length !== 4 || input.shape[1] > 2048 || input.shape[2] > 2048) return skipFrame; // cache disabled or input is invalid or too large for cache analysis
/*
const checkSum = await checksum(input);

View File

@ -1,26 +1,26 @@
2021-11-15 09:19:13 INFO:  @vladmandic/human version 2.5.2
2021-11-15 09:19:13 INFO:  User: vlado Platform: linux Arch: x64 Node: v17.0.1
2021-11-15 09:19:13 INFO:  Application: {"name":"@vladmandic/human","version":"2.5.2"}
2021-11-15 09:19:13 INFO:  Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
2021-11-15 09:19:13 INFO:  Toolchain: {"build":"0.6.4","esbuild":"0.13.13","typescript":"4.4.4","typedoc":"0.22.9","eslint":"8.2.0"}
2021-11-15 09:19:13 INFO:  Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
2021-11-15 09:19:13 STATE: Clean: {"locations":["dist/*","types/*","typedoc/*"]}
2021-11-15 09:19:13 STATE: Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":102,"outputBytes":1275}
2021-11-15 09:19:13 STATE: Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":61,"inputBytes":545714,"outputBytes":462580}
2021-11-15 09:19:13 STATE: Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":1283}
2021-11-15 09:19:13 STATE: Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":61,"inputBytes":545722,"outputBytes":462584}
2021-11-15 09:19:13 STATE: Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":149,"outputBytes":1350}
2021-11-15 09:19:13 STATE: Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":61,"inputBytes":545789,"outputBytes":462656}
2021-11-15 09:19:13 STATE: Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1063,"outputBytes":1652}
2021-11-15 09:19:13 STATE: Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":2326,"outputBytes":912}
2021-11-15 09:19:13 STATE: Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":61,"inputBytes":545351,"outputBytes":464846}
2021-11-15 09:19:13 STATE: Compile: {"name":"tfjs/browser/esm/custom","format":"esm","platform":"browser","input":"tfjs/tf-custom.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":307,"outputBytes":2497761}
2021-11-15 09:19:14 STATE: Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":61,"inputBytes":3042200,"outputBytes":1624010}
2021-11-15 09:19:14 STATE: Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":61,"inputBytes":3042200,"outputBytes":2967931}
2021-11-15 09:19:33 STATE: Typings: {"input":"src/human.ts","output":"types","files":53}
2021-11-15 09:19:40 STATE: TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":51,"generated":true}
2021-11-15 09:19:40 STATE: Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":5801,"outputBytes":3822}
2021-11-15 09:19:40 STATE: Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15166,"outputBytes":11786}
2021-11-15 09:20:19 STATE: Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":92,"errors":0,"warnings":0}
2021-11-15 09:20:20 STATE: ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
2021-11-15 09:20:20 INFO:  Done...
2021-11-16 12:51:36 INFO:  @vladmandic/human version 2.5.2
2021-11-16 12:51:36 INFO:  User: vlado Platform: linux Arch: x64 Node: v17.0.1
2021-11-16 12:51:36 INFO:  Application: {"name":"@vladmandic/human","version":"2.5.2"}
2021-11-16 12:51:36 INFO:  Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
2021-11-16 12:51:36 INFO:  Toolchain: {"build":"0.6.4","esbuild":"0.13.13","typescript":"4.4.4","typedoc":"0.22.9","eslint":"8.2.0"}
2021-11-16 12:51:36 INFO:  Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
2021-11-16 12:51:36 STATE: Clean: {"locations":["dist/*","types/*","typedoc/*"]}
2021-11-16 12:51:36 STATE: Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":102,"outputBytes":1275}
2021-11-16 12:51:36 STATE: Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":61,"inputBytes":545763,"outputBytes":462549}
2021-11-16 12:51:36 STATE: Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":1283}
2021-11-16 12:51:36 STATE: Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":61,"inputBytes":545771,"outputBytes":462553}
2021-11-16 12:51:36 STATE: Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":149,"outputBytes":1350}
2021-11-16 12:51:36 STATE: Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":61,"inputBytes":545838,"outputBytes":462625}
2021-11-16 12:51:36 STATE: Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1063,"outputBytes":1652}
2021-11-16 12:51:36 STATE: Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":2326,"outputBytes":912}
2021-11-16 12:51:37 STATE: Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":61,"inputBytes":545400,"outputBytes":464789}
2021-11-16 12:51:37 STATE: Compile: {"name":"tfjs/browser/esm/custom","format":"esm","platform":"browser","input":"tfjs/tf-custom.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":307,"outputBytes":2497780}
2021-11-16 12:51:37 STATE: Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":61,"inputBytes":3042268,"outputBytes":1623936}
2021-11-16 12:51:38 STATE: Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":61,"inputBytes":3042268,"outputBytes":2967931}
2021-11-16 12:52:01 STATE: Typings: {"input":"src/human.ts","output":"types","files":53}
2021-11-16 12:52:08 STATE: TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":51,"generated":true}
2021-11-16 12:52:08 STATE: Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":5811,"outputBytes":3821}
2021-11-16 12:52:08 STATE: Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15166,"outputBytes":11786}
2021-11-16 12:52:49 STATE: Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":92,"errors":0,"warnings":0}
2021-11-16 12:52:50 STATE: ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
2021-11-16 12:52:50 INFO:  Done...

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,8 @@ export declare const getBoxCenter: (box: any) => [number, number];
export declare const getClampedBox: (box: any, input: any) => Box;
export declare const getRawBox: (box: any, input: any) => Box;
export declare const scaleBoxCoordinates: (box: any, factor: any) => {
startPoint: number[];
endPoint: number[];
startPoint: Point;
endPoint: Point;
landmarks: any;
confidence: any;
};