mirror of https://github.com/vladmandic/human
change default face crop
parent
0d2d34d5c7
commit
e9300cc43a
|
@ -11,10 +11,11 @@
|
|||
|
||||
### **HEAD -> main** 2022/04/11 mandic00@live.com
|
||||
|
||||
- face attention model is available in human-models
|
||||
- beta release 2.7
|
||||
- refactor draw methods
|
||||
- implement face attention model
|
||||
|
||||
### **origin/main** 2022/04/10 mandic00@live.com
|
||||
|
||||
- add electronjs demo
|
||||
- rebuild
|
||||
|
||||
### **2.6.5** 2022/04/01 mandic00@live.com
|
||||
|
|
|
@ -1,19 +1,71 @@
|
|||
import type { Tensor } from '../tfjs/types';
|
||||
|
||||
const attentionDefinitions = {
|
||||
eyeLLower: [33, 7, 163, 144, 145, 153, 154, 155, 133], // 9
|
||||
eyeRLower: [263, 249, 390, 373, 374, 380, 381, 382, 362], // 9
|
||||
// eslint-disable-next-line max-len
|
||||
lips: [61, 76, 91, 181, 84, 17, 314, 405, 321, 291, 291, 185, 40, 39, 37, 0, 267, 269, 270, 291, 62, 183, 88, 178, 87, 14, 268, 303, 304, 408, 291, 184, 42, 178, 87, 14, 268, 303, 304, 408, 61, 62, 90, 180, 85, 16, 315, 404, 307, 308, 291, 185, 40, 73, 72, 0, 302, 269, 270, 409, 61, 184, 95, 179, 86, 15, 316, 403, 324, 408, 291, 184, 74, 41, 38, 11, 268, 303, 304, 408],
|
||||
// eslint-disable-next-line max-len
|
||||
eyeL: [33, 7, 163, 144, 145, 153, 154, 155, 133, 246, 161, 160, 159, 158, 157, 173, 130, 25, 110, 24, 23, 22, 26, 112, 243, 247, 30, 29, 27, 28, 56, 190, 226, 31, 228, 229, 230, 231, 232, 233, 244, 113, 225, 224, 223, 222, 221, 189, 35, 124, 46, 53, 52, 65, 143, 111, 117, 118, 119, 120, 121, 128, 245, 156, 70, 63, 105, 66, 107, 55, 193],
|
||||
// eslint-disable-next-line max-len
|
||||
eyeR: [263, 249, 390, 373, 374, 380, 381, 382, 362, 466, 388, 387, 386, 385, 384, 398, 359, 255, 339, 254, 253, 252, 256, 341, 463, 467, 260, 259, 257, 258, 286, 414, 446, 261, 448, 449, 450, 451, 452, 453, 464, 342, 445, 444, 443, 442, 441, 413, 265, 353, 276, 283, 282, 295, 372, 340, 346, 347, 348, 349, 350, 357, 465, 383, 300, 293, 334, 296, 336, 285, 417],
|
||||
};
|
||||
|
||||
/*
|
||||
// function used to determine heuristic mapping
|
||||
// values in attentionDefinitions are based on top values from 200 iterations
|
||||
function replaceClosestPoint(rawCoords, newCoords) {
|
||||
const res: number[] = [];
|
||||
for (let i = 0; i < newCoords.length / 2; i++) {
|
||||
let minDist = Number.MAX_VALUE;
|
||||
let minDistIdx = -1;
|
||||
const pts = rawCoords.map((r) => [r[0], r[1]]);
|
||||
for (let j = 0; j < rawCoords.length; j++) {
|
||||
const x = pts[j][0] - newCoords[2 * i + 0];
|
||||
const y = pts[j][1] - newCoords[2 * i + 1];
|
||||
const dist = (x * x) + (y * y);
|
||||
if (dist < minDist) {
|
||||
minDist = dist;
|
||||
minDistIdx = j;
|
||||
}
|
||||
}
|
||||
res.push(minDistIdx);
|
||||
rawCoords[minDistIdx] = [newCoords[2 * i + 0], newCoords[2 * i + 1], rawCoords[minDistIdx][2]];
|
||||
}
|
||||
return rawCoords;
|
||||
}
|
||||
*/
|
||||
|
||||
export async function augment(rawCoords, results: Tensor[]) {
|
||||
const t: Record<string, Float32Array> = {
|
||||
eyeL: results[0].dataSync() as Float32Array, // 71 x 2d // output_left_eye
|
||||
eyeR: results[6].dataSync() as Float32Array, // 71 x 2d // output_right_eye
|
||||
const t: Record<string, Float32Array> = { // all attention models produce 2d results so it needs to be later augmented with correct z-coords
|
||||
irisL: results[3].dataSync() as Float32Array, // 5 x 2d // output_left_iris
|
||||
irisR: results[1].dataSync() as Float32Array, // 5 x 2d // output_right_iris
|
||||
eyeL: results[0].dataSync() as Float32Array, // 71 x 2d // output_left_eye
|
||||
eyeR: results[6].dataSync() as Float32Array, // 71 x 2d // output_right_eye
|
||||
lips: results[5].dataSync() as Float32Array, // 80 x 2d // output_lips
|
||||
// flag: results[4], // already processed in parent // conv_faceflag
|
||||
// mesh: results[2], // already have it in rawCoords // output_mesh_identity
|
||||
};
|
||||
for (let i = 0; i < t.lips.length / 2; i++) rawCoords.push([t.lips[2 * i + 0], t.lips[2 * i + 1], 0]);
|
||||
for (let i = 0; i < t.eyeL.length / 2; i++) rawCoords.push([t.eyeL[2 * i + 0], t.eyeL[2 * i + 1], 0]);
|
||||
for (let i = 0; i < t.eyeR.length / 2; i++) rawCoords.push([t.eyeR[2 * i + 0], t.eyeR[2 * i + 1], 0]);
|
||||
for (let i = 0; i < t.irisL.length / 2; i++) rawCoords.push([t.irisL[2 * i + 0], t.irisL[2 * i + 1], 0]);
|
||||
for (let i = 0; i < t.irisR.length / 2; i++) rawCoords.push([t.irisR[2 * i + 0], t.irisR[2 * i + 1], 0]);
|
||||
|
||||
// rawCoords = replaceClosestPoint(rawCoords, t.eyeL);
|
||||
// rawCoords = replaceClosestPoint(rawCoords, t.eyeR);
|
||||
// rawCoords = replaceClosestPoint(rawCoords, t.lips);
|
||||
|
||||
// augment iris: adds additional 5 keypoints per eye
|
||||
const irisRDepth = attentionDefinitions.eyeRLower.reduce((prev, curr) => prev += rawCoords[curr][2], 0) / attentionDefinitions.eyeRLower.length; // get average z-coord for iris
|
||||
for (let i = 0; i < t.irisR.length / 2; i++) rawCoords.push([t.irisR[2 * i + 0], t.irisR[2 * i + 1], irisRDepth]);
|
||||
const irisLDepth = attentionDefinitions.eyeLLower.reduce((prev, curr) => prev += rawCoords[curr][2], 0) / attentionDefinitions.eyeLLower.length; // get average z-coord for iris
|
||||
for (let i = 0; i < t.irisL.length / 2; i++) rawCoords.push([t.irisL[2 * i + 0], t.irisL[2 * i + 1], irisLDepth]);
|
||||
|
||||
// augment eyes: replaces eye keypoints based on heuristic mapping
|
||||
for (let i = 0; i < t.eyeL.length / 2; i++) rawCoords[attentionDefinitions.eyeL[i]] = [t.eyeL[2 * i + 0], t.eyeL[2 * i + 1], rawCoords[attentionDefinitions.eyeL[i]][2]];
|
||||
// for (let i = 0; i < t.eyeL.length / 2; i++) rawCoords.push([t.eyeL[2 * i + 0], t.eyeL[2 * i + 1], 0]);
|
||||
for (let i = 0; i < t.eyeR.length / 2; i++) rawCoords[attentionDefinitions.eyeR[i]] = [t.eyeR[2 * i + 0], t.eyeR[2 * i + 1], rawCoords[attentionDefinitions.eyeR[i]][2]];
|
||||
// for (let i = 0; i < t.eyeR.length / 2; i++) rawCoords.push([t.eyeR[2 * i + 0], t.eyeR[2 * i + 1], 0]);
|
||||
|
||||
// augment lips: replaces eye keypoints based on heuristic mapping
|
||||
// for (let i = 0; i < t.lips.length / 2; i++) rawCoords[attentionDefinitions.lips[i]] = [t.lips[2 * i + 0], t.lips[2 * i + 1], rawCoords[attentionDefinitions.lips[i]][2]];
|
||||
// for (let i = 0; i < t.lips.length / 2; i++) rawCoords.push([t.lips[2 * i + 0], t.lips[2 * i + 1], 0]);
|
||||
|
||||
return rawCoords;
|
||||
}
|
||||
|
|
|
@ -9,20 +9,20 @@ export const meshAnnotations: Record<string, number[]> = {
|
|||
397, 365, 379, 378, 400, 377, 152, 148, 176, 149, 150, 136,
|
||||
172, 58, 132, 93, 234, 127, 162, 21, 54, 103, 67, 109,
|
||||
],
|
||||
lipsUpperOuter: [61, 185, 40, 39, 37, 0, 267, 269, 270, 409, 291],
|
||||
lipsLowerOuter: [146, 91, 181, 84, 17, 314, 405, 321, 375, 291],
|
||||
lipsUpperInner: [78, 191, 80, 81, 82, 13, 312, 311, 310, 415, 308],
|
||||
lipsLowerInner: [78, 95, 88, 178, 87, 14, 317, 402, 318, 324, 308],
|
||||
rightEyeUpper0: [246, 161, 160, 159, 158, 157, 173],
|
||||
rightEyeLower0: [33, 7, 163, 144, 145, 153, 154, 155, 133],
|
||||
rightEyeUpper1: [247, 30, 29, 27, 28, 56, 190],
|
||||
rightEyeLower1: [130, 25, 110, 24, 23, 22, 26, 112, 243],
|
||||
rightEyeUpper2: [113, 225, 224, 223, 222, 221, 189],
|
||||
rightEyeLower2: [226, 31, 228, 229, 230, 231, 232, 233, 244],
|
||||
rightEyeLower3: [143, 111, 117, 118, 119, 120, 121, 128, 245],
|
||||
rightEyebrowUpper: [156, 70, 63, 105, 66, 107, 55, 193],
|
||||
rightEyebrowLower: [35, 124, 46, 53, 52, 65],
|
||||
rightEyeIris: [473, 474, 475, 476, 477],
|
||||
lipsUpperOuter: [61, 185, 40, 39, 37, 0, 267, 269, 270, 409, 291], // 11
|
||||
lipsLowerOuter: [146, 91, 181, 84, 17, 314, 405, 321, 375, 291], // 10
|
||||
lipsUpperInner: [78, 191, 80, 81, 82, 13, 312, 311, 310, 415, 308], // 11
|
||||
lipsLowerInner: [78, 95, 88, 178, 87, 14, 317, 402, 318, 324, 308], // 11
|
||||
rightEyeUpper0: [246, 161, 160, 159, 158, 157, 173], // 7
|
||||
rightEyeLower0: [33, 7, 163, 144, 145, 153, 154, 155, 133], // 9
|
||||
rightEyeUpper1: [247, 30, 29, 27, 28, 56, 190], // 7
|
||||
rightEyeLower1: [130, 25, 110, 24, 23, 22, 26, 112, 243], // 9
|
||||
rightEyeUpper2: [113, 225, 224, 223, 222, 221, 189], // 7
|
||||
rightEyeLower2: [226, 31, 228, 229, 230, 231, 232, 233, 244], // 9
|
||||
rightEyeLower3: [143, 111, 117, 118, 119, 120, 121, 128, 245], // 9
|
||||
rightEyebrowUpper: [156, 70, 63, 105, 66, 107, 55, 193], // 8
|
||||
rightEyebrowLower: [35, 124, 46, 53, 52, 65], // 6
|
||||
rightEyeIris: [473, 474, 475, 476, 477], // 5
|
||||
leftEyeUpper0: [466, 388, 387, 386, 385, 384, 398],
|
||||
leftEyeLower0: [263, 249, 390, 373, 374, 380, 381, 382, 362],
|
||||
leftEyeUpper1: [467, 260, 259, 257, 258, 286, 414],
|
||||
|
@ -59,15 +59,15 @@ export const blazeFaceLandmarks: Record<string, number | number[]> = {
|
|||
};
|
||||
|
||||
export const MESH_TO_IRIS_INDICES_MAP: Array<{ key: string, indices: number[] }> = [ // A mapping from facemesh model keypoints to iris model keypoints.
|
||||
{ key: 'EyeUpper0', indices: [9, 10, 11, 12, 13, 14, 15] },
|
||||
{ key: 'EyeUpper1', indices: [25, 26, 27, 28, 29, 30, 31] },
|
||||
{ key: 'EyeUpper2', indices: [41, 42, 43, 44, 45, 46, 47] },
|
||||
{ key: 'EyeLower0', indices: [0, 1, 2, 3, 4, 5, 6, 7, 8] },
|
||||
{ key: 'EyeLower1', indices: [16, 17, 18, 19, 20, 21, 22, 23, 24] },
|
||||
{ key: 'EyeLower2', indices: [32, 33, 34, 35, 36, 37, 38, 39, 40] },
|
||||
{ key: 'EyeLower3', indices: [54, 55, 56, 57, 58, 59, 60, 61, 62] },
|
||||
// { key: 'EyebrowUpper', indices: [63, 64, 65, 66, 67, 68, 69, 70] },
|
||||
// { key: 'EyebrowLower', indices: [48, 49, 50, 51, 52, 53] },
|
||||
{ key: 'EyeUpper0', indices: [9, 10, 11, 12, 13, 14, 15] }, // 7 x 3d
|
||||
{ key: 'EyeUpper1', indices: [25, 26, 27, 28, 29, 30, 31] }, // 7 x 3d
|
||||
{ key: 'EyeUpper2', indices: [41, 42, 43, 44, 45, 46, 47] }, // 7 x 3d
|
||||
{ key: 'EyeLower0', indices: [0, 1, 2, 3, 4, 5, 6, 7, 8] }, // 7 x 3d
|
||||
{ key: 'EyeLower1', indices: [16, 17, 18, 19, 20, 21, 22, 23, 24] }, // 9 x 3d
|
||||
{ key: 'EyeLower2', indices: [32, 33, 34, 35, 36, 37, 38, 39, 40] }, // 9 x 3d
|
||||
{ key: 'EyeLower3', indices: [54, 55, 56, 57, 58, 59, 60, 61, 62] }, // 9 x 3d
|
||||
{ key: 'EyebrowUpper', indices: [63, 64, 65, 66, 67, 68, 69, 70] }, // 8 x 3d
|
||||
{ key: 'EyebrowLower', indices: [48, 49, 50, 51, 52, 53] }, // 6 x 3d
|
||||
];
|
||||
|
||||
export const UV468: [number, number][] = [
|
||||
|
|
|
@ -39,7 +39,7 @@ export async function load(config: Config): Promise<GraphModel> {
|
|||
|
||||
// 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.
|
||||
function replaceRawCoordinates(rawCoords, newCoords, prefix, keys) {
|
||||
export function replaceIrisCoords(rawCoords, newCoords, prefix, keys) {
|
||||
for (let i = 0; i < coords.MESH_TO_IRIS_INDICES_MAP.length; i++) {
|
||||
const { key, indices } = coords.MESH_TO_IRIS_INDICES_MAP[i];
|
||||
const originalIndices = coords.meshAnnotations[`${prefix}${key}`];
|
||||
|
@ -47,7 +47,8 @@ function replaceRawCoordinates(rawCoords, newCoords, prefix, keys) {
|
|||
for (let j = 0; j < indices.length; j++) {
|
||||
const index = indices[j];
|
||||
rawCoords[originalIndices[j]] = [
|
||||
newCoords[index][0], newCoords[index][1],
|
||||
newCoords[index][0],
|
||||
newCoords[index][1],
|
||||
(newCoords[index][2] + rawCoords[originalIndices[j]][2]) / 2,
|
||||
];
|
||||
}
|
||||
|
@ -132,14 +133,14 @@ export async function augmentIris(rawCoords, face, config, meshSize) {
|
|||
const { rawCoords: rightEyeRawCoords, iris: rightIrisRawCoords } = getEyeCoords(rightEyeData, rightEyeBox, rightEyeBoxSize, false);
|
||||
const leftToRightEyeDepthDifference = getLeftToRightEyeDepthDifference(rawCoords);
|
||||
if (Math.abs(leftToRightEyeDepthDifference) < 30) { // User is looking straight ahead.
|
||||
replaceRawCoordinates(rawCoords, leftEyeRawCoords, 'left', null);
|
||||
replaceRawCoordinates(rawCoords, rightEyeRawCoords, 'right', null);
|
||||
replaceIrisCoords(rawCoords, leftEyeRawCoords, 'left', null);
|
||||
replaceIrisCoords(rawCoords, rightEyeRawCoords, 'right', null);
|
||||
// If the user is looking to the left or to the right, the iris coordinates tend to diverge too much from the mesh coordinates for them to be merged
|
||||
// So we only update a single contour line above and below the eye.
|
||||
} else if (leftToRightEyeDepthDifference < 1) { // User is looking towards the right.
|
||||
replaceRawCoordinates(rawCoords, leftEyeRawCoords, 'left', ['EyeUpper0', 'EyeLower0']);
|
||||
replaceIrisCoords(rawCoords, leftEyeRawCoords, 'left', ['EyeUpper0', 'EyeLower0']);
|
||||
} else { // User is looking towards the left.
|
||||
replaceRawCoordinates(rawCoords, rightEyeRawCoords, 'right', ['EyeUpper0', 'EyeLower0']);
|
||||
replaceIrisCoords(rawCoords, rightEyeRawCoords, 'right', ['EyeUpper0', 'EyeLower0']);
|
||||
}
|
||||
const adjustedLeftIrisCoords = getAdjustedIrisCoords(rawCoords, leftIrisRawCoords, 'left');
|
||||
const adjustedRightIrisCoords = getAdjustedIrisCoords(rawCoords, rightIrisRawCoords, 'right');
|
||||
|
|
|
@ -81,7 +81,7 @@ export async function load(instance: Human): Promise<void> {
|
|||
if (instance.config.face.enabled && instance.config.face.liveness?.enabled && !instance.models.liveness) instance.models.liveness = liveness.load(instance.config);
|
||||
if (instance.config.face.enabled && instance.config.face.description?.enabled && !instance.models.faceres) instance.models.faceres = faceres.load(instance.config);
|
||||
if (instance.config.face.enabled && instance.config.face.emotion?.enabled && !instance.models.emotion) instance.models.emotion = emotion.load(instance.config);
|
||||
if (instance.config.face.enabled && instance.config.face.iris?.enabled && !instance.models.faceiris) instance.models.faceiris = iris.load(instance.config);
|
||||
if (instance.config.face.enabled && instance.config.face.iris?.enabled && !instance.config.face.attention?.enabled && !instance.models.faceiris) instance.models.faceiris = iris.load(instance.config);
|
||||
if (instance.config.face.enabled && instance.config.face.mesh?.enabled && !instance.models.facemesh) instance.models.facemesh = facemesh.load(instance.config);
|
||||
// @ts-ignore optional model
|
||||
if (instance.config.face.enabled && instance.config.face['gear']?.enabled && !instance.models.gear) instance.models.gear = gear.load(instance.config);
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
2022-04-11 11:46:03 [36mINFO: [39m Application: {"name":"@vladmandic/human","version":"2.7.0"}
|
||||
2022-04-11 11:46:03 [36mINFO: [39m Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
|
||||
2022-04-11 11:46:03 [36mINFO: [39m Toolchain: {"build":"0.7.2","esbuild":"0.14.34","typescript":"4.6.3","typedoc":"0.22.15","eslint":"8.13.0"}
|
||||
2022-04-11 11:46:03 [36mINFO: [39m Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
|
||||
2022-04-11 11:46:03 [35mSTATE:[39m Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]}
|
||||
2022-04-11 11:46:03 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":102,"outputBytes":595}
|
||||
2022-04-11 11:46:03 [35mSTATE:[39m Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":72,"inputBytes":568981,"outputBytes":294190}
|
||||
2022-04-11 11:46:03 [35mSTATE:[39m 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":599}
|
||||
2022-04-11 11:46:03 [35mSTATE:[39m Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":72,"inputBytes":568985,"outputBytes":294194}
|
||||
2022-04-11 11:46:03 [35mSTATE:[39m 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":651}
|
||||
2022-04-11 11:46:03 [35mSTATE:[39m Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":72,"inputBytes":569037,"outputBytes":294244}
|
||||
2022-04-11 11:46:03 [35mSTATE:[39m Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1063,"outputBytes":394}
|
||||
2022-04-11 11:46:03 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":1068,"outputBytes":615}
|
||||
2022-04-11 11:46:03 [35mSTATE:[39m Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":72,"inputBytes":569001,"outputBytes":293151}
|
||||
2022-04-11 11:46:04 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/custom","format":"esm","platform":"browser","input":"tfjs/tf-custom.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":1344714}
|
||||
2022-04-11 11:46:04 [35mSTATE:[39m Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":72,"inputBytes":1913100,"outputBytes":1636880}
|
||||
2022-04-11 11:46:04 [35mSTATE:[39m Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":72,"inputBytes":1913100,"outputBytes":2115805}
|
||||
2022-04-11 11:46:09 [35mSTATE:[39m Typings: {"input":"src/human.ts","output":"types/lib","files":114}
|
||||
2022-04-11 11:46:11 [35mSTATE:[39m TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":73,"generated":true}
|
||||
2022-04-11 11:46:11 [35mSTATE:[39m Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":5916,"outputBytes":2957}
|
||||
2022-04-11 11:46:11 [35mSTATE:[39m Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15174,"outputBytes":7820}
|
||||
2022-04-11 11:46:19 [35mSTATE:[39m Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":104,"errors":0,"warnings":0}
|
||||
2022-04-11 11:46:19 [35mSTATE:[39m ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
|
||||
2022-04-11 11:46:19 [36mINFO: [39m Done...
|
||||
2022-04-14 11:39:30 [36mINFO: [39m Application: {"name":"@vladmandic/human","version":"2.7.0"}
|
||||
2022-04-14 11:39:30 [36mINFO: [39m Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
|
||||
2022-04-14 11:39:30 [36mINFO: [39m Toolchain: {"build":"0.7.2","esbuild":"0.14.34","typescript":"4.6.3","typedoc":"0.22.15","eslint":"8.13.0"}
|
||||
2022-04-14 11:39:30 [36mINFO: [39m Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
|
||||
2022-04-14 11:39:30 [35mSTATE:[39m Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]}
|
||||
2022-04-14 11:39:30 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":102,"outputBytes":595}
|
||||
2022-04-14 11:39:30 [35mSTATE:[39m Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":72,"inputBytes":572717,"outputBytes":295399}
|
||||
2022-04-14 11:39:30 [35mSTATE:[39m 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":599}
|
||||
2022-04-14 11:39:30 [35mSTATE:[39m Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":72,"inputBytes":572721,"outputBytes":295403}
|
||||
2022-04-14 11:39:30 [35mSTATE:[39m 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":651}
|
||||
2022-04-14 11:39:30 [35mSTATE:[39m Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":72,"inputBytes":572773,"outputBytes":295453}
|
||||
2022-04-14 11:39:30 [35mSTATE:[39m Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1063,"outputBytes":394}
|
||||
2022-04-14 11:39:30 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":1068,"outputBytes":615}
|
||||
2022-04-14 11:39:30 [35mSTATE:[39m Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":72,"inputBytes":572737,"outputBytes":294360}
|
||||
2022-04-14 11:39:31 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/custom","format":"esm","platform":"browser","input":"tfjs/tf-custom.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":1344714}
|
||||
2022-04-14 11:39:31 [35mSTATE:[39m Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":72,"inputBytes":1916836,"outputBytes":1638088}
|
||||
2022-04-14 11:39:31 [35mSTATE:[39m Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":72,"inputBytes":1916836,"outputBytes":2117565}
|
||||
2022-04-14 11:39:37 [35mSTATE:[39m Typings: {"input":"src/human.ts","output":"types/lib","files":114}
|
||||
2022-04-14 11:39:39 [35mSTATE:[39m TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":73,"generated":true}
|
||||
2022-04-14 11:39:39 [35mSTATE:[39m Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":5916,"outputBytes":2957}
|
||||
2022-04-14 11:39:39 [35mSTATE:[39m Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15174,"outputBytes":7820}
|
||||
2022-04-14 11:39:47 [35mSTATE:[39m Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":104,"errors":0,"warnings":0}
|
||||
2022-04-14 11:39:48 [35mSTATE:[39m ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
|
||||
2022-04-14 11:39:48 [36mINFO: [39m Done...
|
||||
|
|
|
@ -150,9 +150,9 @@ async function verifyDetails(human) {
|
|||
verify(res.face.length === 1, 'details face length', res.face.length);
|
||||
for (const face of res.face) {
|
||||
verify(face.score > 0.9 && face.boxScore > 0.9 && face.faceScore > 0.9, 'details face score', face.score, face.boxScore, face.faceScore);
|
||||
verify(face.age > 25 && face.age < 30 && face.gender === 'female' && face.genderScore > 0.9 && face.iris > 70 && face.iris < 80, 'details face age/gender', face.age, face.gender, face.genderScore, face.iris);
|
||||
verify(face.age > 23 && face.age < 30 && face.gender === 'female' && face.genderScore > 0.9 && face.iris > 70 && face.iris < 80, 'details face age/gender', face.age, face.gender, face.genderScore, face.iris);
|
||||
verify(face.box.length === 4 && face.boxRaw.length === 4 && face.mesh.length === 478 && face.meshRaw.length === 478 && face.embedding.length === 1024, 'details face arrays', face.box.length, face.mesh.length, face.embedding.length);
|
||||
verify(face.emotion.length === 3 && face.emotion[0].score > 0.30 && face.emotion[0].emotion === 'fear', 'details face emotion', face.emotion.length, face.emotion[0]);
|
||||
verify(face.emotion.length >= 2 && face.emotion[0].score > 0.30 && face.emotion[0].emotion === 'angry', 'details face emotion', face.emotion.length, face.emotion[0]);
|
||||
verify(face.real > 0.75, 'details face anti-spoofing', face.real);
|
||||
verify(face.live > 0.75, 'details face liveness', face.live);
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ async function test(Human, inputConfig) {
|
|||
else log('state', 'passed: warmup none result match');
|
||||
config.warmup = 'face';
|
||||
res = await testWarmup(human, 'default');
|
||||
if (!res || res?.face?.length !== 1 || res?.body?.length !== 1 || res?.hand?.length !== 1 || res?.gesture?.length < 7) log('error', 'failed: warmup face result mismatch', res?.face?.length, res?.body?.length, res?.hand?.length, res?.gesture?.length);
|
||||
if (!res || res?.face?.length !== 1 || res?.body?.length !== 1 || res?.hand?.length !== 1 || res?.gesture?.length < 6) log('error', 'failed: warmup face result mismatch', res?.face?.length, res?.body?.length, res?.hand?.length, res?.gesture?.length);
|
||||
else log('state', 'passed: warmup face result match');
|
||||
config.warmup = 'body';
|
||||
res = await testWarmup(human, 'default');
|
||||
|
@ -334,7 +334,7 @@ async function test(Human, inputConfig) {
|
|||
res1 = human.similarity(desc1, desc1);
|
||||
res2 = human.similarity(desc1, desc2);
|
||||
res3 = human.similarity(desc1, desc3);
|
||||
if (res1 < 1 || res2 < 0.50 || res3 < 0.45 || res2 > 0.75 || res3 > 0.75) log('error', 'failed: face similarity', { similarity: [res1, res2, res3], descriptors: [desc1?.length, desc2?.length, desc3?.length] });
|
||||
if (res1 < 1 || res2 < 0.40 || res3 < 0.40 || res2 > 0.75 || res3 > 0.75) log('error', 'failed: face similarity', { similarity: [res1, res2, res3], descriptors: [desc1?.length, desc2?.length, desc3?.length] });
|
||||
else log('state', 'passed: face similarity', { similarity: [res1, res2, res3], descriptors: [desc1?.length, desc2?.length, desc3?.length] });
|
||||
|
||||
// test face matching
|
||||
|
|
1368
test/test.log
1368
test/test.log
File diff suppressed because it is too large
Load Diff
|
@ -6,7 +6,7 @@
|
|||
"outDir": "types",
|
||||
"baseUrl": "./",
|
||||
"paths": { "tslib": ["./node_modules/tslib/tslib.d.ts"] },
|
||||
"lib": ["esnext", "dom", "webworker"],
|
||||
"lib": ["esnext", "dom"],
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": false,
|
||||
"allowUnreachableCode": false,
|
||||
|
|
Loading…
Reference in New Issue