update blazepose and extend hand annotations

pull/233/head
Vladimir Mandic 2021-11-24 16:17:03 -05:00
parent db6fe46741
commit 8050f5ed99
18 changed files with 2394 additions and 2686 deletions

View File

@ -11,14 +11,13 @@
### **HEAD -> main** 2021/11/23 mandic00@live.com ### **HEAD -> main** 2021/11/23 mandic00@live.com
- fix face box scaling on detection
- cleanup - cleanup
### **2.5.4** 2021/11/22 mandic00@live.com ### **2.5.4** 2021/11/22 mandic00@live.com
- prototype blazepose detector - prototype blazepose detector
- minor fixes
### **origin/main** 2021/11/21 mandic00@live.com
- add body 3d interpolation - add body 3d interpolation
- edit blazepose keypoints - edit blazepose keypoints
- new build process - new build process

File diff suppressed because one or more lines are too long

View File

@ -10,7 +10,7 @@
import { Human, Config } from '../../dist/human.esm.js'; // equivalent of @vladmandic/Human import { Human, Config } from '../../dist/human.esm.js'; // equivalent of @vladmandic/Human
const humanConfig: Partial<Config> = { // user configuration for human, used to fine-tune behavior const humanConfig: Partial<Config> = { // user configuration for human, used to fine-tune behavior
// backend: 'webgpu' as 'webgpu, // backend: 'webgpu' as const,
// async: true, // async: true,
modelBasePath: '../../models', modelBasePath: '../../models',
filter: { enabled: true, equalization: false }, filter: { enabled: true, equalization: false },

View File

@ -963,8 +963,8 @@ function GLImageFilter() {
// src/image/enhance.ts // src/image/enhance.ts
async function histogramEqualization(inputImage) { async function histogramEqualization(inputImage) {
const squeeze11 = inputImage.shape.length === 4 ? tfjs_esm_exports.squeeze(inputImage) : inputImage; const squeeze10 = inputImage.shape.length === 4 ? tfjs_esm_exports.squeeze(inputImage) : inputImage;
const channels = tfjs_esm_exports.split(squeeze11, 3, 2); const channels = tfjs_esm_exports.split(squeeze10, 3, 2);
const min2 = [tfjs_esm_exports.min(channels[0]), tfjs_esm_exports.min(channels[1]), tfjs_esm_exports.min(channels[2])]; const min2 = [tfjs_esm_exports.min(channels[0]), tfjs_esm_exports.min(channels[1]), tfjs_esm_exports.min(channels[2])];
const max4 = [tfjs_esm_exports.max(channels[0]), tfjs_esm_exports.max(channels[1]), tfjs_esm_exports.max(channels[2])]; const max4 = [tfjs_esm_exports.max(channels[0]), tfjs_esm_exports.max(channels[1]), tfjs_esm_exports.max(channels[2])];
const absMax = await Promise.all(max4.map((channel) => channel.data())); const absMax = await Promise.all(max4.map((channel) => channel.data()));
@ -974,8 +974,8 @@ async function histogramEqualization(inputImage) {
const fact = [tfjs_esm_exports.div(maxValue, range[0]), tfjs_esm_exports.div(maxValue, range[1]), tfjs_esm_exports.div(maxValue, range[2])]; const fact = [tfjs_esm_exports.div(maxValue, range[0]), tfjs_esm_exports.div(maxValue, range[1]), tfjs_esm_exports.div(maxValue, range[2])];
const enh = [tfjs_esm_exports.mul(sub10[0], fact[0]), tfjs_esm_exports.mul(sub10[1], fact[1]), tfjs_esm_exports.mul(sub10[2], fact[2])]; const enh = [tfjs_esm_exports.mul(sub10[0], fact[0]), tfjs_esm_exports.mul(sub10[1], fact[1]), tfjs_esm_exports.mul(sub10[2], fact[2])];
const rgb2 = tfjs_esm_exports.stack([enh[0], enh[1], enh[2]], 2); const rgb2 = tfjs_esm_exports.stack([enh[0], enh[1], enh[2]], 2);
const reshape8 = tfjs_esm_exports.reshape(rgb2, [1, squeeze11.shape[0], squeeze11.shape[1], 3]); const reshape8 = tfjs_esm_exports.reshape(rgb2, [1, squeeze10.shape[0], squeeze10.shape[1], 3]);
tfjs_esm_exports.dispose([...channels, ...min2, ...max4, ...sub10, ...range, ...fact, ...enh, rgb2, squeeze11]); tfjs_esm_exports.dispose([...channels, ...min2, ...max4, ...sub10, ...range, ...fact, ...enh, rgb2, squeeze10]);
return reshape8; return reshape8;
} }
@ -1390,8 +1390,8 @@ async function predict(image29, config3, idx, count2) {
if (!(model == null ? void 0 : model.inputs[0].shape)) if (!(model == null ? void 0 : model.inputs[0].shape))
return; return;
const t = {}; const t = {};
const box4 = [[0, 0.1, 0.9, 0.9]]; const box5 = [[0, 0.1, 0.9, 0.9]];
t.resize = tfjs_esm_exports.image.cropAndResize(image29, box4, [0], [model.inputs[0].shape[2], model.inputs[0].shape[1]]); t.resize = tfjs_esm_exports.image.cropAndResize(image29, box5, [0], [model.inputs[0].shape[2], model.inputs[0].shape[1]]);
const obj = { age: 0, gender: "unknown", genderScore: 0, race: [] }; const obj = { age: 0, gender: "unknown", genderScore: 0, race: [] };
if ((_a2 = config3.face["gear"]) == null ? void 0 : _a2.enabled) if ((_a2 = config3.face["gear"]) == null ? void 0 : _a2.enabled)
[t.age, t.gender, t.race] = model.execute(t.resize, ["age_output", "gender_output", "race_output"]); [t.age, t.gender, t.race] = model.execute(t.resize, ["age_output", "gender_output", "race_output"]);
@ -4875,44 +4875,44 @@ var UV33 = VTX33.map((x) => UV468[x]);
var UV7 = VTX7.map((x) => UV468[x]); var UV7 = VTX7.map((x) => UV468[x]);
// src/face/facemeshutil.ts // src/face/facemeshutil.ts
var getBoxSize = (box4) => [Math.abs(box4.endPoint[0] - box4.startPoint[0]), Math.abs(box4.endPoint[1] - box4.startPoint[1])]; var getBoxSize = (box5) => [Math.abs(box5.endPoint[0] - box5.startPoint[0]), Math.abs(box5.endPoint[1] - box5.startPoint[1])];
var getBoxCenter = (box4) => [box4.startPoint[0] + (box4.endPoint[0] - box4.startPoint[0]) / 2, box4.startPoint[1] + (box4.endPoint[1] - box4.startPoint[1]) / 2]; var getBoxCenter = (box5) => [box5.startPoint[0] + (box5.endPoint[0] - box5.startPoint[0]) / 2, box5.startPoint[1] + (box5.endPoint[1] - box5.startPoint[1]) / 2];
var getClampedBox = (box4, input) => box4 ? [ var getClampedBox = (box5, input) => box5 ? [
Math.trunc(Math.max(0, box4.startPoint[0])), Math.trunc(Math.max(0, box5.startPoint[0])),
Math.trunc(Math.max(0, box4.startPoint[1])), Math.trunc(Math.max(0, box5.startPoint[1])),
Math.trunc(Math.min(input.shape[2] || 0, box4.endPoint[0]) - Math.max(0, box4.startPoint[0])), Math.trunc(Math.min(input.shape[2] || 0, box5.endPoint[0]) - Math.max(0, box5.startPoint[0])),
Math.trunc(Math.min(input.shape[1] || 0, box4.endPoint[1]) - Math.max(0, box4.startPoint[1])) Math.trunc(Math.min(input.shape[1] || 0, box5.endPoint[1]) - Math.max(0, box5.startPoint[1]))
] : [0, 0, 0, 0]; ] : [0, 0, 0, 0];
var getRawBox = (box4, input) => box4 ? [ var getRawBox = (box5, input) => box5 ? [
box4.startPoint[0] / (input.shape[2] || 0), box5.startPoint[0] / (input.shape[2] || 0),
box4.startPoint[1] / (input.shape[1] || 0), box5.startPoint[1] / (input.shape[1] || 0),
(box4.endPoint[0] - box4.startPoint[0]) / (input.shape[2] || 0), (box5.endPoint[0] - box5.startPoint[0]) / (input.shape[2] || 0),
(box4.endPoint[1] - box4.startPoint[1]) / (input.shape[1] || 0) (box5.endPoint[1] - box5.startPoint[1]) / (input.shape[1] || 0)
] : [0, 0, 0, 0]; ] : [0, 0, 0, 0];
var scaleBoxCoordinates = (box4, factor) => { var scaleBoxCoordinates = (box5, factor) => {
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]]; const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]]; const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
return { startPoint, endPoint, landmarks: box4.landmarks, confidence: box4.confidence }; return { startPoint, endPoint, landmarks: box5.landmarks, confidence: box5.confidence };
}; };
var cutBoxFromImageAndResize = (box4, image29, cropSize) => { var cutBoxFromImageAndResize = (box5, image29, cropSize) => {
const h = image29.shape[1]; const h = image29.shape[1];
const w = image29.shape[2]; const w = image29.shape[2];
const crop2 = tfjs_esm_exports.image.cropAndResize(image29, [[box4.startPoint[1] / h, box4.startPoint[0] / w, box4.endPoint[1] / h, box4.endPoint[0] / w]], [0], cropSize); const crop2 = tfjs_esm_exports.image.cropAndResize(image29, [[box5.startPoint[1] / h, box5.startPoint[0] / w, box5.endPoint[1] / h, box5.endPoint[0] / w]], [0], cropSize);
const norm = tfjs_esm_exports.div(crop2, constants.tf255); const norm = tfjs_esm_exports.div(crop2, constants.tf255);
tfjs_esm_exports.dispose(crop2); tfjs_esm_exports.dispose(crop2);
return norm; return norm;
}; };
var enlargeBox = (box4, factor) => { var enlargeBox = (box5, factor) => {
const center = getBoxCenter(box4); const center = getBoxCenter(box5);
const size2 = getBoxSize(box4); const size2 = getBoxSize(box5);
const halfSize = [factor * size2[0] / 2, factor * size2[1] / 2]; const halfSize = [factor * size2[0] / 2, factor * size2[1] / 2];
return { startPoint: [center[0] - halfSize[0], center[1] - halfSize[1]], endPoint: [center[0] + halfSize[0], center[1] + halfSize[1]], landmarks: box4.landmarks, confidence: box4.confidence }; return { startPoint: [center[0] - halfSize[0], center[1] - halfSize[1]], endPoint: [center[0] + halfSize[0], center[1] + halfSize[1]], landmarks: box5.landmarks, confidence: box5.confidence };
}; };
var squarifyBox = (box4) => { var squarifyBox = (box5) => {
const centers = getBoxCenter(box4); const centers = getBoxCenter(box5);
const size2 = getBoxSize(box4); const size2 = getBoxSize(box5);
const halfSize = Math.max(...size2) / 2; const halfSize = Math.max(...size2) / 2;
return { startPoint: [Math.round(centers[0] - halfSize), Math.round(centers[1] - halfSize)], endPoint: [Math.round(centers[0] + halfSize), Math.round(centers[1] + halfSize)], landmarks: box4.landmarks, confidence: box4.confidence }; return { startPoint: [Math.round(centers[0] - halfSize), Math.round(centers[1] - halfSize)], endPoint: [Math.round(centers[0] + halfSize), Math.round(centers[1] + halfSize)], landmarks: box5.landmarks, confidence: box5.confidence };
}; };
var calculateLandmarksBoundingBox = (landmarks) => { var calculateLandmarksBoundingBox = (landmarks) => {
const xs = landmarks.map((d) => d[0]); const xs = landmarks.map((d) => d[0]);
@ -4980,8 +4980,8 @@ function generateAnchors(inputSize9) {
} }
return anchors4; return anchors4;
} }
function transformRawCoords(coordsRaw, box4, angle, rotationMatrix, inputSize9) { function transformRawCoords(coordsRaw, box5, angle, rotationMatrix, inputSize9) {
const boxSize = getBoxSize(box4); const boxSize = getBoxSize(box5);
const coordsScaled = coordsRaw.map((coord) => [ const coordsScaled = coordsRaw.map((coord) => [
boxSize[0] / inputSize9 * (coord[0] - inputSize9 / 2), boxSize[0] / inputSize9 * (coord[0] - inputSize9 / 2),
boxSize[1] / inputSize9 * (coord[1] - inputSize9 / 2), boxSize[1] / inputSize9 * (coord[1] - inputSize9 / 2),
@ -4991,33 +4991,33 @@ function transformRawCoords(coordsRaw, box4, angle, rotationMatrix, inputSize9)
const coordsRotationMatrix = largeAngle ? buildRotationMatrix(angle, [0, 0]) : fixedRotationMatrix; const coordsRotationMatrix = largeAngle ? buildRotationMatrix(angle, [0, 0]) : fixedRotationMatrix;
const coordsRotated = largeAngle ? coordsScaled.map((coord) => [...rotatePoint(coord, coordsRotationMatrix), coord[2]]) : coordsScaled; const coordsRotated = largeAngle ? coordsScaled.map((coord) => [...rotatePoint(coord, coordsRotationMatrix), coord[2]]) : coordsScaled;
const inverseRotationMatrix = largeAngle ? invertTransformMatrix(rotationMatrix) : fixedRotationMatrix; const inverseRotationMatrix = largeAngle ? invertTransformMatrix(rotationMatrix) : fixedRotationMatrix;
const boxCenter = [...getBoxCenter({ startPoint: box4.startPoint, endPoint: box4.endPoint }), 1]; const boxCenter = [...getBoxCenter({ startPoint: box5.startPoint, endPoint: box5.endPoint }), 1];
return coordsRotated.map((coord) => [ return coordsRotated.map((coord) => [
Math.round(coord[0] + dot(boxCenter, inverseRotationMatrix[0])), Math.round(coord[0] + dot(boxCenter, inverseRotationMatrix[0])),
Math.round(coord[1] + dot(boxCenter, inverseRotationMatrix[1])), Math.round(coord[1] + dot(boxCenter, inverseRotationMatrix[1])),
Math.round(coord[2] || 0) Math.round(coord[2] || 0)
]); ]);
} }
function correctFaceRotation(rotate, box4, input, inputSize9) { function correctFaceRotation(rotate, box5, input, inputSize9) {
const symmetryLine = box4.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine; const symmetryLine = box5.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine;
let angle = 0; let angle = 0;
let rotationMatrix = fixedRotationMatrix; let rotationMatrix = fixedRotationMatrix;
let face5; let face5;
if (rotate && env.kernels.includes("rotatewithoffset")) { if (rotate && env.kernels.includes("rotatewithoffset")) {
angle = computeRotation(box4.landmarks[symmetryLine[0]], box4.landmarks[symmetryLine[1]]); angle = computeRotation(box5.landmarks[symmetryLine[0]], box5.landmarks[symmetryLine[1]]);
const largeAngle = angle && angle !== 0 && Math.abs(angle) > 0.2; const largeAngle = angle && angle !== 0 && Math.abs(angle) > 0.2;
if (largeAngle) { if (largeAngle) {
const center = getBoxCenter({ startPoint: box4.startPoint, endPoint: box4.endPoint }); const center = getBoxCenter({ startPoint: box5.startPoint, endPoint: box5.endPoint });
const centerRaw = [center[0] / input.shape[2], center[1] / input.shape[1]]; const centerRaw = [center[0] / input.shape[2], center[1] / input.shape[1]];
const rotated = tfjs_esm_exports.image.rotateWithOffset(input, angle, 0, centerRaw); const rotated = tfjs_esm_exports.image.rotateWithOffset(input, angle, 0, centerRaw);
rotationMatrix = buildRotationMatrix(-angle, center); rotationMatrix = buildRotationMatrix(-angle, center);
face5 = cutBoxFromImageAndResize(box4, rotated, [inputSize9, inputSize9]); face5 = cutBoxFromImageAndResize(box5, rotated, [inputSize9, inputSize9]);
tfjs_esm_exports.dispose(rotated); tfjs_esm_exports.dispose(rotated);
} else { } else {
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]); face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
} }
} else { } else {
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]); face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
} }
return [angle, rotationMatrix, face5]; return [angle, rotationMatrix, face5];
} }
@ -5198,41 +5198,39 @@ async function createAnchors() {
} }
anchorTensor = { x: tfjs_esm_exports.tensor1d(anchors4.map((a) => a.x)), y: tfjs_esm_exports.tensor1d(anchors4.map((a) => a.y)) }; anchorTensor = { x: tfjs_esm_exports.tensor1d(anchors4.map((a) => a.x)), y: tfjs_esm_exports.tensor1d(anchors4.map((a) => a.y)) };
} }
var cropFactor = [5, 5];
function decodeBoxes(boxesTensor, anchor) { // src/util/box.ts
return tfjs_esm_exports.tidy(() => { function calc(keypoints, outputSize2 = [1, 1]) {
const split5 = tfjs_esm_exports.split(boxesTensor, 12, 1); const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
let xCenter = tfjs_esm_exports.squeeze(split5[0]); const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
let yCenter = tfjs_esm_exports.squeeze(split5[1]); const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
let width = tfjs_esm_exports.squeeze(split5[2]); const box5 = [min2[0], min2[1], max4[0] - min2[0], max4[1] - min2[1]];
let height = tfjs_esm_exports.squeeze(split5[3]); const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
xCenter = tfjs_esm_exports.add(tfjs_esm_exports.div(xCenter, inputSize2), anchor.x); return { box: box5, boxRaw };
yCenter = tfjs_esm_exports.add(tfjs_esm_exports.div(yCenter, inputSize2), anchor.y);
width = tfjs_esm_exports.mul(tfjs_esm_exports.div(width, inputSize2), cropFactor[0]);
height = tfjs_esm_exports.mul(tfjs_esm_exports.div(height, inputSize2), cropFactor[1]);
const xMin = tfjs_esm_exports.sub(xCenter, tfjs_esm_exports.div(width, 2));
const yMin = tfjs_esm_exports.sub(yCenter, tfjs_esm_exports.div(height, 2));
const boxes = tfjs_esm_exports.stack([xMin, yMin, width, height], 1);
return boxes;
});
} }
async function decode(boxesTensor, logitsTensor, config3, outputSize2) { function square(keypoints, outputSize2 = [1, 1]) {
const t = {}; const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
t.boxes = decodeBoxes(boxesTensor, anchorTensor); const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
t.scores = tfjs_esm_exports.sigmoid(logitsTensor); const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
t.argmax = tfjs_esm_exports.argMax(t.scores); const center = [(min2[0] + max4[0]) / 2, (min2[1] + max4[1]) / 2];
const i = (await t.argmax.data())[0]; const dist = Math.max(center[0] - min2[0], center[1] - min2[1], -center[0] + max4[0], -center[1] + max4[1]);
const scores = await t.scores.data(); const box5 = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];
const detected = []; const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
const minScore = config3.body["detector"] && config3.body["detector"]["minConfidence"] ? config3.body["detector"]["minConfidence"] : 0; return { box: box5, boxRaw };
if (scores[i] >= minScore) { }
const boxes = await t.boxes.array(); function scale(box5, scaleFact) {
const boxRaw = boxes[i]; const dist = [box5[2] * scaleFact, box5[3] * scaleFact];
const box4 = [boxRaw[0] * outputSize2[0], boxRaw[1] * outputSize2[1], boxRaw[2] * outputSize2[0], boxRaw[3] * outputSize2[1]]; const newBox = [
detected.push({ box: box4, boxRaw, score: scores[i] }); box5[0] - (dist[0] - box5[2]) / 2,
} box5[1] - (dist[1] - box5[3]) / 2,
Object.keys(t).forEach((tensor3) => tfjs_esm_exports.dispose(t[tensor3])); dist[0],
return detected; dist[1]
];
return newBox;
}
function crop(box5) {
const yxBox = [Math.max(0, box5[1]), Math.max(0, box5[0]), Math.min(1, box5[3] + box5[1]), Math.min(1, box5[2] + box5[0])];
return yxBox;
} }
// src/body/blazepose.ts // src/body/blazepose.ts
@ -5245,7 +5243,7 @@ var outputNodes = {
detector: [] detector: []
}; };
var cache = null; var cache = null;
var lastBox; var cropBox;
var padding = [[0, 0], [0, 0], [0, 0], [0, 0]]; var padding = [[0, 0], [0, 0], [0, 0], [0, 0]];
var lastTime5 = 0; var lastTime5 = 0;
var sigmoid3 = (x) => 1 - 1 / (1 + Math.exp(x)); var sigmoid3 = (x) => 1 - 1 / (1 + Math.exp(x));
@ -5282,39 +5280,37 @@ async function loadPose(config3) {
log("cached model:", models.landmarks["modelUrl"]); log("cached model:", models.landmarks["modelUrl"]);
return models.landmarks; return models.landmarks;
} }
function calculateBoxes(keypoints, outputSize2) { async function prepareImage(input, size2) {
const x = keypoints.map((a) => a.position[0]);
const y = keypoints.map((a) => a.position[1]);
const keypointsBox = [Math.min(...x), Math.min(...y), Math.max(...x) - Math.min(...x), Math.max(...y) - Math.min(...y)];
const keypointsBoxRaw = [keypointsBox[0] / outputSize2[0], keypointsBox[1] / outputSize2[1], keypointsBox[2] / outputSize2[0], keypointsBox[3] / outputSize2[1]];
return { keypointsBox, keypointsBoxRaw };
}
async function prepareImage(input, size2, box4) {
const t = {}; const t = {};
if (!input.shape || !input.shape[1] || !input.shape[2]) if (!input.shape || !input.shape[1] || !input.shape[2])
return input; return input;
let final; let final;
if (cropBox) {
t.cropped = tfjs_esm_exports.image.cropAndResize(input, [cropBox], [0], [input.shape[1], input.shape[2]]);
}
if (input.shape[1] !== input.shape[2]) { if (input.shape[1] !== input.shape[2]) {
const height = box4 ? [Math.trunc(input.shape[1] * box4[1]), Math.trunc(input.shape[1] * (box4[1] + box4[3]))] : [input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0, input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0]; const height = [
const width = box4 ? [Math.trunc(input.shape[2] * box4[0]), Math.trunc(input.shape[2] * (box4[0] + box4[2]))] : [input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0, input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0]; input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0,
input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0
];
const width = [
input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0,
input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0
];
padding = [ padding = [
[0, 0], [0, 0],
height, height,
width, width,
[0, 0] [0, 0]
]; ];
if (box4) { t.pad = tfjs_esm_exports.pad(t.cropped || input, padding);
t.resize = tfjs_esm_exports.image.cropAndResize(input, [box4], [0], [size2, size2]); t.resize = tfjs_esm_exports.image.resizeBilinear(t.pad, [size2, size2]);
} else {
t.pad = tfjs_esm_exports.pad(input, padding);
t.resize = tfjs_esm_exports.image.resizeBilinear(t.pad, [size2, size2]);
}
final = tfjs_esm_exports.div(t.resize, constants.tf255); final = tfjs_esm_exports.div(t.resize, constants.tf255);
} else if (input.shape[1] !== size2) { } else if (input.shape[1] !== size2) {
t.resize = tfjs_esm_exports.image.resizeBilinear(input, [size2, size2]); t.resize = tfjs_esm_exports.image.resizeBilinear(t.cropped || input, [size2, size2]);
final = tfjs_esm_exports.div(t.resize, constants.tf255); final = tfjs_esm_exports.div(t.resize, constants.tf255);
} else { } else {
final = tfjs_esm_exports.div(input, constants.tf255); final = tfjs_esm_exports.div(t.cropped || input, constants.tf255);
} }
Object.keys(t).forEach((tensor3) => tfjs_esm_exports.dispose(t[tensor3])); Object.keys(t).forEach((tensor3) => tfjs_esm_exports.dispose(t[tensor3]));
return final; return final;
@ -5328,19 +5324,21 @@ function rescaleKeypoints(keypoints, outputSize2) {
]; ];
kpt4.positionRaw = [kpt4.position[0] / outputSize2[0], kpt4.position[1] / outputSize2[1], kpt4.position[2]]; kpt4.positionRaw = [kpt4.position[0] / outputSize2[0], kpt4.position[1] / outputSize2[1], kpt4.position[2]];
} }
return keypoints; if (cropBox) {
} for (const kpt4 of keypoints) {
function rescaleBoxes(boxes, outputSize2) { kpt4.positionRaw = [
for (const box4 of boxes) { kpt4.positionRaw[0] + cropBox[1],
box4.box = [ kpt4.positionRaw[1] + cropBox[0],
Math.trunc(box4.box[0] * (outputSize2[0] + padding[2][0] + padding[2][1]) / outputSize2[0]), kpt4.positionRaw[2]
Math.trunc(box4.box[1] * (outputSize2[1] + padding[1][0] + padding[1][1]) / outputSize2[1]), ];
Math.trunc(box4.box[2] * (outputSize2[0] + padding[2][0] + padding[2][1]) / outputSize2[0]), kpt4.position = [
Math.trunc(box4.box[3] * (outputSize2[1] + padding[1][0] + padding[1][1]) / outputSize2[1]) Math.trunc(kpt4.positionRaw[0] * outputSize2[0]),
]; Math.trunc(kpt4.positionRaw[1] * outputSize2[1]),
box4.boxRaw = [box4.box[0] / outputSize2[0], box4.box[1] / outputSize2[1], box4.box[2] / outputSize2[0], box4.box[3] / outputSize2[1]]; kpt4.positionRaw[2]
];
}
} }
return boxes; return keypoints;
} }
async function detectLandmarks(input, config3, outputSize2) { async function detectLandmarks(input, config3, outputSize2) {
var _a; var _a;
@ -5362,7 +5360,8 @@ async function detectLandmarks(input, config3, outputSize2) {
if (poseScore < (config3.body.minConfidence || 0)) if (poseScore < (config3.body.minConfidence || 0))
return null; return null;
const keypoints = rescaleKeypoints(keypointsRelative, outputSize2); const keypoints = rescaleKeypoints(keypointsRelative, outputSize2);
const boxes = calculateBoxes(keypoints, [outputSize2[0], outputSize2[1]]); const kpts = keypoints.map((k) => k.position);
const boxes = calc(kpts, [outputSize2[0], outputSize2[1]]);
const annotations2 = {}; const annotations2 = {};
for (const [name, indexes] of Object.entries(connected)) { for (const [name, indexes] of Object.entries(connected)) {
const pt = []; const pt = [];
@ -5374,22 +5373,9 @@ async function detectLandmarks(input, config3, outputSize2) {
} }
annotations2[name] = pt; annotations2[name] = pt;
} }
const body4 = { id: 0, score: Math.trunc(100 * poseScore) / 100, box: boxes.keypointsBox, boxRaw: boxes.keypointsBoxRaw, keypoints, annotations: annotations2 }; const body4 = { id: 0, score: Math.trunc(100 * poseScore) / 100, box: boxes.box, boxRaw: boxes.boxRaw, keypoints, annotations: annotations2 };
return body4; return body4;
} }
async function detectBoxes(input, config3, outputSize2) {
var _a;
const t = {};
t.res = (_a = models.detector) == null ? void 0 : _a.execute(input, ["Identity"]);
t.logitsRaw = tfjs_esm_exports.slice(t.res, [0, 0, 0], [1, -1, 1]);
t.boxesRaw = tfjs_esm_exports.slice(t.res, [0, 0, 1], [1, -1, -1]);
t.logits = tfjs_esm_exports.squeeze(t.logitsRaw);
t.boxes = tfjs_esm_exports.squeeze(t.boxesRaw);
const boxes = await decode(t.boxes, t.logits, config3, outputSize2);
rescaleBoxes(boxes, outputSize2);
Object.keys(t).forEach((tensor3) => tfjs_esm_exports.dispose(t[tensor3]));
return boxes;
}
async function predict5(input, config3) { async function predict5(input, config3) {
const outputSize2 = [input.shape[2] || 0, input.shape[1] || 0]; const outputSize2 = [input.shape[2] || 0, input.shape[1] || 0];
const skipTime = (config3.body.skipTime || 0) > now() - lastTime5; const skipTime = (config3.body.skipTime || 0) > now() - lastTime5;
@ -5398,26 +5384,13 @@ async function predict5(input, config3) {
skipped5++; skipped5++;
} else { } else {
const t = {}; const t = {};
if (config3.body["detector"] && config3.body["detector"]["enabled"]) { t.landmarks = await prepareImage(input, 256);
t.detector = await prepareImage(input, 224); cache = await detectLandmarks(t.landmarks, config3, outputSize2);
const boxes = await detectBoxes(t.detector, config3, outputSize2);
if (boxes && boxes.length === 1) {
t.landmarks = await prepareImage(input, 256, boxes[0].box);
cache = await detectLandmarks(t.landmarks, config3, outputSize2);
}
if (cache)
cache.score = boxes[0].score;
} else {
t.landmarks = await prepareImage(input, 256, lastBox);
cache = await detectLandmarks(t.landmarks, config3, outputSize2);
}
Object.keys(t).forEach((tensor3) => tfjs_esm_exports.dispose(t[tensor3])); Object.keys(t).forEach((tensor3) => tfjs_esm_exports.dispose(t[tensor3]));
lastTime5 = now(); lastTime5 = now();
skipped5 = 0; skipped5 = 0;
} }
if (cache) return cache ? [cache] : [];
return [cache];
return [];
} }
// src/object/labels.ts // src/object/labels.ts
@ -5555,13 +5528,13 @@ async function process3(res, outputShape, config3) {
detections[0][id][2] / inputSize4 - x, detections[0][id][2] / inputSize4 - x,
detections[0][id][3] / inputSize4 - y detections[0][id][3] / inputSize4 - y
]; ];
const box4 = [ const box5 = [
Math.trunc(boxRaw[0] * outputShape[0]), Math.trunc(boxRaw[0] * outputShape[0]),
Math.trunc(boxRaw[1] * outputShape[1]), Math.trunc(boxRaw[1] * outputShape[1]),
Math.trunc(boxRaw[2] * outputShape[0]), Math.trunc(boxRaw[2] * outputShape[0]),
Math.trunc(boxRaw[3] * outputShape[1]) Math.trunc(boxRaw[3] * outputShape[1])
]; ];
results.push({ id: i++, score, class: classVal, label, box: box4, boxRaw }); results.push({ id: i++, score, class: classVal, label, box: box5, boxRaw });
} }
Object.keys(t).forEach((tensor3) => tfjs_esm_exports.dispose(t[tensor3])); Object.keys(t).forEach((tensor3) => tfjs_esm_exports.dispose(t[tensor3]));
return results; return results;
@ -5679,10 +5652,10 @@ async function predict7(image29, config3) {
tfjs_esm_exports.dispose(tensor3); tfjs_esm_exports.dispose(tensor3);
if (resT) { if (resT) {
cache2.keypoints.length = 0; cache2.keypoints.length = 0;
const squeeze11 = resT.squeeze(); const squeeze10 = resT.squeeze();
tfjs_esm_exports.dispose(resT); tfjs_esm_exports.dispose(resT);
const stack5 = squeeze11.unstack(2); const stack5 = squeeze10.unstack(2);
tfjs_esm_exports.dispose(squeeze11); tfjs_esm_exports.dispose(squeeze10);
for (let id = 0; id < stack5.length; id++) { for (let id = 0; id < stack5.length; id++) {
const [x2, y2, partScore] = await max2d(stack5[id], config3.body.minConfidence); const [x2, y2, partScore] = await max2d(stack5[id], config3.body.minConfidence);
if (partScore > (((_a = config3.body) == null ? void 0 : _a.minConfidence) || 0)) { if (partScore > (((_a = config3.body) == null ? void 0 : _a.minConfidence) || 0)) {
@ -5894,20 +5867,20 @@ var getLeftToRightEyeDepthDifference = (rawCoords) => {
return leftEyeZ - rightEyeZ; return leftEyeZ - rightEyeZ;
}; };
var getEyeBox = (rawCoords, face5, eyeInnerCornerIndex, eyeOuterCornerIndex, meshSize, flip = false) => { var getEyeBox = (rawCoords, face5, eyeInnerCornerIndex, eyeOuterCornerIndex, meshSize, flip = false) => {
const box4 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge)); const box5 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge));
const boxSize = getBoxSize(box4); const boxSize = getBoxSize(box5);
let crop2 = tfjs_esm_exports.image.cropAndResize(face5, [[ let crop2 = tfjs_esm_exports.image.cropAndResize(face5, [[
box4.startPoint[1] / meshSize, box5.startPoint[1] / meshSize,
box4.startPoint[0] / meshSize, box5.startPoint[0] / meshSize,
box4.endPoint[1] / meshSize, box5.endPoint[1] / meshSize,
box4.endPoint[0] / meshSize box5.endPoint[0] / meshSize
]], [0], [inputSize5, inputSize5]); ]], [0], [inputSize5, inputSize5]);
if (flip && env.kernels.includes("flipleftright")) { if (flip && env.kernels.includes("flipleftright")) {
const flipped = tfjs_esm_exports.image.flipLeftRight(crop2); const flipped = tfjs_esm_exports.image.flipLeftRight(crop2);
tfjs_esm_exports.dispose(crop2); tfjs_esm_exports.dispose(crop2);
crop2 = flipped; crop2 = flipped;
} }
return { box: box4, boxSize, crop: crop2 }; return { box: box5, boxSize, crop: crop2 };
}; };
var getEyeCoords = (eyeData, eyeBox, eyeBoxSize, flip = false) => { var getEyeCoords = (eyeData, eyeBox, eyeBoxSize, flip = false) => {
const eyeRawCoords = []; const eyeRawCoords = [];
@ -6001,7 +5974,7 @@ async function predict10(input, config3) {
const newCache = []; const newCache = [];
let id = 0; let id = 0;
for (let i = 0; i < boxCache.length; i++) { for (let i = 0; i < boxCache.length; i++) {
let box4 = boxCache[i]; let box5 = boxCache[i];
let angle = 0; let angle = 0;
let rotationMatrix; let rotationMatrix;
const face5 = { const face5 = {
@ -6015,20 +5988,20 @@ async function predict10(input, config3) {
faceScore: 0, faceScore: 0,
annotations: {} annotations: {}
}; };
[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) ? inputSize6 : size()); [angle, rotationMatrix, face5.tensor] = correctFaceRotation((_d = config3.face.detector) == null ? void 0 : _d.rotation, box5, input, ((_e = config3.face.mesh) == null ? void 0 : _e.enabled) ? inputSize6 : size());
if ((_f = config3 == null ? void 0 : config3.filter) == null ? void 0 : _f.equalization) { if ((_f = config3 == null ? void 0 : config3.filter) == null ? void 0 : _f.equalization) {
const equilized = await histogramEqualization(face5.tensor); const equilized = await histogramEqualization(face5.tensor);
tfjs_esm_exports.dispose(face5.tensor); tfjs_esm_exports.dispose(face5.tensor);
face5.tensor = equilized; face5.tensor = equilized;
} }
face5.boxScore = Math.round(100 * box4.confidence) / 100; face5.boxScore = Math.round(100 * box5.confidence) / 100;
if (!((_g = config3.face.mesh) == null ? void 0 : _g.enabled)) { if (!((_g = config3.face.mesh) == null ? void 0 : _g.enabled)) {
face5.box = getClampedBox(box4, input); face5.box = getClampedBox(box5, input);
face5.boxRaw = getRawBox(box4, input); face5.boxRaw = getRawBox(box5, input);
face5.score = face5.boxScore; face5.score = face5.boxScore;
face5.mesh = box4.landmarks.map((pt) => [ face5.mesh = box5.landmarks.map((pt) => [
(box4.startPoint[0] + box4.endPoint[0]) / 2 + (box4.endPoint[0] + box4.startPoint[0]) * pt[0] / size(), (box5.startPoint[0] + box5.endPoint[0]) / 2 + (box5.endPoint[0] + box5.startPoint[0]) * pt[0] / size(),
(box4.startPoint[1] + box4.endPoint[1]) / 2 + (box4.endPoint[1] + box4.startPoint[1]) * pt[1] / size() (box5.startPoint[1] + box5.endPoint[1]) / 2 + (box5.endPoint[1] + box5.startPoint[1]) * pt[1] / size()
]); ]);
face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]); face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]);
for (const key of Object.keys(blazeFaceLandmarks)) for (const key of Object.keys(blazeFaceLandmarks))
@ -6044,24 +6017,24 @@ async function predict10(input, config3) {
let rawCoords = await coordsReshaped.array(); let rawCoords = await coordsReshaped.array();
tfjs_esm_exports.dispose([contourCoords, coordsReshaped, confidence, contours]); tfjs_esm_exports.dispose([contourCoords, coordsReshaped, confidence, contours]);
if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) { if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
box4.confidence = face5.faceScore; box5.confidence = face5.faceScore;
} else { } else {
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled) if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize6); rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize6);
face5.mesh = transformRawCoords(rawCoords, box4, angle, rotationMatrix, inputSize6); face5.mesh = transformRawCoords(rawCoords, box5, angle, rotationMatrix, inputSize6);
face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]); face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]);
for (const key of Object.keys(meshAnnotations)) for (const key of Object.keys(meshAnnotations))
face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]); face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]);
const boxCalculated = calculateLandmarksBoundingBox(face5.mesh); const boxCalculated = calculateLandmarksBoundingBox(face5.mesh);
const boxEnlarged = enlargeBox(boxCalculated, ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6); const boxEnlarged = enlargeBox(boxCalculated, ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6);
const boxSquared = squarifyBox(boxEnlarged); const boxSquared = squarifyBox(boxEnlarged);
box4 = { ...boxSquared, confidence: box4.confidence }; box5 = { ...boxSquared, confidence: box5.confidence };
face5.box = getClampedBox(box4, input); face5.box = getClampedBox(box5, input);
face5.boxRaw = getRawBox(box4, input); face5.boxRaw = getRawBox(box5, input);
face5.score = face5.faceScore; face5.score = face5.faceScore;
newCache.push(box4); newCache.push(box5);
tfjs_esm_exports.dispose(face5.tensor); tfjs_esm_exports.dispose(face5.tensor);
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_k = config3.face.detector) == null ? void 0 : _k.rotation, box4, input, inputSize6); [angle, rotationMatrix, face5.tensor] = correctFaceRotation((_k = config3.face.detector) == null ? void 0 : _k.rotation, box5, input, inputSize6);
} }
} }
faces.push(face5); faces.push(face5);
@ -6166,54 +6139,54 @@ async function predict11(image29, config3, idx, count2) {
} }
// src/hand/handposeutil.ts // src/hand/handposeutil.ts
function getBoxSize2(box4) { function getBoxSize2(box5) {
return [ return [
Math.abs(box4.endPoint[0] - box4.startPoint[0]), Math.abs(box5.endPoint[0] - box5.startPoint[0]),
Math.abs(box4.endPoint[1] - box4.startPoint[1]) Math.abs(box5.endPoint[1] - box5.startPoint[1])
]; ];
} }
function getBoxCenter2(box4) { function getBoxCenter2(box5) {
return [ return [
box4.startPoint[0] + (box4.endPoint[0] - box4.startPoint[0]) / 2, box5.startPoint[0] + (box5.endPoint[0] - box5.startPoint[0]) / 2,
box4.startPoint[1] + (box4.endPoint[1] - box4.startPoint[1]) / 2 box5.startPoint[1] + (box5.endPoint[1] - box5.startPoint[1]) / 2
]; ];
} }
function cutBoxFromImageAndResize2(box4, image29, cropSize) { function cutBoxFromImageAndResize2(box5, image29, cropSize) {
const h = image29.shape[1]; const h = image29.shape[1];
const w = image29.shape[2]; const w = image29.shape[2];
const boxes = [[ const boxes = [[
box4.startPoint[1] / h, box5.startPoint[1] / h,
box4.startPoint[0] / w, box5.startPoint[0] / w,
box4.endPoint[1] / h, box5.endPoint[1] / h,
box4.endPoint[0] / w box5.endPoint[0] / w
]]; ]];
return tfjs_esm_exports.image.cropAndResize(image29, boxes, [0], cropSize); return tfjs_esm_exports.image.cropAndResize(image29, boxes, [0], cropSize);
} }
function scaleBoxCoordinates2(box4, factor) { function scaleBoxCoordinates2(box5, factor) {
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]]; const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]]; const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
const palmLandmarks = box4.palmLandmarks.map((coord) => { const palmLandmarks = box5.palmLandmarks.map((coord) => {
const scaledCoord = [coord[0] * factor[0], coord[1] * factor[1]]; const scaledCoord = [coord[0] * factor[0], coord[1] * factor[1]];
return scaledCoord; return scaledCoord;
}); });
return { startPoint, endPoint, palmLandmarks, confidence: box4.confidence }; return { startPoint, endPoint, palmLandmarks, confidence: box5.confidence };
} }
function enlargeBox2(box4, factor = 1.5) { function enlargeBox2(box5, factor = 1.5) {
const center = getBoxCenter2(box4); const center = getBoxCenter2(box5);
const size2 = getBoxSize2(box4); const size2 = getBoxSize2(box5);
const newHalfSize = [factor * size2[0] / 2, factor * size2[1] / 2]; const newHalfSize = [factor * size2[0] / 2, factor * size2[1] / 2];
const startPoint = [center[0] - newHalfSize[0], center[1] - newHalfSize[1]]; const startPoint = [center[0] - newHalfSize[0], center[1] - newHalfSize[1]];
const endPoint = [center[0] + newHalfSize[0], center[1] + newHalfSize[1]]; const endPoint = [center[0] + newHalfSize[0], center[1] + newHalfSize[1]];
return { startPoint, endPoint, palmLandmarks: box4.palmLandmarks }; return { startPoint, endPoint, palmLandmarks: box5.palmLandmarks };
} }
function squarifyBox2(box4) { function squarifyBox2(box5) {
const centers = getBoxCenter2(box4); const centers = getBoxCenter2(box5);
const size2 = getBoxSize2(box4); const size2 = getBoxSize2(box5);
const maxEdge = Math.max(...size2); const maxEdge = Math.max(...size2);
const halfSize = maxEdge / 2; const halfSize = maxEdge / 2;
const startPoint = [centers[0] - halfSize, centers[1] - halfSize]; const startPoint = [centers[0] - halfSize, centers[1] - halfSize];
const endPoint = [centers[0] + halfSize, centers[1] + halfSize]; const endPoint = [centers[0] + halfSize, centers[1] + halfSize];
return { startPoint, endPoint, palmLandmarks: box4.palmLandmarks }; return { startPoint, endPoint, palmLandmarks: box5.palmLandmarks };
} }
function normalizeRadians2(angle) { function normalizeRadians2(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));
@ -9287,9 +9260,9 @@ var HandDetector = class {
p.slice = tfjs_esm_exports.slice(t.predictions, [index2, 5], [1, 14]); p.slice = tfjs_esm_exports.slice(t.predictions, [index2, 5], [1, 14]);
p.norm = this.normalizeLandmarks(p.slice, index2); p.norm = this.normalizeLandmarks(p.slice, index2);
p.palmLandmarks = tfjs_esm_exports.reshape(p.norm, [-1, 2]); p.palmLandmarks = tfjs_esm_exports.reshape(p.norm, [-1, 2]);
const box4 = await p.box.data(); const box5 = await p.box.data();
const startPoint = box4.slice(0, 2); const startPoint = box5.slice(0, 2);
const endPoint = box4.slice(2, 4); const endPoint = box5.slice(2, 4);
const palmLandmarks = await p.palmLandmarks.array(); const palmLandmarks = await p.palmLandmarks.array();
const hand3 = { startPoint, endPoint, palmLandmarks, confidence: scores[index2] }; const hand3 = { startPoint, endPoint, palmLandmarks, confidence: scores[index2] };
const scaled = scaleBoxCoordinates2(hand3, [input.shape[2] / this.inputSize, input.shape[1] / this.inputSize]); const scaled = scaleBoxCoordinates2(hand3, [input.shape[2] / this.inputSize, input.shape[1] / this.inputSize]);
@ -9875,24 +9848,24 @@ async function predict12(input, config3) {
} }
} }
const keypoints = predictions[i].landmarks; const keypoints = predictions[i].landmarks;
let box4 = [Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, 0, 0]; let box5 = [Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, 0, 0];
let boxRaw = [0, 0, 0, 0]; let boxRaw = [0, 0, 0, 0];
if (keypoints && keypoints.length > 0) { if (keypoints && keypoints.length > 0) {
for (const pt of keypoints) { for (const pt of keypoints) {
if (pt[0] < box4[0]) if (pt[0] < box5[0])
box4[0] = pt[0]; box5[0] = pt[0];
if (pt[1] < box4[1]) if (pt[1] < box5[1])
box4[1] = pt[1]; box5[1] = pt[1];
if (pt[0] > box4[2]) if (pt[0] > box5[2])
box4[2] = pt[0]; box5[2] = pt[0];
if (pt[1] > box4[3]) if (pt[1] > box5[3])
box4[3] = pt[1]; box5[3] = pt[1];
} }
box4[2] -= box4[0]; box5[2] -= box5[0];
box4[3] -= box4[1]; box5[3] -= box5[1];
boxRaw = [box4[0] / (input.shape[2] || 0), box4[1] / (input.shape[1] || 0), box4[2] / (input.shape[2] || 0), box4[3] / (input.shape[1] || 0)]; boxRaw = [box5[0] / (input.shape[2] || 0), box5[1] / (input.shape[1] || 0), box5[2] / (input.shape[2] || 0), box5[3] / (input.shape[1] || 0)];
} else { } else {
box4 = predictions[i].box ? [ box5 = predictions[i].box ? [
Math.trunc(Math.max(0, predictions[i].box.topLeft[0])), Math.trunc(Math.max(0, predictions[i].box.topLeft[0])),
Math.trunc(Math.max(0, predictions[i].box.topLeft[1])), Math.trunc(Math.max(0, predictions[i].box.topLeft[1])),
Math.trunc(Math.min(input.shape[2] || 0, predictions[i].box.bottomRight[0]) - Math.max(0, predictions[i].box.topLeft[0])), Math.trunc(Math.min(input.shape[2] || 0, predictions[i].box.bottomRight[0]) - Math.max(0, predictions[i].box.topLeft[0])),
@ -9912,7 +9885,7 @@ async function predict12(input, config3) {
boxScore: Math.round(100 * predictions[i].boxConfidence) / 100, boxScore: Math.round(100 * predictions[i].boxConfidence) / 100,
fingerScore: Math.round(100 * predictions[i].fingerConfidence) / 100, fingerScore: Math.round(100 * predictions[i].fingerConfidence) / 100,
label: "hand", label: "hand",
box: box4, box: box5,
boxRaw, boxRaw,
keypoints, keypoints,
annotations: annotations2, annotations: annotations2,
@ -9953,40 +9926,6 @@ async function load13(config3) {
return [handDetectorModel, handPoseModel]; return [handDetectorModel, handPoseModel];
} }
// src/util/box.ts
function calc(keypoints, outputSize2 = [1, 1]) {
const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
const box4 = [min2[0], min2[1], max4[0] - min2[0], max4[1] - min2[1]];
const boxRaw = [box4[0] / outputSize2[0], box4[1] / outputSize2[1], box4[2] / outputSize2[0], box4[3] / outputSize2[1]];
return { box: box4, boxRaw };
}
function square(keypoints, outputSize2 = [1, 1]) {
const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
const center = [(min2[0] + max4[0]) / 2, (min2[1] + max4[1]) / 2];
const dist = Math.max(center[0] - min2[0], center[1] - min2[1], -center[0] + max4[0], -center[1] + max4[1]);
const box4 = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];
const boxRaw = [box4[0] / outputSize2[0], box4[1] / outputSize2[1], box4[2] / outputSize2[0], box4[3] / outputSize2[1]];
return { box: box4, boxRaw };
}
function scale(box4, scaleFact) {
const dist = [box4[2] * scaleFact, box4[3] * scaleFact];
const newBox = [
box4[0] - (dist[0] - box4[2]) / 2,
box4[1] - (dist[1] - box4[3]) / 2,
dist[0],
dist[1]
];
return newBox;
}
function crop(box4) {
const yxBox = [Math.max(0, box4[1]), Math.max(0, box4[0]), Math.min(1, box4[3] + box4[1]), Math.min(1, box4[2] + box4[0])];
return yxBox;
}
// src/hand/handtrack.ts // src/hand/handtrack.ts
var models2 = [null, null]; var models2 = [null, null];
var modelOutputNodes = ["StatefulPartitionedCall/Postprocessor/Slice", "StatefulPartitionedCall/Postprocessor/ExpandDims_1"]; var modelOutputNodes = ["StatefulPartitionedCall/Postprocessor/Slice", "StatefulPartitionedCall/Postprocessor/ExpandDims_1"];
@ -10004,11 +9943,11 @@ var cache3 = {
hands: [] hands: []
}; };
var fingerMap = { var fingerMap = {
thumb: [1, 2, 3, 4], thumb: [0, 1, 2, 3, 4],
index: [5, 6, 7, 8], index: [0, 5, 6, 7, 8],
middle: [9, 10, 11, 12], middle: [0, 9, 10, 11, 12],
ring: [13, 14, 15, 16], ring: [0, 13, 14, 15, 16],
pinky: [17, 18, 19, 20], pinky: [0, 17, 18, 19, 20],
palm: [0] palm: [0]
}; };
async function loadDetect2(config3) { async function loadDetect2(config3) {
@ -10553,7 +10492,7 @@ async function process4(res, inputSize9, outputShape, config3) {
]; ];
let boxRaw = [x, y, w, h]; let boxRaw = [x, y, w, h];
boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1))); boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1)));
const box4 = [ const box5 = [
boxRaw[0] * outputShape[0], boxRaw[0] * outputShape[0],
boxRaw[1] * outputShape[1], boxRaw[1] * outputShape[1],
boxRaw[2] * outputShape[0], boxRaw[2] * outputShape[0],
@ -10564,7 +10503,7 @@ async function process4(res, inputSize9, outputShape, config3) {
score: Math.round(100 * score) / 100, score: Math.round(100 * score) / 100,
class: j + 1, class: j + 1,
label: labels[j].label, label: labels[j].label,
box: box4.map((a) => Math.trunc(a)), box: box5.map((a) => Math.trunc(a)),
boxRaw boxRaw
}; };
results.push(result); results.push(result);
@ -10904,7 +10843,7 @@ function getInstanceScore(existingPoses, keypoints) {
}, 0); }, 0);
return notOverlappedKeypointScores / keypoints.length; return notOverlappedKeypointScores / keypoints.length;
} }
function decode2(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) { function decode(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) {
const poses = []; const poses = [];
const queue = buildPartWithScoreQueue(minConfidence2, scores); const queue = buildPartWithScoreQueue(minConfidence2, scores);
while (poses.length < maxDetected && !queue.empty()) { while (poses.length < maxDetected && !queue.empty()) {
@ -10915,9 +10854,9 @@ function decode2(offsets, scores, displacementsFwd, displacementsBwd, maxDetecte
let keypoints = decodePose(root, scores, offsets, displacementsFwd, displacementsBwd); let keypoints = decodePose(root, scores, offsets, displacementsFwd, displacementsBwd);
keypoints = keypoints.filter((a) => a.score > minConfidence2); keypoints = keypoints.filter((a) => a.score > minConfidence2);
const score = getInstanceScore(poses, keypoints); const score = getInstanceScore(poses, keypoints);
const box4 = getBoundingBox(keypoints); const box5 = getBoundingBox(keypoints);
if (score > minConfidence2) if (score > minConfidence2)
poses.push({ keypoints, box: box4, score: Math.round(100 * score) / 100 }); poses.push({ keypoints, box: box5, score: Math.round(100 * score) / 100 });
} }
return poses; return poses;
} }
@ -10935,7 +10874,7 @@ async function predict17(input, config3) {
const buffers = await Promise.all(res.map((tensor3) => tensor3.buffer())); const buffers = await Promise.all(res.map((tensor3) => tensor3.buffer()));
for (const t of res) for (const t of res)
tfjs_esm_exports.dispose(t); tfjs_esm_exports.dispose(t);
const decoded = await decode2(buffers[0], buffers[1], buffers[2], buffers[3], config3.body.maxDetected, config3.body.minConfidence); const decoded = await decode(buffers[0], buffers[1], buffers[2], buffers[3], config3.body.maxDetected, config3.body.minConfidence);
if (!model16.inputs[0].shape) if (!model16.inputs[0].shape)
return []; return [];
const scaled = scalePoses(decoded, [input.shape[1], input.shape[2]], [model16.inputs[0].shape[2], model16.inputs[0].shape[1]]); const scaled = scalePoses(decoded, [input.shape[1], input.shape[2]], [model16.inputs[0].shape[2], model16.inputs[0].shape[1]]);
@ -11988,7 +11927,7 @@ var calculateFaceAngle = (face5, imageSize) => {
thetaY = 0; thetaY = 0;
if (isNaN(thetaZ)) if (isNaN(thetaZ))
thetaZ = 0; thetaZ = 0;
return { pitch: 2 * -thetaX, yaw: 2 * -thetaY, roll: 2 * -thetaZ }; return { pitch: -thetaX, yaw: -thetaY, roll: -thetaZ };
}; };
const meshToEulerAngle = (mesh2) => { const meshToEulerAngle = (mesh2) => {
const radians = (a1, a2, b1, b2) => Math.atan2(b2 - a2, b1 - a1); const radians = (a1, a2, b1, b2) => Math.atan2(b2 - a2, b1 - a1);
@ -12334,7 +12273,7 @@ function calc2(newResult, config3) {
bufferedResult.body = JSON.parse(JSON.stringify(newResult.body)); bufferedResult.body = JSON.parse(JSON.stringify(newResult.body));
} else { } else {
for (let i = 0; i < newResult.body.length; i++) { for (let i = 0; i < newResult.body.length; i++) {
const box4 = newResult.body[i].box.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor); const box5 = newResult.body[i].box.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor);
const boxRaw = newResult.body[i].boxRaw.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + newBoxCoord) / bufferedFactor); const boxRaw = newResult.body[i].boxRaw.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + newBoxCoord) / bufferedFactor);
const keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({ const keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({
score: newKpt.score, score: newKpt.score,
@ -12368,14 +12307,14 @@ function calc2(newResult, config3) {
} }
annotations2[name] = pt; annotations2[name] = pt;
} }
bufferedResult.body[i] = { ...newResult.body[i], box: box4, boxRaw, keypoints, annotations: annotations2 }; bufferedResult.body[i] = { ...newResult.body[i], box: box5, boxRaw, keypoints, annotations: annotations2 };
} }
} }
if (!bufferedResult.hand || newResult.hand.length !== bufferedResult.hand.length) { if (!bufferedResult.hand || newResult.hand.length !== bufferedResult.hand.length) {
bufferedResult.hand = JSON.parse(JSON.stringify(newResult.hand)); bufferedResult.hand = JSON.parse(JSON.stringify(newResult.hand));
} else { } else {
for (let i = 0; i < newResult.hand.length; i++) { for (let i = 0; i < newResult.hand.length; i++) {
const box4 = newResult.hand[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].box[j] + b) / bufferedFactor); const box5 = newResult.hand[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].box[j] + b) / bufferedFactor);
const boxRaw = newResult.hand[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].boxRaw[j] + b) / bufferedFactor); const boxRaw = newResult.hand[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].boxRaw[j] + b) / bufferedFactor);
if (bufferedResult.hand[i].keypoints.length !== newResult.hand[i].keypoints.length) if (bufferedResult.hand[i].keypoints.length !== newResult.hand[i].keypoints.length)
bufferedResult.hand[i].keypoints = newResult.hand[i].keypoints; bufferedResult.hand[i].keypoints = newResult.hand[i].keypoints;
@ -12389,14 +12328,14 @@ function calc2(newResult, config3) {
annotations2[key] = newResult.hand[i].annotations[key] && newResult.hand[i].annotations[key][0] ? newResult.hand[i].annotations[key].map((val, j) => val.map((coord, k) => ((bufferedFactor - 1) * bufferedResult.hand[i].annotations[key][j][k] + coord) / bufferedFactor)) : null; annotations2[key] = newResult.hand[i].annotations[key] && newResult.hand[i].annotations[key][0] ? newResult.hand[i].annotations[key].map((val, j) => val.map((coord, k) => ((bufferedFactor - 1) * bufferedResult.hand[i].annotations[key][j][k] + coord) / bufferedFactor)) : null;
} }
} }
bufferedResult.hand[i] = { ...newResult.hand[i], box: box4, boxRaw, keypoints, annotations: annotations2 }; bufferedResult.hand[i] = { ...newResult.hand[i], box: box5, boxRaw, keypoints, annotations: annotations2 };
} }
} }
if (!bufferedResult.face || newResult.face.length !== bufferedResult.face.length) { if (!bufferedResult.face || newResult.face.length !== bufferedResult.face.length) {
bufferedResult.face = JSON.parse(JSON.stringify(newResult.face)); bufferedResult.face = JSON.parse(JSON.stringify(newResult.face));
} else { } else {
for (let i = 0; i < newResult.face.length; i++) { for (let i = 0; i < newResult.face.length; i++) {
const box4 = newResult.face[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].box[j] + b) / bufferedFactor); const box5 = newResult.face[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].box[j] + b) / bufferedFactor);
const boxRaw = newResult.face[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].boxRaw[j] + b) / bufferedFactor); const boxRaw = newResult.face[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].boxRaw[j] + b) / bufferedFactor);
if (newResult.face[i].rotation) { if (newResult.face[i].rotation) {
const rotation = { matrix: [0, 0, 0, 0, 0, 0, 0, 0, 0], angle: { roll: 0, yaw: 0, pitch: 0 }, gaze: { bearing: 0, strength: 0 } }; const rotation = { matrix: [0, 0, 0, 0, 0, 0, 0, 0, 0], angle: { roll: 0, yaw: 0, pitch: 0 }, gaze: { bearing: 0, strength: 0 } };
@ -12410,18 +12349,18 @@ function calc2(newResult, config3) {
bearing: ((bufferedFactor - 1) * (((_u = (_t = bufferedResult.face[i].rotation) == null ? void 0 : _t.gaze) == null ? void 0 : _u.bearing) || 0) + (((_w = (_v = newResult.face[i].rotation) == null ? void 0 : _v.gaze) == null ? void 0 : _w.bearing) || 0)) / bufferedFactor, bearing: ((bufferedFactor - 1) * (((_u = (_t = bufferedResult.face[i].rotation) == null ? void 0 : _t.gaze) == null ? void 0 : _u.bearing) || 0) + (((_w = (_v = newResult.face[i].rotation) == null ? void 0 : _v.gaze) == null ? void 0 : _w.bearing) || 0)) / bufferedFactor,
strength: ((bufferedFactor - 1) * (((_y = (_x = bufferedResult.face[i].rotation) == null ? void 0 : _x.gaze) == null ? void 0 : _y.strength) || 0) + (((_A = (_z = newResult.face[i].rotation) == null ? void 0 : _z.gaze) == null ? void 0 : _A.strength) || 0)) / bufferedFactor strength: ((bufferedFactor - 1) * (((_y = (_x = bufferedResult.face[i].rotation) == null ? void 0 : _x.gaze) == null ? void 0 : _y.strength) || 0) + (((_A = (_z = newResult.face[i].rotation) == null ? void 0 : _z.gaze) == null ? void 0 : _A.strength) || 0)) / bufferedFactor
}; };
bufferedResult.face[i] = { ...newResult.face[i], rotation, box: box4, boxRaw }; bufferedResult.face[i] = { ...newResult.face[i], rotation, box: box5, boxRaw };
} }
bufferedResult.face[i] = { ...newResult.face[i], box: box4, boxRaw }; bufferedResult.face[i] = { ...newResult.face[i], box: box5, boxRaw };
} }
} }
if (!bufferedResult.object || newResult.object.length !== bufferedResult.object.length) { if (!bufferedResult.object || newResult.object.length !== bufferedResult.object.length) {
bufferedResult.object = JSON.parse(JSON.stringify(newResult.object)); bufferedResult.object = JSON.parse(JSON.stringify(newResult.object));
} else { } else {
for (let i = 0; i < newResult.object.length; i++) { for (let i = 0; i < newResult.object.length; i++) {
const box4 = newResult.object[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].box[j] + b) / bufferedFactor); const box5 = newResult.object[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].box[j] + b) / bufferedFactor);
const boxRaw = newResult.object[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].boxRaw[j] + b) / bufferedFactor); const boxRaw = newResult.object[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].boxRaw[j] + b) / bufferedFactor);
bufferedResult.object[i] = { ...newResult.object[i], box: box4, boxRaw }; bufferedResult.object[i] = { ...newResult.object[i], box: box5, boxRaw };
} }
} }
if (newResult.persons) { if (newResult.persons) {
@ -12430,7 +12369,7 @@ function calc2(newResult, config3) {
bufferedResult.persons = JSON.parse(JSON.stringify(newPersons)); bufferedResult.persons = JSON.parse(JSON.stringify(newPersons));
} else { } else {
for (let i = 0; i < newPersons.length; i++) { for (let i = 0; i < newPersons.length; i++) {
bufferedResult.persons[i].box = newPersons[i].box.map((box4, j) => ((bufferedFactor - 1) * bufferedResult.persons[i].box[j] + box4) / bufferedFactor); bufferedResult.persons[i].box = newPersons[i].box.map((box5, j) => ((bufferedFactor - 1) * bufferedResult.persons[i].box[j] + box5) / bufferedFactor);
} }
} }
} }
@ -12521,10 +12460,10 @@ function join2(faces, bodies, hands, gestures, shape) {
} }
const x = []; const x = [];
const y = []; const y = [];
const extractXY = (box4) => { const extractXY = (box5) => {
if (box4 && box4.length === 4) { if (box5 && box5.length === 4) {
x.push(box4[0], box4[0] + box4[2]); x.push(box5[0], box5[0] + box5[2]);
y.push(box4[1], box4[1] + box4[3]); y.push(box5[1], box5[1] + box5[3]);
} }
}; };
extractXY((_k = person2.face) == null ? void 0 : _k.box); extractXY((_k = person2.face) == null ? void 0 : _k.box);

File diff suppressed because one or more lines are too long

572
dist/human.esm.js vendored
View File

@ -49402,19 +49402,20 @@ var PackProgram = class {
this.packedInputs = false; this.packedInputs = false;
this.packedOutput = true; this.packedOutput = true;
this.outputShape = outputShape; this.outputShape = outputShape;
const rank = outputShape.length; this.rank = outputShape.length;
if (rank === 0) { this.enableShapeUniforms = useShapeUniforms(this.outputShape.length);
if (this.rank === 0) {
this.userCode = ` this.userCode = `
void main() { void main() {
setOutput(vec4(getA(), 0., 0., 0.)); setOutput(vec4(getA(), 0., 0., 0.));
} }
`; `;
} else { } else {
const channels = getChannels("rc", rank); const channels = getChannels("rc", this.rank);
const dtype = getCoordsDataType(rank); const dtype = getCoordsDataType(this.rank);
const outOfBoundsCondition = getOutOfBoundsCondition(rank, outputShape, channels); const outOfBoundsCondition = this.getOutOfBoundsCondition(channels);
const setup46 = getSetup(rank, outputShape[outputShape.length - 1], outputShape[outputShape.length - 2], channels); const setup46 = this.getSetup(channels);
const output = getOutput(outputShape, channels); const output = this.getOutput(channels);
this.userCode = ` this.userCode = `
void main() { void main() {
${dtype} rc = getOutputCoords(); ${dtype} rc = getOutputCoords();
@ -49430,61 +49431,62 @@ var PackProgram = class {
`; `;
} }
} }
}; getSourceCoordsArr(dims) {
function getSourceCoordsArr(rank, dims) { const coords32 = [];
const coords32 = []; for (let row = 0; row <= 1; row++) {
for (let row = 0; row <= 1; row++) { for (let col = 0; col <= 1; col++) {
for (let col = 0; col <= 1; col++) { let coord = `${row === 0 ? "r" : "rp1"}, ${col === 0 ? "c" : "cp1"}`;
let coord = `${row === 0 ? "r" : "rp1"}, ${col === 0 ? "c" : "cp1"}`; for (let d = 2; d < this.rank; d++) {
for (let d = 2; d < rank; d++) { coord = `${dims[dims.length - 1 - d]},` + coord;
coord = `${dims[dims.length - 1 - d]},` + coord; }
coords32.push(coord);
} }
coords32.push(coord);
} }
return coords32;
} }
return coords32; getOutOfBoundsCondition(dims) {
} if (this.rank === 1) {
function getOutOfBoundsCondition(rank, shape, dims) { return `rc > ${this.enableShapeUniforms ? "outShape" : this.outputShape[0]}`;
if (rank === 1) {
return `rc > ${shape[0]}`;
}
let cond = "";
for (let i = rank - 2; i < rank; i++) {
cond += `${dims[i]} >= ${shape[i]}`;
if (i < rank - 1) {
cond += "||";
} }
let cond = "";
for (let i = this.rank - 2; i < this.rank; i++) {
cond += `${dims[i]} >= ${this.enableShapeUniforms ? `outShape[${i}]` : this.outputShape[i]}`;
if (i < this.rank - 1) {
cond += "||";
}
}
return cond;
} }
return cond; getSetup(dims) {
} if (this.rank === 1) {
function getSetup(rank, cols, rows, dims) { return "";
if (rank === 1) { }
return ""; const innerDims = dims.slice(-2);
} const col = this.enableShapeUniforms ? `outShape[${this.rank} - 1]` : this.outputShape[this.rank - 1];
const innerDims = dims.slice(-2); const row = this.enableShapeUniforms ? `outShape[${this.rank} - 2]` : this.outputShape[this.rank - 2];
return ` return `
int r = ${innerDims[0]}; int r = ${innerDims[0]};
int c = ${innerDims[1]}; int c = ${innerDims[1]};
int rp1 = r + 1; int rp1 = r + 1;
int cp1 = c + 1; int cp1 = c + 1;
bool cEdge = cp1 >= ${cols}; bool cEdge = cp1 >= ${col};
bool rEdge = rp1 >= ${rows}; bool rEdge = rp1 >= ${row};
`; `;
}
function getOutput(shape, dims) {
const rank = shape.length;
const sourceCoords = getSourceCoordsArr(rank, dims);
if (rank === 1) {
return `getA(rc),
rc + 1 >= ${shape[0]} ? 0. : getA(rc + 1),
0, 0`;
} }
return `getA(${sourceCoords[0]}), getOutput(dims) {
cEdge ? 0. : getA(${sourceCoords[1]}), const sourceCoords = this.getSourceCoordsArr(dims);
rEdge ? 0. : getA(${sourceCoords[2]}), if (this.rank === 1) {
rEdge || cEdge ? 0. : getA(${sourceCoords[3]})`; return `getA(rc),
} rc + 1 >= ${this.enableShapeUniforms ? "outShape" : this.outputShape[0]} ? 0. : getA(rc + 1),
0, 0`;
}
return `getA(${sourceCoords[0]}),
cEdge ? 0. : getA(${sourceCoords[1]}),
rEdge ? 0. : getA(${sourceCoords[2]}),
rEdge || cEdge ? 0. : getA(${sourceCoords[3]})`;
}
};
var ReshapePackedProgram = class { var ReshapePackedProgram = class {
constructor(outputShape, inputShape) { constructor(outputShape, inputShape) {
this.variableNames = ["A"]; this.variableNames = ["A"];
@ -49827,6 +49829,7 @@ var UnpackProgram = class {
this.packedInputs = true; this.packedInputs = true;
this.packedOutput = false; this.packedOutput = false;
this.outputShape = outputShape; this.outputShape = outputShape;
this.enableShapeUniforms = useShapeUniforms(this.outputShape.length);
const rank = outputShape.length; const rank = outputShape.length;
const channels = getChannels("rc", rank); const channels = getChannels("rc", rank);
const dtype = getCoordsDataType(rank); const dtype = getCoordsDataType(rank);
@ -70672,7 +70675,7 @@ registerBackend("wasm", async () => {
const { wasm } = await init(); const { wasm } = await init();
return new BackendWasm(wasm); return new BackendWasm(wasm);
}, WASM_PRIORITY); }, WASM_PRIORITY);
var externalVersion = "3.11.0-20211123"; var externalVersion = "3.11.0-20211124";
var version8 = { var version8 = {
tfjs: externalVersion, tfjs: externalVersion,
"tfjs-core": externalVersion, "tfjs-core": externalVersion,
@ -71818,8 +71821,8 @@ async function predict(image7, config3, idx, count3) {
if (!(model2 == null ? void 0 : model2.inputs[0].shape)) if (!(model2 == null ? void 0 : model2.inputs[0].shape))
return; return;
const t = {}; const t = {};
const box4 = [[0, 0.1, 0.9, 0.9]]; const box5 = [[0, 0.1, 0.9, 0.9]];
t.resize = image.cropAndResize(image7, box4, [0], [model2.inputs[0].shape[2], model2.inputs[0].shape[1]]); t.resize = image.cropAndResize(image7, box5, [0], [model2.inputs[0].shape[2], model2.inputs[0].shape[1]]);
const obj = { age: 0, gender: "unknown", genderScore: 0, race: [] }; const obj = { age: 0, gender: "unknown", genderScore: 0, race: [] };
if ((_a2 = config3.face["gear"]) == null ? void 0 : _a2.enabled) if ((_a2 = config3.face["gear"]) == null ? void 0 : _a2.enabled)
[t.age, t.gender, t.race] = model2.execute(t.resize, ["age_output", "gender_output", "race_output"]); [t.age, t.gender, t.race] = model2.execute(t.resize, ["age_output", "gender_output", "race_output"]);
@ -75303,44 +75306,44 @@ var UV33 = VTX33.map((x) => UV468[x]);
var UV7 = VTX7.map((x) => UV468[x]); var UV7 = VTX7.map((x) => UV468[x]);
// src/face/facemeshutil.ts // src/face/facemeshutil.ts
var getBoxSize = (box4) => [Math.abs(box4.endPoint[0] - box4.startPoint[0]), Math.abs(box4.endPoint[1] - box4.startPoint[1])]; var getBoxSize = (box5) => [Math.abs(box5.endPoint[0] - box5.startPoint[0]), Math.abs(box5.endPoint[1] - box5.startPoint[1])];
var getBoxCenter = (box4) => [box4.startPoint[0] + (box4.endPoint[0] - box4.startPoint[0]) / 2, box4.startPoint[1] + (box4.endPoint[1] - box4.startPoint[1]) / 2]; var getBoxCenter = (box5) => [box5.startPoint[0] + (box5.endPoint[0] - box5.startPoint[0]) / 2, box5.startPoint[1] + (box5.endPoint[1] - box5.startPoint[1]) / 2];
var getClampedBox = (box4, input2) => box4 ? [ var getClampedBox = (box5, input2) => box5 ? [
Math.trunc(Math.max(0, box4.startPoint[0])), Math.trunc(Math.max(0, box5.startPoint[0])),
Math.trunc(Math.max(0, box4.startPoint[1])), Math.trunc(Math.max(0, box5.startPoint[1])),
Math.trunc(Math.min(input2.shape[2] || 0, box4.endPoint[0]) - Math.max(0, box4.startPoint[0])), Math.trunc(Math.min(input2.shape[2] || 0, box5.endPoint[0]) - Math.max(0, box5.startPoint[0])),
Math.trunc(Math.min(input2.shape[1] || 0, box4.endPoint[1]) - Math.max(0, box4.startPoint[1])) Math.trunc(Math.min(input2.shape[1] || 0, box5.endPoint[1]) - Math.max(0, box5.startPoint[1]))
] : [0, 0, 0, 0]; ] : [0, 0, 0, 0];
var getRawBox = (box4, input2) => box4 ? [ var getRawBox = (box5, input2) => box5 ? [
box4.startPoint[0] / (input2.shape[2] || 0), box5.startPoint[0] / (input2.shape[2] || 0),
box4.startPoint[1] / (input2.shape[1] || 0), box5.startPoint[1] / (input2.shape[1] || 0),
(box4.endPoint[0] - box4.startPoint[0]) / (input2.shape[2] || 0), (box5.endPoint[0] - box5.startPoint[0]) / (input2.shape[2] || 0),
(box4.endPoint[1] - box4.startPoint[1]) / (input2.shape[1] || 0) (box5.endPoint[1] - box5.startPoint[1]) / (input2.shape[1] || 0)
] : [0, 0, 0, 0]; ] : [0, 0, 0, 0];
var scaleBoxCoordinates = (box4, factor) => { var scaleBoxCoordinates = (box5, factor) => {
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]]; const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]]; const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
return { startPoint, endPoint, landmarks: box4.landmarks, confidence: box4.confidence }; return { startPoint, endPoint, landmarks: box5.landmarks, confidence: box5.confidence };
}; };
var cutBoxFromImageAndResize = (box4, image7, cropSize) => { var cutBoxFromImageAndResize = (box5, image7, cropSize) => {
const h = image7.shape[1]; const h = image7.shape[1];
const w = image7.shape[2]; const w = image7.shape[2];
const crop2 = image.cropAndResize(image7, [[box4.startPoint[1] / h, box4.startPoint[0] / w, box4.endPoint[1] / h, box4.endPoint[0] / w]], [0], cropSize); const crop2 = image.cropAndResize(image7, [[box5.startPoint[1] / h, box5.startPoint[0] / w, box5.endPoint[1] / h, box5.endPoint[0] / w]], [0], cropSize);
const norm2 = div(crop2, constants.tf255); const norm2 = div(crop2, constants.tf255);
dispose(crop2); dispose(crop2);
return norm2; return norm2;
}; };
var enlargeBox = (box4, factor) => { var enlargeBox = (box5, factor) => {
const center = getBoxCenter(box4); const center = getBoxCenter(box5);
const size2 = getBoxSize(box4); const size2 = getBoxSize(box5);
const halfSize = [factor * size2[0] / 2, factor * size2[1] / 2]; const halfSize = [factor * size2[0] / 2, factor * size2[1] / 2];
return { startPoint: [center[0] - halfSize[0], center[1] - halfSize[1]], endPoint: [center[0] + halfSize[0], center[1] + halfSize[1]], landmarks: box4.landmarks, confidence: box4.confidence }; return { startPoint: [center[0] - halfSize[0], center[1] - halfSize[1]], endPoint: [center[0] + halfSize[0], center[1] + halfSize[1]], landmarks: box5.landmarks, confidence: box5.confidence };
}; };
var squarifyBox = (box4) => { var squarifyBox = (box5) => {
const centers = getBoxCenter(box4); const centers = getBoxCenter(box5);
const size2 = getBoxSize(box4); const size2 = getBoxSize(box5);
const halfSize = Math.max(...size2) / 2; const halfSize = Math.max(...size2) / 2;
return { startPoint: [Math.round(centers[0] - halfSize), Math.round(centers[1] - halfSize)], endPoint: [Math.round(centers[0] + halfSize), Math.round(centers[1] + halfSize)], landmarks: box4.landmarks, confidence: box4.confidence }; return { startPoint: [Math.round(centers[0] - halfSize), Math.round(centers[1] - halfSize)], endPoint: [Math.round(centers[0] + halfSize), Math.round(centers[1] + halfSize)], landmarks: box5.landmarks, confidence: box5.confidence };
}; };
var calculateLandmarksBoundingBox = (landmarks) => { var calculateLandmarksBoundingBox = (landmarks) => {
const xs = landmarks.map((d) => d[0]); const xs = landmarks.map((d) => d[0]);
@ -75408,8 +75411,8 @@ function generateAnchors(inputSize9) {
} }
return anchors4; return anchors4;
} }
function transformRawCoords(coordsRaw, box4, angle, rotationMatrix, inputSize9) { function transformRawCoords(coordsRaw, box5, angle, rotationMatrix, inputSize9) {
const boxSize = getBoxSize(box4); const boxSize = getBoxSize(box5);
const coordsScaled = coordsRaw.map((coord) => [ const coordsScaled = coordsRaw.map((coord) => [
boxSize[0] / inputSize9 * (coord[0] - inputSize9 / 2), boxSize[0] / inputSize9 * (coord[0] - inputSize9 / 2),
boxSize[1] / inputSize9 * (coord[1] - inputSize9 / 2), boxSize[1] / inputSize9 * (coord[1] - inputSize9 / 2),
@ -75419,33 +75422,33 @@ function transformRawCoords(coordsRaw, box4, angle, rotationMatrix, inputSize9)
const coordsRotationMatrix = largeAngle ? buildRotationMatrix(angle, [0, 0]) : fixedRotationMatrix; const coordsRotationMatrix = largeAngle ? buildRotationMatrix(angle, [0, 0]) : fixedRotationMatrix;
const coordsRotated = largeAngle ? coordsScaled.map((coord) => [...rotatePoint(coord, coordsRotationMatrix), coord[2]]) : coordsScaled; const coordsRotated = largeAngle ? coordsScaled.map((coord) => [...rotatePoint(coord, coordsRotationMatrix), coord[2]]) : coordsScaled;
const inverseRotationMatrix = largeAngle ? invertTransformMatrix(rotationMatrix) : fixedRotationMatrix; const inverseRotationMatrix = largeAngle ? invertTransformMatrix(rotationMatrix) : fixedRotationMatrix;
const boxCenter = [...getBoxCenter({ startPoint: box4.startPoint, endPoint: box4.endPoint }), 1]; const boxCenter = [...getBoxCenter({ startPoint: box5.startPoint, endPoint: box5.endPoint }), 1];
return coordsRotated.map((coord) => [ return coordsRotated.map((coord) => [
Math.round(coord[0] + dot4(boxCenter, inverseRotationMatrix[0])), Math.round(coord[0] + dot4(boxCenter, inverseRotationMatrix[0])),
Math.round(coord[1] + dot4(boxCenter, inverseRotationMatrix[1])), Math.round(coord[1] + dot4(boxCenter, inverseRotationMatrix[1])),
Math.round(coord[2] || 0) Math.round(coord[2] || 0)
]); ]);
} }
function correctFaceRotation(rotate, box4, input2, inputSize9) { function correctFaceRotation(rotate, box5, input2, inputSize9) {
const symmetryLine = box4.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine; const symmetryLine = box5.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine;
let angle = 0; let angle = 0;
let rotationMatrix = fixedRotationMatrix; let rotationMatrix = fixedRotationMatrix;
let face5; let face5;
if (rotate && env2.kernels.includes("rotatewithoffset")) { if (rotate && env2.kernels.includes("rotatewithoffset")) {
angle = computeRotation(box4.landmarks[symmetryLine[0]], box4.landmarks[symmetryLine[1]]); angle = computeRotation(box5.landmarks[symmetryLine[0]], box5.landmarks[symmetryLine[1]]);
const largeAngle = angle && angle !== 0 && Math.abs(angle) > 0.2; const largeAngle = angle && angle !== 0 && Math.abs(angle) > 0.2;
if (largeAngle) { if (largeAngle) {
const center = getBoxCenter({ startPoint: box4.startPoint, endPoint: box4.endPoint }); const center = getBoxCenter({ startPoint: box5.startPoint, endPoint: box5.endPoint });
const centerRaw = [center[0] / input2.shape[2], center[1] / input2.shape[1]]; const centerRaw = [center[0] / input2.shape[2], center[1] / input2.shape[1]];
const rotated = image.rotateWithOffset(input2, angle, 0, centerRaw); const rotated = image.rotateWithOffset(input2, angle, 0, centerRaw);
rotationMatrix = buildRotationMatrix(-angle, center); rotationMatrix = buildRotationMatrix(-angle, center);
face5 = cutBoxFromImageAndResize(box4, rotated, [inputSize9, inputSize9]); face5 = cutBoxFromImageAndResize(box5, rotated, [inputSize9, inputSize9]);
dispose(rotated); dispose(rotated);
} else { } else {
face5 = cutBoxFromImageAndResize(box4, input2, [inputSize9, inputSize9]); face5 = cutBoxFromImageAndResize(box5, input2, [inputSize9, inputSize9]);
} }
} else { } else {
face5 = cutBoxFromImageAndResize(box4, input2, [inputSize9, inputSize9]); face5 = cutBoxFromImageAndResize(box5, input2, [inputSize9, inputSize9]);
} }
return [angle, rotationMatrix, face5]; return [angle, rotationMatrix, face5];
} }
@ -75626,41 +75629,39 @@ async function createAnchors() {
} }
anchorTensor = { x: tensor1d(anchors4.map((a) => a.x)), y: tensor1d(anchors4.map((a) => a.y)) }; anchorTensor = { x: tensor1d(anchors4.map((a) => a.x)), y: tensor1d(anchors4.map((a) => a.y)) };
} }
var cropFactor = [5, 5];
function decodeBoxes(boxesTensor, anchor) { // src/util/box.ts
return tidy(() => { function calc(keypoints, outputSize2 = [1, 1]) {
const split4 = split(boxesTensor, 12, 1); const coords10 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
let xCenter = squeeze(split4[0]); const min7 = [Math.min(...coords10[0]), Math.min(...coords10[1])];
let yCenter = squeeze(split4[1]); const max7 = [Math.max(...coords10[0]), Math.max(...coords10[1])];
let width = squeeze(split4[2]); const box5 = [min7[0], min7[1], max7[0] - min7[0], max7[1] - min7[1]];
let height = squeeze(split4[3]); const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
xCenter = add2(div(xCenter, inputSize2), anchor.x); return { box: box5, boxRaw };
yCenter = add2(div(yCenter, inputSize2), anchor.y);
width = mul(div(width, inputSize2), cropFactor[0]);
height = mul(div(height, inputSize2), cropFactor[1]);
const xMin = sub(xCenter, div(width, 2));
const yMin = sub(yCenter, div(height, 2));
const boxes = stack([xMin, yMin, width, height], 1);
return boxes;
});
} }
async function decode(boxesTensor, logitsTensor, config3, outputSize2) { function square4(keypoints, outputSize2 = [1, 1]) {
const t = {}; const coords10 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
t.boxes = decodeBoxes(boxesTensor, anchorTensor); const min7 = [Math.min(...coords10[0]), Math.min(...coords10[1])];
t.scores = sigmoid(logitsTensor); const max7 = [Math.max(...coords10[0]), Math.max(...coords10[1])];
t.argmax = argMax(t.scores); const center = [(min7[0] + max7[0]) / 2, (min7[1] + max7[1]) / 2];
const i = (await t.argmax.data())[0]; const dist = Math.max(center[0] - min7[0], center[1] - min7[1], -center[0] + max7[0], -center[1] + max7[1]);
const scores = await t.scores.data(); const box5 = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];
const detected = []; const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
const minScore = config3.body["detector"] && config3.body["detector"]["minConfidence"] ? config3.body["detector"]["minConfidence"] : 0; return { box: box5, boxRaw };
if (scores[i] >= minScore) { }
const boxes = await t.boxes.array(); function scale2(box5, scaleFact) {
const boxRaw = boxes[i]; const dist = [box5[2] * scaleFact, box5[3] * scaleFact];
const box4 = [boxRaw[0] * outputSize2[0], boxRaw[1] * outputSize2[1], boxRaw[2] * outputSize2[0], boxRaw[3] * outputSize2[1]]; const newBox = [
detected.push({ box: box4, boxRaw, score: scores[i] }); box5[0] - (dist[0] - box5[2]) / 2,
} box5[1] - (dist[1] - box5[3]) / 2,
Object.keys(t).forEach((tensor2) => dispose(t[tensor2])); dist[0],
return detected; dist[1]
];
return newBox;
}
function crop(box5) {
const yxBox = [Math.max(0, box5[1]), Math.max(0, box5[0]), Math.min(1, box5[3] + box5[1]), Math.min(1, box5[2] + box5[0])];
return yxBox;
} }
// src/body/blazepose.ts // src/body/blazepose.ts
@ -75673,7 +75674,7 @@ var outputNodes = {
detector: [] detector: []
}; };
var cache = null; var cache = null;
var lastBox; var cropBox;
var padding = [[0, 0], [0, 0], [0, 0], [0, 0]]; var padding = [[0, 0], [0, 0], [0, 0], [0, 0]];
var lastTime5 = 0; var lastTime5 = 0;
var sigmoid6 = (x) => 1 - 1 / (1 + Math.exp(x)); var sigmoid6 = (x) => 1 - 1 / (1 + Math.exp(x));
@ -75710,39 +75711,37 @@ async function loadPose(config3) {
log("cached model:", models.landmarks["modelUrl"]); log("cached model:", models.landmarks["modelUrl"]);
return models.landmarks; return models.landmarks;
} }
function calculateBoxes(keypoints, outputSize2) { async function prepareImage(input2, size2) {
const x = keypoints.map((a) => a.position[0]);
const y = keypoints.map((a) => a.position[1]);
const keypointsBox = [Math.min(...x), Math.min(...y), Math.max(...x) - Math.min(...x), Math.max(...y) - Math.min(...y)];
const keypointsBoxRaw = [keypointsBox[0] / outputSize2[0], keypointsBox[1] / outputSize2[1], keypointsBox[2] / outputSize2[0], keypointsBox[3] / outputSize2[1]];
return { keypointsBox, keypointsBoxRaw };
}
async function prepareImage(input2, size2, box4) {
const t = {}; const t = {};
if (!input2.shape || !input2.shape[1] || !input2.shape[2]) if (!input2.shape || !input2.shape[1] || !input2.shape[2])
return input2; return input2;
let final; let final;
if (cropBox) {
t.cropped = image.cropAndResize(input2, [cropBox], [0], [input2.shape[1], input2.shape[2]]);
}
if (input2.shape[1] !== input2.shape[2]) { if (input2.shape[1] !== input2.shape[2]) {
const height = box4 ? [Math.trunc(input2.shape[1] * box4[1]), Math.trunc(input2.shape[1] * (box4[1] + box4[3]))] : [input2.shape[2] > input2.shape[1] ? Math.trunc((input2.shape[2] - input2.shape[1]) / 2) : 0, input2.shape[2] > input2.shape[1] ? Math.trunc((input2.shape[2] - input2.shape[1]) / 2) : 0]; const height = [
const width = box4 ? [Math.trunc(input2.shape[2] * box4[0]), Math.trunc(input2.shape[2] * (box4[0] + box4[2]))] : [input2.shape[1] > input2.shape[2] ? Math.trunc((input2.shape[1] - input2.shape[2]) / 2) : 0, input2.shape[1] > input2.shape[2] ? Math.trunc((input2.shape[1] - input2.shape[2]) / 2) : 0]; input2.shape[2] > input2.shape[1] ? Math.trunc((input2.shape[2] - input2.shape[1]) / 2) : 0,
input2.shape[2] > input2.shape[1] ? Math.trunc((input2.shape[2] - input2.shape[1]) / 2) : 0
];
const width = [
input2.shape[1] > input2.shape[2] ? Math.trunc((input2.shape[1] - input2.shape[2]) / 2) : 0,
input2.shape[1] > input2.shape[2] ? Math.trunc((input2.shape[1] - input2.shape[2]) / 2) : 0
];
padding = [ padding = [
[0, 0], [0, 0],
height, height,
width, width,
[0, 0] [0, 0]
]; ];
if (box4) { t.pad = pad(t.cropped || input2, padding);
t.resize = image.cropAndResize(input2, [box4], [0], [size2, size2]); t.resize = image.resizeBilinear(t.pad, [size2, size2]);
} else {
t.pad = pad(input2, padding);
t.resize = image.resizeBilinear(t.pad, [size2, size2]);
}
final = div(t.resize, constants.tf255); final = div(t.resize, constants.tf255);
} else if (input2.shape[1] !== size2) { } else if (input2.shape[1] !== size2) {
t.resize = image.resizeBilinear(input2, [size2, size2]); t.resize = image.resizeBilinear(t.cropped || input2, [size2, size2]);
final = div(t.resize, constants.tf255); final = div(t.resize, constants.tf255);
} else { } else {
final = div(input2, constants.tf255); final = div(t.cropped || input2, constants.tf255);
} }
Object.keys(t).forEach((tensor2) => dispose(t[tensor2])); Object.keys(t).forEach((tensor2) => dispose(t[tensor2]));
return final; return final;
@ -75756,19 +75755,21 @@ function rescaleKeypoints(keypoints, outputSize2) {
]; ];
kpt4.positionRaw = [kpt4.position[0] / outputSize2[0], kpt4.position[1] / outputSize2[1], kpt4.position[2]]; kpt4.positionRaw = [kpt4.position[0] / outputSize2[0], kpt4.position[1] / outputSize2[1], kpt4.position[2]];
} }
return keypoints; if (cropBox) {
} for (const kpt4 of keypoints) {
function rescaleBoxes(boxes, outputSize2) { kpt4.positionRaw = [
for (const box4 of boxes) { kpt4.positionRaw[0] + cropBox[1],
box4.box = [ kpt4.positionRaw[1] + cropBox[0],
Math.trunc(box4.box[0] * (outputSize2[0] + padding[2][0] + padding[2][1]) / outputSize2[0]), kpt4.positionRaw[2]
Math.trunc(box4.box[1] * (outputSize2[1] + padding[1][0] + padding[1][1]) / outputSize2[1]), ];
Math.trunc(box4.box[2] * (outputSize2[0] + padding[2][0] + padding[2][1]) / outputSize2[0]), kpt4.position = [
Math.trunc(box4.box[3] * (outputSize2[1] + padding[1][0] + padding[1][1]) / outputSize2[1]) Math.trunc(kpt4.positionRaw[0] * outputSize2[0]),
]; Math.trunc(kpt4.positionRaw[1] * outputSize2[1]),
box4.boxRaw = [box4.box[0] / outputSize2[0], box4.box[1] / outputSize2[1], box4.box[2] / outputSize2[0], box4.box[3] / outputSize2[1]]; kpt4.positionRaw[2]
];
}
} }
return boxes; return keypoints;
} }
async function detectLandmarks(input2, config3, outputSize2) { async function detectLandmarks(input2, config3, outputSize2) {
var _a; var _a;
@ -75790,7 +75791,8 @@ async function detectLandmarks(input2, config3, outputSize2) {
if (poseScore < (config3.body.minConfidence || 0)) if (poseScore < (config3.body.minConfidence || 0))
return null; return null;
const keypoints = rescaleKeypoints(keypointsRelative, outputSize2); const keypoints = rescaleKeypoints(keypointsRelative, outputSize2);
const boxes = calculateBoxes(keypoints, [outputSize2[0], outputSize2[1]]); const kpts = keypoints.map((k) => k.position);
const boxes = calc(kpts, [outputSize2[0], outputSize2[1]]);
const annotations2 = {}; const annotations2 = {};
for (const [name, indexes] of Object.entries(connected)) { for (const [name, indexes] of Object.entries(connected)) {
const pt = []; const pt = [];
@ -75802,22 +75804,9 @@ async function detectLandmarks(input2, config3, outputSize2) {
} }
annotations2[name] = pt; annotations2[name] = pt;
} }
const body4 = { id: 0, score: Math.trunc(100 * poseScore) / 100, box: boxes.keypointsBox, boxRaw: boxes.keypointsBoxRaw, keypoints, annotations: annotations2 }; const body4 = { id: 0, score: Math.trunc(100 * poseScore) / 100, box: boxes.box, boxRaw: boxes.boxRaw, keypoints, annotations: annotations2 };
return body4; return body4;
} }
async function detectBoxes(input2, config3, outputSize2) {
var _a;
const t = {};
t.res = (_a = models.detector) == null ? void 0 : _a.execute(input2, ["Identity"]);
t.logitsRaw = slice(t.res, [0, 0, 0], [1, -1, 1]);
t.boxesRaw = slice(t.res, [0, 0, 1], [1, -1, -1]);
t.logits = squeeze(t.logitsRaw);
t.boxes = squeeze(t.boxesRaw);
const boxes = await decode(t.boxes, t.logits, config3, outputSize2);
rescaleBoxes(boxes, outputSize2);
Object.keys(t).forEach((tensor2) => dispose(t[tensor2]));
return boxes;
}
async function predict5(input2, config3) { async function predict5(input2, config3) {
const outputSize2 = [input2.shape[2] || 0, input2.shape[1] || 0]; const outputSize2 = [input2.shape[2] || 0, input2.shape[1] || 0];
const skipTime = (config3.body.skipTime || 0) > now() - lastTime5; const skipTime = (config3.body.skipTime || 0) > now() - lastTime5;
@ -75826,26 +75815,13 @@ async function predict5(input2, config3) {
skipped5++; skipped5++;
} else { } else {
const t = {}; const t = {};
if (config3.body["detector"] && config3.body["detector"]["enabled"]) { t.landmarks = await prepareImage(input2, 256);
t.detector = await prepareImage(input2, 224); cache = await detectLandmarks(t.landmarks, config3, outputSize2);
const boxes = await detectBoxes(t.detector, config3, outputSize2);
if (boxes && boxes.length === 1) {
t.landmarks = await prepareImage(input2, 256, boxes[0].box);
cache = await detectLandmarks(t.landmarks, config3, outputSize2);
}
if (cache)
cache.score = boxes[0].score;
} else {
t.landmarks = await prepareImage(input2, 256, lastBox);
cache = await detectLandmarks(t.landmarks, config3, outputSize2);
}
Object.keys(t).forEach((tensor2) => dispose(t[tensor2])); Object.keys(t).forEach((tensor2) => dispose(t[tensor2]));
lastTime5 = now(); lastTime5 = now();
skipped5 = 0; skipped5 = 0;
} }
if (cache) return cache ? [cache] : [];
return [cache];
return [];
} }
// src/object/labels.ts // src/object/labels.ts
@ -75983,13 +75959,13 @@ async function process3(res, outputShape, config3) {
detections[0][id][2] / inputSize4 - x, detections[0][id][2] / inputSize4 - x,
detections[0][id][3] / inputSize4 - y detections[0][id][3] / inputSize4 - y
]; ];
const box4 = [ const box5 = [
Math.trunc(boxRaw[0] * outputShape[0]), Math.trunc(boxRaw[0] * outputShape[0]),
Math.trunc(boxRaw[1] * outputShape[1]), Math.trunc(boxRaw[1] * outputShape[1]),
Math.trunc(boxRaw[2] * outputShape[0]), Math.trunc(boxRaw[2] * outputShape[0]),
Math.trunc(boxRaw[3] * outputShape[1]) Math.trunc(boxRaw[3] * outputShape[1])
]; ];
results.push({ id: i++, score, class: classVal, label, box: box4, boxRaw }); results.push({ id: i++, score, class: classVal, label, box: box5, boxRaw });
} }
Object.keys(t).forEach((tensor2) => dispose(t[tensor2])); Object.keys(t).forEach((tensor2) => dispose(t[tensor2]));
return results; return results;
@ -76322,20 +76298,20 @@ var getLeftToRightEyeDepthDifference = (rawCoords) => {
return leftEyeZ - rightEyeZ; return leftEyeZ - rightEyeZ;
}; };
var getEyeBox = (rawCoords, face5, eyeInnerCornerIndex, eyeOuterCornerIndex, meshSize, flip = false) => { var getEyeBox = (rawCoords, face5, eyeInnerCornerIndex, eyeOuterCornerIndex, meshSize, flip = false) => {
const box4 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge)); const box5 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge));
const boxSize = getBoxSize(box4); const boxSize = getBoxSize(box5);
let crop2 = image.cropAndResize(face5, [[ let crop2 = image.cropAndResize(face5, [[
box4.startPoint[1] / meshSize, box5.startPoint[1] / meshSize,
box4.startPoint[0] / meshSize, box5.startPoint[0] / meshSize,
box4.endPoint[1] / meshSize, box5.endPoint[1] / meshSize,
box4.endPoint[0] / meshSize box5.endPoint[0] / meshSize
]], [0], [inputSize5, inputSize5]); ]], [0], [inputSize5, inputSize5]);
if (flip && env2.kernels.includes("flipleftright")) { if (flip && env2.kernels.includes("flipleftright")) {
const flipped = image.flipLeftRight(crop2); const flipped = image.flipLeftRight(crop2);
dispose(crop2); dispose(crop2);
crop2 = flipped; crop2 = flipped;
} }
return { box: box4, boxSize, crop: crop2 }; return { box: box5, boxSize, crop: crop2 };
}; };
var getEyeCoords = (eyeData, eyeBox, eyeBoxSize, flip = false) => { var getEyeCoords = (eyeData, eyeBox, eyeBoxSize, flip = false) => {
const eyeRawCoords = []; const eyeRawCoords = [];
@ -76429,7 +76405,7 @@ async function predict10(input2, config3) {
const newCache = []; const newCache = [];
let id = 0; let id = 0;
for (let i = 0; i < boxCache.length; i++) { for (let i = 0; i < boxCache.length; i++) {
let box4 = boxCache[i]; let box5 = boxCache[i];
let angle = 0; let angle = 0;
let rotationMatrix; let rotationMatrix;
const face5 = { const face5 = {
@ -76443,20 +76419,20 @@ async function predict10(input2, config3) {
faceScore: 0, faceScore: 0,
annotations: {} annotations: {}
}; };
[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) ? inputSize6 : size()); [angle, rotationMatrix, face5.tensor] = correctFaceRotation((_d = config3.face.detector) == null ? void 0 : _d.rotation, box5, input2, ((_e = config3.face.mesh) == null ? void 0 : _e.enabled) ? inputSize6 : size());
if ((_f = config3 == null ? void 0 : config3.filter) == null ? void 0 : _f.equalization) { if ((_f = config3 == null ? void 0 : config3.filter) == null ? void 0 : _f.equalization) {
const equilized = await histogramEqualization(face5.tensor); const equilized = await histogramEqualization(face5.tensor);
dispose(face5.tensor); dispose(face5.tensor);
face5.tensor = equilized; face5.tensor = equilized;
} }
face5.boxScore = Math.round(100 * box4.confidence) / 100; face5.boxScore = Math.round(100 * box5.confidence) / 100;
if (!((_g = config3.face.mesh) == null ? void 0 : _g.enabled)) { if (!((_g = config3.face.mesh) == null ? void 0 : _g.enabled)) {
face5.box = getClampedBox(box4, input2); face5.box = getClampedBox(box5, input2);
face5.boxRaw = getRawBox(box4, input2); face5.boxRaw = getRawBox(box5, input2);
face5.score = face5.boxScore; face5.score = face5.boxScore;
face5.mesh = box4.landmarks.map((pt) => [ face5.mesh = box5.landmarks.map((pt) => [
(box4.startPoint[0] + box4.endPoint[0]) / 2 + (box4.endPoint[0] + box4.startPoint[0]) * pt[0] / size(), (box5.startPoint[0] + box5.endPoint[0]) / 2 + (box5.endPoint[0] + box5.startPoint[0]) * pt[0] / size(),
(box4.startPoint[1] + box4.endPoint[1]) / 2 + (box4.endPoint[1] + box4.startPoint[1]) * pt[1] / size() (box5.startPoint[1] + box5.endPoint[1]) / 2 + (box5.endPoint[1] + box5.startPoint[1]) * pt[1] / size()
]); ]);
face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input2.shape[2] || 0), pt[1] / (input2.shape[1] || 0), (pt[2] || 0) / inputSize6]); face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input2.shape[2] || 0), pt[1] / (input2.shape[1] || 0), (pt[2] || 0) / inputSize6]);
for (const key of Object.keys(blazeFaceLandmarks)) for (const key of Object.keys(blazeFaceLandmarks))
@ -76472,24 +76448,24 @@ async function predict10(input2, config3) {
let rawCoords = await coordsReshaped.array(); let rawCoords = await coordsReshaped.array();
dispose([contourCoords, coordsReshaped, confidence, contours]); dispose([contourCoords, coordsReshaped, confidence, contours]);
if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) { if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
box4.confidence = face5.faceScore; box5.confidence = face5.faceScore;
} else { } else {
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled) if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize6); rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize6);
face5.mesh = transformRawCoords(rawCoords, box4, angle, rotationMatrix, inputSize6); face5.mesh = transformRawCoords(rawCoords, box5, angle, rotationMatrix, inputSize6);
face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input2.shape[2] || 0), pt[1] / (input2.shape[1] || 0), (pt[2] || 0) / inputSize6]); face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input2.shape[2] || 0), pt[1] / (input2.shape[1] || 0), (pt[2] || 0) / inputSize6]);
for (const key of Object.keys(meshAnnotations)) for (const key of Object.keys(meshAnnotations))
face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]); face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]);
const boxCalculated = calculateLandmarksBoundingBox(face5.mesh); const boxCalculated = calculateLandmarksBoundingBox(face5.mesh);
const boxEnlarged = enlargeBox(boxCalculated, ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6); const boxEnlarged = enlargeBox(boxCalculated, ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6);
const boxSquared = squarifyBox(boxEnlarged); const boxSquared = squarifyBox(boxEnlarged);
box4 = { ...boxSquared, confidence: box4.confidence }; box5 = { ...boxSquared, confidence: box5.confidence };
face5.box = getClampedBox(box4, input2); face5.box = getClampedBox(box5, input2);
face5.boxRaw = getRawBox(box4, input2); face5.boxRaw = getRawBox(box5, input2);
face5.score = face5.faceScore; face5.score = face5.faceScore;
newCache.push(box4); newCache.push(box5);
dispose(face5.tensor); dispose(face5.tensor);
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_k = config3.face.detector) == null ? void 0 : _k.rotation, box4, input2, inputSize6); [angle, rotationMatrix, face5.tensor] = correctFaceRotation((_k = config3.face.detector) == null ? void 0 : _k.rotation, box5, input2, inputSize6);
} }
} }
faces.push(face5); faces.push(face5);
@ -76594,54 +76570,54 @@ async function predict11(image7, config3, idx, count3) {
} }
// src/hand/handposeutil.ts // src/hand/handposeutil.ts
function getBoxSize2(box4) { function getBoxSize2(box5) {
return [ return [
Math.abs(box4.endPoint[0] - box4.startPoint[0]), Math.abs(box5.endPoint[0] - box5.startPoint[0]),
Math.abs(box4.endPoint[1] - box4.startPoint[1]) Math.abs(box5.endPoint[1] - box5.startPoint[1])
]; ];
} }
function getBoxCenter2(box4) { function getBoxCenter2(box5) {
return [ return [
box4.startPoint[0] + (box4.endPoint[0] - box4.startPoint[0]) / 2, box5.startPoint[0] + (box5.endPoint[0] - box5.startPoint[0]) / 2,
box4.startPoint[1] + (box4.endPoint[1] - box4.startPoint[1]) / 2 box5.startPoint[1] + (box5.endPoint[1] - box5.startPoint[1]) / 2
]; ];
} }
function cutBoxFromImageAndResize2(box4, image7, cropSize) { function cutBoxFromImageAndResize2(box5, image7, cropSize) {
const h = image7.shape[1]; const h = image7.shape[1];
const w = image7.shape[2]; const w = image7.shape[2];
const boxes = [[ const boxes = [[
box4.startPoint[1] / h, box5.startPoint[1] / h,
box4.startPoint[0] / w, box5.startPoint[0] / w,
box4.endPoint[1] / h, box5.endPoint[1] / h,
box4.endPoint[0] / w box5.endPoint[0] / w
]]; ]];
return image.cropAndResize(image7, boxes, [0], cropSize); return image.cropAndResize(image7, boxes, [0], cropSize);
} }
function scaleBoxCoordinates2(box4, factor) { function scaleBoxCoordinates2(box5, factor) {
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]]; const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]]; const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
const palmLandmarks = box4.palmLandmarks.map((coord) => { const palmLandmarks = box5.palmLandmarks.map((coord) => {
const scaledCoord = [coord[0] * factor[0], coord[1] * factor[1]]; const scaledCoord = [coord[0] * factor[0], coord[1] * factor[1]];
return scaledCoord; return scaledCoord;
}); });
return { startPoint, endPoint, palmLandmarks, confidence: box4.confidence }; return { startPoint, endPoint, palmLandmarks, confidence: box5.confidence };
} }
function enlargeBox2(box4, factor = 1.5) { function enlargeBox2(box5, factor = 1.5) {
const center = getBoxCenter2(box4); const center = getBoxCenter2(box5);
const size2 = getBoxSize2(box4); const size2 = getBoxSize2(box5);
const newHalfSize = [factor * size2[0] / 2, factor * size2[1] / 2]; const newHalfSize = [factor * size2[0] / 2, factor * size2[1] / 2];
const startPoint = [center[0] - newHalfSize[0], center[1] - newHalfSize[1]]; const startPoint = [center[0] - newHalfSize[0], center[1] - newHalfSize[1]];
const endPoint = [center[0] + newHalfSize[0], center[1] + newHalfSize[1]]; const endPoint = [center[0] + newHalfSize[0], center[1] + newHalfSize[1]];
return { startPoint, endPoint, palmLandmarks: box4.palmLandmarks }; return { startPoint, endPoint, palmLandmarks: box5.palmLandmarks };
} }
function squarifyBox2(box4) { function squarifyBox2(box5) {
const centers = getBoxCenter2(box4); const centers = getBoxCenter2(box5);
const size2 = getBoxSize2(box4); const size2 = getBoxSize2(box5);
const maxEdge = Math.max(...size2); const maxEdge = Math.max(...size2);
const halfSize = maxEdge / 2; const halfSize = maxEdge / 2;
const startPoint = [centers[0] - halfSize, centers[1] - halfSize]; const startPoint = [centers[0] - halfSize, centers[1] - halfSize];
const endPoint = [centers[0] + halfSize, centers[1] + halfSize]; const endPoint = [centers[0] + halfSize, centers[1] + halfSize];
return { startPoint, endPoint, palmLandmarks: box4.palmLandmarks }; return { startPoint, endPoint, palmLandmarks: box5.palmLandmarks };
} }
function normalizeRadians2(angle) { function normalizeRadians2(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));
@ -79715,9 +79691,9 @@ var HandDetector = class {
p2.slice = slice(t.predictions, [index2, 5], [1, 14]); p2.slice = slice(t.predictions, [index2, 5], [1, 14]);
p2.norm = this.normalizeLandmarks(p2.slice, index2); p2.norm = this.normalizeLandmarks(p2.slice, index2);
p2.palmLandmarks = reshape(p2.norm, [-1, 2]); p2.palmLandmarks = reshape(p2.norm, [-1, 2]);
const box4 = await p2.box.data(); const box5 = await p2.box.data();
const startPoint = box4.slice(0, 2); const startPoint = box5.slice(0, 2);
const endPoint = box4.slice(2, 4); const endPoint = box5.slice(2, 4);
const palmLandmarks = await p2.palmLandmarks.array(); const palmLandmarks = await p2.palmLandmarks.array();
const hand3 = { startPoint, endPoint, palmLandmarks, confidence: scores[index2] }; const hand3 = { startPoint, endPoint, palmLandmarks, confidence: scores[index2] };
const scaled = scaleBoxCoordinates2(hand3, [input2.shape[2] / this.inputSize, input2.shape[1] / this.inputSize]); const scaled = scaleBoxCoordinates2(hand3, [input2.shape[2] / this.inputSize, input2.shape[1] / this.inputSize]);
@ -80303,24 +80279,24 @@ async function predict12(input2, config3) {
} }
} }
const keypoints = predictions[i].landmarks; const keypoints = predictions[i].landmarks;
let box4 = [Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, 0, 0]; let box5 = [Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, 0, 0];
let boxRaw = [0, 0, 0, 0]; let boxRaw = [0, 0, 0, 0];
if (keypoints && keypoints.length > 0) { if (keypoints && keypoints.length > 0) {
for (const pt of keypoints) { for (const pt of keypoints) {
if (pt[0] < box4[0]) if (pt[0] < box5[0])
box4[0] = pt[0]; box5[0] = pt[0];
if (pt[1] < box4[1]) if (pt[1] < box5[1])
box4[1] = pt[1]; box5[1] = pt[1];
if (pt[0] > box4[2]) if (pt[0] > box5[2])
box4[2] = pt[0]; box5[2] = pt[0];
if (pt[1] > box4[3]) if (pt[1] > box5[3])
box4[3] = pt[1]; box5[3] = pt[1];
} }
box4[2] -= box4[0]; box5[2] -= box5[0];
box4[3] -= box4[1]; box5[3] -= box5[1];
boxRaw = [box4[0] / (input2.shape[2] || 0), box4[1] / (input2.shape[1] || 0), box4[2] / (input2.shape[2] || 0), box4[3] / (input2.shape[1] || 0)]; boxRaw = [box5[0] / (input2.shape[2] || 0), box5[1] / (input2.shape[1] || 0), box5[2] / (input2.shape[2] || 0), box5[3] / (input2.shape[1] || 0)];
} else { } else {
box4 = predictions[i].box ? [ box5 = predictions[i].box ? [
Math.trunc(Math.max(0, predictions[i].box.topLeft[0])), Math.trunc(Math.max(0, predictions[i].box.topLeft[0])),
Math.trunc(Math.max(0, predictions[i].box.topLeft[1])), Math.trunc(Math.max(0, predictions[i].box.topLeft[1])),
Math.trunc(Math.min(input2.shape[2] || 0, predictions[i].box.bottomRight[0]) - Math.max(0, predictions[i].box.topLeft[0])), Math.trunc(Math.min(input2.shape[2] || 0, predictions[i].box.bottomRight[0]) - Math.max(0, predictions[i].box.topLeft[0])),
@ -80340,7 +80316,7 @@ async function predict12(input2, config3) {
boxScore: Math.round(100 * predictions[i].boxConfidence) / 100, boxScore: Math.round(100 * predictions[i].boxConfidence) / 100,
fingerScore: Math.round(100 * predictions[i].fingerConfidence) / 100, fingerScore: Math.round(100 * predictions[i].fingerConfidence) / 100,
label: "hand", label: "hand",
box: box4, box: box5,
boxRaw, boxRaw,
keypoints, keypoints,
annotations: annotations2, annotations: annotations2,
@ -80381,40 +80357,6 @@ async function load13(config3) {
return [handDetectorModel, handPoseModel]; return [handDetectorModel, handPoseModel];
} }
// src/util/box.ts
function calc(keypoints, outputSize2 = [1, 1]) {
const coords10 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
const min7 = [Math.min(...coords10[0]), Math.min(...coords10[1])];
const max7 = [Math.max(...coords10[0]), Math.max(...coords10[1])];
const box4 = [min7[0], min7[1], max7[0] - min7[0], max7[1] - min7[1]];
const boxRaw = [box4[0] / outputSize2[0], box4[1] / outputSize2[1], box4[2] / outputSize2[0], box4[3] / outputSize2[1]];
return { box: box4, boxRaw };
}
function square4(keypoints, outputSize2 = [1, 1]) {
const coords10 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
const min7 = [Math.min(...coords10[0]), Math.min(...coords10[1])];
const max7 = [Math.max(...coords10[0]), Math.max(...coords10[1])];
const center = [(min7[0] + max7[0]) / 2, (min7[1] + max7[1]) / 2];
const dist = Math.max(center[0] - min7[0], center[1] - min7[1], -center[0] + max7[0], -center[1] + max7[1]);
const box4 = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];
const boxRaw = [box4[0] / outputSize2[0], box4[1] / outputSize2[1], box4[2] / outputSize2[0], box4[3] / outputSize2[1]];
return { box: box4, boxRaw };
}
function scale2(box4, scaleFact) {
const dist = [box4[2] * scaleFact, box4[3] * scaleFact];
const newBox = [
box4[0] - (dist[0] - box4[2]) / 2,
box4[1] - (dist[1] - box4[3]) / 2,
dist[0],
dist[1]
];
return newBox;
}
function crop(box4) {
const yxBox = [Math.max(0, box4[1]), Math.max(0, box4[0]), Math.min(1, box4[3] + box4[1]), Math.min(1, box4[2] + box4[0])];
return yxBox;
}
// src/hand/handtrack.ts // src/hand/handtrack.ts
var models2 = [null, null]; var models2 = [null, null];
var modelOutputNodes = ["StatefulPartitionedCall/Postprocessor/Slice", "StatefulPartitionedCall/Postprocessor/ExpandDims_1"]; var modelOutputNodes = ["StatefulPartitionedCall/Postprocessor/Slice", "StatefulPartitionedCall/Postprocessor/ExpandDims_1"];
@ -80432,11 +80374,11 @@ var cache3 = {
hands: [] hands: []
}; };
var fingerMap = { var fingerMap = {
thumb: [1, 2, 3, 4], thumb: [0, 1, 2, 3, 4],
index: [5, 6, 7, 8], index: [0, 5, 6, 7, 8],
middle: [9, 10, 11, 12], middle: [0, 9, 10, 11, 12],
ring: [13, 14, 15, 16], ring: [0, 13, 14, 15, 16],
pinky: [17, 18, 19, 20], pinky: [0, 17, 18, 19, 20],
palm: [0] palm: [0]
}; };
async function loadDetect2(config3) { async function loadDetect2(config3) {
@ -80981,7 +80923,7 @@ async function process4(res, inputSize9, outputShape, config3) {
]; ];
let boxRaw = [x, y, w, h]; let boxRaw = [x, y, w, h];
boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1))); boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1)));
const box4 = [ const box5 = [
boxRaw[0] * outputShape[0], boxRaw[0] * outputShape[0],
boxRaw[1] * outputShape[1], boxRaw[1] * outputShape[1],
boxRaw[2] * outputShape[0], boxRaw[2] * outputShape[0],
@ -80992,7 +80934,7 @@ async function process4(res, inputSize9, outputShape, config3) {
score: Math.round(100 * score) / 100, score: Math.round(100 * score) / 100,
class: j + 1, class: j + 1,
label: labels[j].label, label: labels[j].label,
box: box4.map((a) => Math.trunc(a)), box: box5.map((a) => Math.trunc(a)),
boxRaw boxRaw
}; };
results.push(result); results.push(result);
@ -81332,7 +81274,7 @@ function getInstanceScore(existingPoses, keypoints) {
}, 0); }, 0);
return notOverlappedKeypointScores / keypoints.length; return notOverlappedKeypointScores / keypoints.length;
} }
function decode2(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) { function decode(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) {
const poses = []; const poses = [];
const queue = buildPartWithScoreQueue(minConfidence2, scores); const queue = buildPartWithScoreQueue(minConfidence2, scores);
while (poses.length < maxDetected && !queue.empty()) { while (poses.length < maxDetected && !queue.empty()) {
@ -81343,9 +81285,9 @@ function decode2(offsets, scores, displacementsFwd, displacementsBwd, maxDetecte
let keypoints = decodePose(root, scores, offsets, displacementsFwd, displacementsBwd); let keypoints = decodePose(root, scores, offsets, displacementsFwd, displacementsBwd);
keypoints = keypoints.filter((a) => a.score > minConfidence2); keypoints = keypoints.filter((a) => a.score > minConfidence2);
const score = getInstanceScore(poses, keypoints); const score = getInstanceScore(poses, keypoints);
const box4 = getBoundingBox(keypoints); const box5 = getBoundingBox(keypoints);
if (score > minConfidence2) if (score > minConfidence2)
poses.push({ keypoints, box: box4, score: Math.round(100 * score) / 100 }); poses.push({ keypoints, box: box5, score: Math.round(100 * score) / 100 });
} }
return poses; return poses;
} }
@ -81363,7 +81305,7 @@ async function predict17(input2, config3) {
const buffers = await Promise.all(res.map((tensor2) => tensor2.buffer())); const buffers = await Promise.all(res.map((tensor2) => tensor2.buffer()));
for (const t of res) for (const t of res)
dispose(t); dispose(t);
const decoded = await decode2(buffers[0], buffers[1], buffers[2], buffers[3], config3.body.maxDetected, config3.body.minConfidence); const decoded = await decode(buffers[0], buffers[1], buffers[2], buffers[3], config3.body.maxDetected, config3.body.minConfidence);
if (!model17.inputs[0].shape) if (!model17.inputs[0].shape)
return []; return [];
const scaled = scalePoses(decoded, [input2.shape[1], input2.shape[2]], [model17.inputs[0].shape[2], model17.inputs[0].shape[1]]); const scaled = scalePoses(decoded, [input2.shape[1], input2.shape[2]], [model17.inputs[0].shape[2], model17.inputs[0].shape[1]]);
@ -82416,7 +82358,7 @@ var calculateFaceAngle = (face5, imageSize) => {
thetaY = 0; thetaY = 0;
if (isNaN(thetaZ)) if (isNaN(thetaZ))
thetaZ = 0; thetaZ = 0;
return { pitch: 2 * -thetaX, yaw: 2 * -thetaY, roll: 2 * -thetaZ }; return { pitch: -thetaX, yaw: -thetaY, roll: -thetaZ };
}; };
const meshToEulerAngle = (mesh2) => { const meshToEulerAngle = (mesh2) => {
const radians = (a12, a22, b1, b2) => Math.atan2(b2 - a22, b1 - a12); const radians = (a12, a22, b1, b2) => Math.atan2(b2 - a22, b1 - a12);
@ -82762,7 +82704,7 @@ function calc2(newResult, config3) {
bufferedResult.body = JSON.parse(JSON.stringify(newResult.body)); bufferedResult.body = JSON.parse(JSON.stringify(newResult.body));
} else { } else {
for (let i = 0; i < newResult.body.length; i++) { for (let i = 0; i < newResult.body.length; i++) {
const box4 = newResult.body[i].box.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor); const box5 = newResult.body[i].box.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor);
const boxRaw = newResult.body[i].boxRaw.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + newBoxCoord) / bufferedFactor); const boxRaw = newResult.body[i].boxRaw.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + newBoxCoord) / bufferedFactor);
const keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({ const keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({
score: newKpt.score, score: newKpt.score,
@ -82796,14 +82738,14 @@ function calc2(newResult, config3) {
} }
annotations2[name] = pt; annotations2[name] = pt;
} }
bufferedResult.body[i] = { ...newResult.body[i], box: box4, boxRaw, keypoints, annotations: annotations2 }; bufferedResult.body[i] = { ...newResult.body[i], box: box5, boxRaw, keypoints, annotations: annotations2 };
} }
} }
if (!bufferedResult.hand || newResult.hand.length !== bufferedResult.hand.length) { if (!bufferedResult.hand || newResult.hand.length !== bufferedResult.hand.length) {
bufferedResult.hand = JSON.parse(JSON.stringify(newResult.hand)); bufferedResult.hand = JSON.parse(JSON.stringify(newResult.hand));
} else { } else {
for (let i = 0; i < newResult.hand.length; i++) { for (let i = 0; i < newResult.hand.length; i++) {
const box4 = newResult.hand[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].box[j] + b) / bufferedFactor); const box5 = newResult.hand[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].box[j] + b) / bufferedFactor);
const boxRaw = newResult.hand[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].boxRaw[j] + b) / bufferedFactor); const boxRaw = newResult.hand[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].boxRaw[j] + b) / bufferedFactor);
if (bufferedResult.hand[i].keypoints.length !== newResult.hand[i].keypoints.length) if (bufferedResult.hand[i].keypoints.length !== newResult.hand[i].keypoints.length)
bufferedResult.hand[i].keypoints = newResult.hand[i].keypoints; bufferedResult.hand[i].keypoints = newResult.hand[i].keypoints;
@ -82817,14 +82759,14 @@ function calc2(newResult, config3) {
annotations2[key] = newResult.hand[i].annotations[key] && newResult.hand[i].annotations[key][0] ? newResult.hand[i].annotations[key].map((val, j) => val.map((coord, k) => ((bufferedFactor - 1) * bufferedResult.hand[i].annotations[key][j][k] + coord) / bufferedFactor)) : null; annotations2[key] = newResult.hand[i].annotations[key] && newResult.hand[i].annotations[key][0] ? newResult.hand[i].annotations[key].map((val, j) => val.map((coord, k) => ((bufferedFactor - 1) * bufferedResult.hand[i].annotations[key][j][k] + coord) / bufferedFactor)) : null;
} }
} }
bufferedResult.hand[i] = { ...newResult.hand[i], box: box4, boxRaw, keypoints, annotations: annotations2 }; bufferedResult.hand[i] = { ...newResult.hand[i], box: box5, boxRaw, keypoints, annotations: annotations2 };
} }
} }
if (!bufferedResult.face || newResult.face.length !== bufferedResult.face.length) { if (!bufferedResult.face || newResult.face.length !== bufferedResult.face.length) {
bufferedResult.face = JSON.parse(JSON.stringify(newResult.face)); bufferedResult.face = JSON.parse(JSON.stringify(newResult.face));
} else { } else {
for (let i = 0; i < newResult.face.length; i++) { for (let i = 0; i < newResult.face.length; i++) {
const box4 = newResult.face[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].box[j] + b) / bufferedFactor); const box5 = newResult.face[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].box[j] + b) / bufferedFactor);
const boxRaw = newResult.face[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].boxRaw[j] + b) / bufferedFactor); const boxRaw = newResult.face[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].boxRaw[j] + b) / bufferedFactor);
if (newResult.face[i].rotation) { if (newResult.face[i].rotation) {
const rotation = { matrix: [0, 0, 0, 0, 0, 0, 0, 0, 0], angle: { roll: 0, yaw: 0, pitch: 0 }, gaze: { bearing: 0, strength: 0 } }; const rotation = { matrix: [0, 0, 0, 0, 0, 0, 0, 0, 0], angle: { roll: 0, yaw: 0, pitch: 0 }, gaze: { bearing: 0, strength: 0 } };
@ -82838,18 +82780,18 @@ function calc2(newResult, config3) {
bearing: ((bufferedFactor - 1) * (((_u = (_t = bufferedResult.face[i].rotation) == null ? void 0 : _t.gaze) == null ? void 0 : _u.bearing) || 0) + (((_w = (_v = newResult.face[i].rotation) == null ? void 0 : _v.gaze) == null ? void 0 : _w.bearing) || 0)) / bufferedFactor, bearing: ((bufferedFactor - 1) * (((_u = (_t = bufferedResult.face[i].rotation) == null ? void 0 : _t.gaze) == null ? void 0 : _u.bearing) || 0) + (((_w = (_v = newResult.face[i].rotation) == null ? void 0 : _v.gaze) == null ? void 0 : _w.bearing) || 0)) / bufferedFactor,
strength: ((bufferedFactor - 1) * (((_y = (_x = bufferedResult.face[i].rotation) == null ? void 0 : _x.gaze) == null ? void 0 : _y.strength) || 0) + (((_A = (_z = newResult.face[i].rotation) == null ? void 0 : _z.gaze) == null ? void 0 : _A.strength) || 0)) / bufferedFactor strength: ((bufferedFactor - 1) * (((_y = (_x = bufferedResult.face[i].rotation) == null ? void 0 : _x.gaze) == null ? void 0 : _y.strength) || 0) + (((_A = (_z = newResult.face[i].rotation) == null ? void 0 : _z.gaze) == null ? void 0 : _A.strength) || 0)) / bufferedFactor
}; };
bufferedResult.face[i] = { ...newResult.face[i], rotation, box: box4, boxRaw }; bufferedResult.face[i] = { ...newResult.face[i], rotation, box: box5, boxRaw };
} }
bufferedResult.face[i] = { ...newResult.face[i], box: box4, boxRaw }; bufferedResult.face[i] = { ...newResult.face[i], box: box5, boxRaw };
} }
} }
if (!bufferedResult.object || newResult.object.length !== bufferedResult.object.length) { if (!bufferedResult.object || newResult.object.length !== bufferedResult.object.length) {
bufferedResult.object = JSON.parse(JSON.stringify(newResult.object)); bufferedResult.object = JSON.parse(JSON.stringify(newResult.object));
} else { } else {
for (let i = 0; i < newResult.object.length; i++) { for (let i = 0; i < newResult.object.length; i++) {
const box4 = newResult.object[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].box[j] + b) / bufferedFactor); const box5 = newResult.object[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].box[j] + b) / bufferedFactor);
const boxRaw = newResult.object[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].boxRaw[j] + b) / bufferedFactor); const boxRaw = newResult.object[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].boxRaw[j] + b) / bufferedFactor);
bufferedResult.object[i] = { ...newResult.object[i], box: box4, boxRaw }; bufferedResult.object[i] = { ...newResult.object[i], box: box5, boxRaw };
} }
} }
if (newResult.persons) { if (newResult.persons) {
@ -82858,7 +82800,7 @@ function calc2(newResult, config3) {
bufferedResult.persons = JSON.parse(JSON.stringify(newPersons)); bufferedResult.persons = JSON.parse(JSON.stringify(newPersons));
} else { } else {
for (let i = 0; i < newPersons.length; i++) { for (let i = 0; i < newPersons.length; i++) {
bufferedResult.persons[i].box = newPersons[i].box.map((box4, j) => ((bufferedFactor - 1) * bufferedResult.persons[i].box[j] + box4) / bufferedFactor); bufferedResult.persons[i].box = newPersons[i].box.map((box5, j) => ((bufferedFactor - 1) * bufferedResult.persons[i].box[j] + box5) / bufferedFactor);
} }
} }
} }
@ -82949,10 +82891,10 @@ function join2(faces, bodies, hands, gestures, shape) {
} }
const x = []; const x = [];
const y = []; const y = [];
const extractXY = (box4) => { const extractXY = (box5) => {
if (box4 && box4.length === 4) { if (box5 && box5.length === 4) {
x.push(box4[0], box4[0] + box4[2]); x.push(box5[0], box5[0] + box5[2]);
y.push(box4[1], box4[1] + box4[3]); y.push(box5[1], box5[1] + box5[3]);
} }
}; };
extractXY((_k = person2.face) == null ? void 0 : _k.box); extractXY((_k = person2.face) == null ? void 0 : _k.box);

File diff suppressed because one or more lines are too long

918
dist/human.js vendored

File diff suppressed because one or more lines are too long

471
dist/human.node-gpu.js vendored
View File

@ -980,8 +980,8 @@ function GLImageFilter() {
// src/image/enhance.ts // src/image/enhance.ts
var tf = __toModule(require_tfjs_esm()); var tf = __toModule(require_tfjs_esm());
async function histogramEqualization(inputImage) { async function histogramEqualization(inputImage) {
const squeeze11 = inputImage.shape.length === 4 ? tf.squeeze(inputImage) : inputImage; const squeeze10 = inputImage.shape.length === 4 ? tf.squeeze(inputImage) : inputImage;
const channels = tf.split(squeeze11, 3, 2); const channels = tf.split(squeeze10, 3, 2);
const min2 = [tf.min(channels[0]), tf.min(channels[1]), tf.min(channels[2])]; const min2 = [tf.min(channels[0]), tf.min(channels[1]), tf.min(channels[2])];
const max4 = [tf.max(channels[0]), tf.max(channels[1]), tf.max(channels[2])]; const max4 = [tf.max(channels[0]), tf.max(channels[1]), tf.max(channels[2])];
const absMax = await Promise.all(max4.map((channel) => channel.data())); const absMax = await Promise.all(max4.map((channel) => channel.data()));
@ -991,8 +991,8 @@ async function histogramEqualization(inputImage) {
const fact = [tf.div(maxValue, range[0]), tf.div(maxValue, range[1]), tf.div(maxValue, range[2])]; const fact = [tf.div(maxValue, range[0]), tf.div(maxValue, range[1]), tf.div(maxValue, range[2])];
const enh = [tf.mul(sub10[0], fact[0]), tf.mul(sub10[1], fact[1]), tf.mul(sub10[2], fact[2])]; const enh = [tf.mul(sub10[0], fact[0]), tf.mul(sub10[1], fact[1]), tf.mul(sub10[2], fact[2])];
const rgb2 = tf.stack([enh[0], enh[1], enh[2]], 2); const rgb2 = tf.stack([enh[0], enh[1], enh[2]], 2);
const reshape8 = tf.reshape(rgb2, [1, squeeze11.shape[0], squeeze11.shape[1], 3]); const reshape8 = tf.reshape(rgb2, [1, squeeze10.shape[0], squeeze10.shape[1], 3]);
tf.dispose([...channels, ...min2, ...max4, ...sub10, ...range, ...fact, ...enh, rgb2, squeeze11]); tf.dispose([...channels, ...min2, ...max4, ...sub10, ...range, ...fact, ...enh, rgb2, squeeze10]);
return reshape8; return reshape8;
} }
@ -1414,8 +1414,8 @@ async function predict(image29, config3, idx, count2) {
if (!(model == null ? void 0 : model.inputs[0].shape)) if (!(model == null ? void 0 : model.inputs[0].shape))
return; return;
const t = {}; const t = {};
const box4 = [[0, 0.1, 0.9, 0.9]]; const box5 = [[0, 0.1, 0.9, 0.9]];
t.resize = tf4.image.cropAndResize(image29, box4, [0], [model.inputs[0].shape[2], model.inputs[0].shape[1]]); t.resize = tf4.image.cropAndResize(image29, box5, [0], [model.inputs[0].shape[2], model.inputs[0].shape[1]]);
const obj = { age: 0, gender: "unknown", genderScore: 0, race: [] }; const obj = { age: 0, gender: "unknown", genderScore: 0, race: [] };
if ((_a2 = config3.face["gear"]) == null ? void 0 : _a2.enabled) if ((_a2 = config3.face["gear"]) == null ? void 0 : _a2.enabled)
[t.age, t.gender, t.race] = model.execute(t.resize, ["age_output", "gender_output", "race_output"]); [t.age, t.gender, t.race] = model.execute(t.resize, ["age_output", "gender_output", "race_output"]);
@ -4911,44 +4911,44 @@ var UV33 = VTX33.map((x) => UV468[x]);
var UV7 = VTX7.map((x) => UV468[x]); var UV7 = VTX7.map((x) => UV468[x]);
// src/face/facemeshutil.ts // src/face/facemeshutil.ts
var getBoxSize = (box4) => [Math.abs(box4.endPoint[0] - box4.startPoint[0]), Math.abs(box4.endPoint[1] - box4.startPoint[1])]; var getBoxSize = (box5) => [Math.abs(box5.endPoint[0] - box5.startPoint[0]), Math.abs(box5.endPoint[1] - box5.startPoint[1])];
var getBoxCenter = (box4) => [box4.startPoint[0] + (box4.endPoint[0] - box4.startPoint[0]) / 2, box4.startPoint[1] + (box4.endPoint[1] - box4.startPoint[1]) / 2]; var getBoxCenter = (box5) => [box5.startPoint[0] + (box5.endPoint[0] - box5.startPoint[0]) / 2, box5.startPoint[1] + (box5.endPoint[1] - box5.startPoint[1]) / 2];
var getClampedBox = (box4, input) => box4 ? [ var getClampedBox = (box5, input) => box5 ? [
Math.trunc(Math.max(0, box4.startPoint[0])), Math.trunc(Math.max(0, box5.startPoint[0])),
Math.trunc(Math.max(0, box4.startPoint[1])), Math.trunc(Math.max(0, box5.startPoint[1])),
Math.trunc(Math.min(input.shape[2] || 0, box4.endPoint[0]) - Math.max(0, box4.startPoint[0])), Math.trunc(Math.min(input.shape[2] || 0, box5.endPoint[0]) - Math.max(0, box5.startPoint[0])),
Math.trunc(Math.min(input.shape[1] || 0, box4.endPoint[1]) - Math.max(0, box4.startPoint[1])) Math.trunc(Math.min(input.shape[1] || 0, box5.endPoint[1]) - Math.max(0, box5.startPoint[1]))
] : [0, 0, 0, 0]; ] : [0, 0, 0, 0];
var getRawBox = (box4, input) => box4 ? [ var getRawBox = (box5, input) => box5 ? [
box4.startPoint[0] / (input.shape[2] || 0), box5.startPoint[0] / (input.shape[2] || 0),
box4.startPoint[1] / (input.shape[1] || 0), box5.startPoint[1] / (input.shape[1] || 0),
(box4.endPoint[0] - box4.startPoint[0]) / (input.shape[2] || 0), (box5.endPoint[0] - box5.startPoint[0]) / (input.shape[2] || 0),
(box4.endPoint[1] - box4.startPoint[1]) / (input.shape[1] || 0) (box5.endPoint[1] - box5.startPoint[1]) / (input.shape[1] || 0)
] : [0, 0, 0, 0]; ] : [0, 0, 0, 0];
var scaleBoxCoordinates = (box4, factor) => { var scaleBoxCoordinates = (box5, factor) => {
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]]; const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]]; const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
return { startPoint, endPoint, landmarks: box4.landmarks, confidence: box4.confidence }; return { startPoint, endPoint, landmarks: box5.landmarks, confidence: box5.confidence };
}; };
var cutBoxFromImageAndResize = (box4, image29, cropSize) => { var cutBoxFromImageAndResize = (box5, image29, cropSize) => {
const h = image29.shape[1]; const h = image29.shape[1];
const w = image29.shape[2]; const w = image29.shape[2];
const crop2 = tf9.image.cropAndResize(image29, [[box4.startPoint[1] / h, box4.startPoint[0] / w, box4.endPoint[1] / h, box4.endPoint[0] / w]], [0], cropSize); const crop2 = tf9.image.cropAndResize(image29, [[box5.startPoint[1] / h, box5.startPoint[0] / w, box5.endPoint[1] / h, box5.endPoint[0] / w]], [0], cropSize);
const norm = tf9.div(crop2, constants.tf255); const norm = tf9.div(crop2, constants.tf255);
tf9.dispose(crop2); tf9.dispose(crop2);
return norm; return norm;
}; };
var enlargeBox = (box4, factor) => { var enlargeBox = (box5, factor) => {
const center = getBoxCenter(box4); const center = getBoxCenter(box5);
const size2 = getBoxSize(box4); const size2 = getBoxSize(box5);
const halfSize = [factor * size2[0] / 2, factor * size2[1] / 2]; const halfSize = [factor * size2[0] / 2, factor * size2[1] / 2];
return { startPoint: [center[0] - halfSize[0], center[1] - halfSize[1]], endPoint: [center[0] + halfSize[0], center[1] + halfSize[1]], landmarks: box4.landmarks, confidence: box4.confidence }; return { startPoint: [center[0] - halfSize[0], center[1] - halfSize[1]], endPoint: [center[0] + halfSize[0], center[1] + halfSize[1]], landmarks: box5.landmarks, confidence: box5.confidence };
}; };
var squarifyBox = (box4) => { var squarifyBox = (box5) => {
const centers = getBoxCenter(box4); const centers = getBoxCenter(box5);
const size2 = getBoxSize(box4); const size2 = getBoxSize(box5);
const halfSize = Math.max(...size2) / 2; const halfSize = Math.max(...size2) / 2;
return { startPoint: [Math.round(centers[0] - halfSize), Math.round(centers[1] - halfSize)], endPoint: [Math.round(centers[0] + halfSize), Math.round(centers[1] + halfSize)], landmarks: box4.landmarks, confidence: box4.confidence }; return { startPoint: [Math.round(centers[0] - halfSize), Math.round(centers[1] - halfSize)], endPoint: [Math.round(centers[0] + halfSize), Math.round(centers[1] + halfSize)], landmarks: box5.landmarks, confidence: box5.confidence };
}; };
var calculateLandmarksBoundingBox = (landmarks) => { var calculateLandmarksBoundingBox = (landmarks) => {
const xs = landmarks.map((d) => d[0]); const xs = landmarks.map((d) => d[0]);
@ -5016,8 +5016,8 @@ function generateAnchors(inputSize9) {
} }
return anchors4; return anchors4;
} }
function transformRawCoords(coordsRaw, box4, angle, rotationMatrix, inputSize9) { function transformRawCoords(coordsRaw, box5, angle, rotationMatrix, inputSize9) {
const boxSize = getBoxSize(box4); const boxSize = getBoxSize(box5);
const coordsScaled = coordsRaw.map((coord) => [ const coordsScaled = coordsRaw.map((coord) => [
boxSize[0] / inputSize9 * (coord[0] - inputSize9 / 2), boxSize[0] / inputSize9 * (coord[0] - inputSize9 / 2),
boxSize[1] / inputSize9 * (coord[1] - inputSize9 / 2), boxSize[1] / inputSize9 * (coord[1] - inputSize9 / 2),
@ -5027,33 +5027,33 @@ function transformRawCoords(coordsRaw, box4, angle, rotationMatrix, inputSize9)
const coordsRotationMatrix = largeAngle ? buildRotationMatrix(angle, [0, 0]) : fixedRotationMatrix; const coordsRotationMatrix = largeAngle ? buildRotationMatrix(angle, [0, 0]) : fixedRotationMatrix;
const coordsRotated = largeAngle ? coordsScaled.map((coord) => [...rotatePoint(coord, coordsRotationMatrix), coord[2]]) : coordsScaled; const coordsRotated = largeAngle ? coordsScaled.map((coord) => [...rotatePoint(coord, coordsRotationMatrix), coord[2]]) : coordsScaled;
const inverseRotationMatrix = largeAngle ? invertTransformMatrix(rotationMatrix) : fixedRotationMatrix; const inverseRotationMatrix = largeAngle ? invertTransformMatrix(rotationMatrix) : fixedRotationMatrix;
const boxCenter = [...getBoxCenter({ startPoint: box4.startPoint, endPoint: box4.endPoint }), 1]; const boxCenter = [...getBoxCenter({ startPoint: box5.startPoint, endPoint: box5.endPoint }), 1];
return coordsRotated.map((coord) => [ return coordsRotated.map((coord) => [
Math.round(coord[0] + dot(boxCenter, inverseRotationMatrix[0])), Math.round(coord[0] + dot(boxCenter, inverseRotationMatrix[0])),
Math.round(coord[1] + dot(boxCenter, inverseRotationMatrix[1])), Math.round(coord[1] + dot(boxCenter, inverseRotationMatrix[1])),
Math.round(coord[2] || 0) Math.round(coord[2] || 0)
]); ]);
} }
function correctFaceRotation(rotate, box4, input, inputSize9) { function correctFaceRotation(rotate, box5, input, inputSize9) {
const symmetryLine = box4.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine; const symmetryLine = box5.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine;
let angle = 0; let angle = 0;
let rotationMatrix = fixedRotationMatrix; let rotationMatrix = fixedRotationMatrix;
let face5; let face5;
if (rotate && env.kernels.includes("rotatewithoffset")) { if (rotate && env.kernels.includes("rotatewithoffset")) {
angle = computeRotation(box4.landmarks[symmetryLine[0]], box4.landmarks[symmetryLine[1]]); angle = computeRotation(box5.landmarks[symmetryLine[0]], box5.landmarks[symmetryLine[1]]);
const largeAngle = angle && angle !== 0 && Math.abs(angle) > 0.2; const largeAngle = angle && angle !== 0 && Math.abs(angle) > 0.2;
if (largeAngle) { if (largeAngle) {
const center = getBoxCenter({ startPoint: box4.startPoint, endPoint: box4.endPoint }); const center = getBoxCenter({ startPoint: box5.startPoint, endPoint: box5.endPoint });
const centerRaw = [center[0] / input.shape[2], center[1] / input.shape[1]]; const centerRaw = [center[0] / input.shape[2], center[1] / input.shape[1]];
const rotated = tf9.image.rotateWithOffset(input, angle, 0, centerRaw); const rotated = tf9.image.rotateWithOffset(input, angle, 0, centerRaw);
rotationMatrix = buildRotationMatrix(-angle, center); rotationMatrix = buildRotationMatrix(-angle, center);
face5 = cutBoxFromImageAndResize(box4, rotated, [inputSize9, inputSize9]); face5 = cutBoxFromImageAndResize(box5, rotated, [inputSize9, inputSize9]);
tf9.dispose(rotated); tf9.dispose(rotated);
} else { } else {
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]); face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
} }
} else { } else {
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]); face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
} }
return [angle, rotationMatrix, face5]; return [angle, rotationMatrix, face5];
} }
@ -5238,41 +5238,39 @@ async function createAnchors() {
} }
anchorTensor = { x: tf11.tensor1d(anchors4.map((a) => a.x)), y: tf11.tensor1d(anchors4.map((a) => a.y)) }; anchorTensor = { x: tf11.tensor1d(anchors4.map((a) => a.x)), y: tf11.tensor1d(anchors4.map((a) => a.y)) };
} }
var cropFactor = [5, 5];
function decodeBoxes(boxesTensor, anchor) { // src/util/box.ts
return tf11.tidy(() => { function calc(keypoints, outputSize2 = [1, 1]) {
const split5 = tf11.split(boxesTensor, 12, 1); const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
let xCenter = tf11.squeeze(split5[0]); const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
let yCenter = tf11.squeeze(split5[1]); const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
let width = tf11.squeeze(split5[2]); const box5 = [min2[0], min2[1], max4[0] - min2[0], max4[1] - min2[1]];
let height = tf11.squeeze(split5[3]); const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
xCenter = tf11.add(tf11.div(xCenter, inputSize2), anchor.x); return { box: box5, boxRaw };
yCenter = tf11.add(tf11.div(yCenter, inputSize2), anchor.y);
width = tf11.mul(tf11.div(width, inputSize2), cropFactor[0]);
height = tf11.mul(tf11.div(height, inputSize2), cropFactor[1]);
const xMin = tf11.sub(xCenter, tf11.div(width, 2));
const yMin = tf11.sub(yCenter, tf11.div(height, 2));
const boxes = tf11.stack([xMin, yMin, width, height], 1);
return boxes;
});
} }
async function decode(boxesTensor, logitsTensor, config3, outputSize2) { function square(keypoints, outputSize2 = [1, 1]) {
const t = {}; const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
t.boxes = decodeBoxes(boxesTensor, anchorTensor); const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
t.scores = tf11.sigmoid(logitsTensor); const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
t.argmax = tf11.argMax(t.scores); const center = [(min2[0] + max4[0]) / 2, (min2[1] + max4[1]) / 2];
const i = (await t.argmax.data())[0]; const dist = Math.max(center[0] - min2[0], center[1] - min2[1], -center[0] + max4[0], -center[1] + max4[1]);
const scores = await t.scores.data(); const box5 = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];
const detected = []; const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
const minScore = config3.body["detector"] && config3.body["detector"]["minConfidence"] ? config3.body["detector"]["minConfidence"] : 0; return { box: box5, boxRaw };
if (scores[i] >= minScore) { }
const boxes = await t.boxes.array(); function scale(box5, scaleFact) {
const boxRaw = boxes[i]; const dist = [box5[2] * scaleFact, box5[3] * scaleFact];
const box4 = [boxRaw[0] * outputSize2[0], boxRaw[1] * outputSize2[1], boxRaw[2] * outputSize2[0], boxRaw[3] * outputSize2[1]]; const newBox = [
detected.push({ box: box4, boxRaw, score: scores[i] }); box5[0] - (dist[0] - box5[2]) / 2,
} box5[1] - (dist[1] - box5[3]) / 2,
Object.keys(t).forEach((tensor3) => tf11.dispose(t[tensor3])); dist[0],
return detected; dist[1]
];
return newBox;
}
function crop(box5) {
const yxBox = [Math.max(0, box5[1]), Math.max(0, box5[0]), Math.min(1, box5[3] + box5[1]), Math.min(1, box5[2] + box5[0])];
return yxBox;
} }
// src/body/blazepose.ts // src/body/blazepose.ts
@ -5285,7 +5283,7 @@ var outputNodes = {
detector: [] detector: []
}; };
var cache = null; var cache = null;
var lastBox; var cropBox;
var padding = [[0, 0], [0, 0], [0, 0], [0, 0]]; var padding = [[0, 0], [0, 0], [0, 0], [0, 0]];
var lastTime5 = 0; var lastTime5 = 0;
var sigmoid3 = (x) => 1 - 1 / (1 + Math.exp(x)); var sigmoid3 = (x) => 1 - 1 / (1 + Math.exp(x));
@ -5322,39 +5320,37 @@ async function loadPose(config3) {
log("cached model:", models.landmarks["modelUrl"]); log("cached model:", models.landmarks["modelUrl"]);
return models.landmarks; return models.landmarks;
} }
function calculateBoxes(keypoints, outputSize2) { async function prepareImage(input, size2) {
const x = keypoints.map((a) => a.position[0]);
const y = keypoints.map((a) => a.position[1]);
const keypointsBox = [Math.min(...x), Math.min(...y), Math.max(...x) - Math.min(...x), Math.max(...y) - Math.min(...y)];
const keypointsBoxRaw = [keypointsBox[0] / outputSize2[0], keypointsBox[1] / outputSize2[1], keypointsBox[2] / outputSize2[0], keypointsBox[3] / outputSize2[1]];
return { keypointsBox, keypointsBoxRaw };
}
async function prepareImage(input, size2, box4) {
const t = {}; const t = {};
if (!input.shape || !input.shape[1] || !input.shape[2]) if (!input.shape || !input.shape[1] || !input.shape[2])
return input; return input;
let final; let final;
if (cropBox) {
t.cropped = tf12.image.cropAndResize(input, [cropBox], [0], [input.shape[1], input.shape[2]]);
}
if (input.shape[1] !== input.shape[2]) { if (input.shape[1] !== input.shape[2]) {
const height = box4 ? [Math.trunc(input.shape[1] * box4[1]), Math.trunc(input.shape[1] * (box4[1] + box4[3]))] : [input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0, input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0]; const height = [
const width = box4 ? [Math.trunc(input.shape[2] * box4[0]), Math.trunc(input.shape[2] * (box4[0] + box4[2]))] : [input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0, input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0]; input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0,
input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0
];
const width = [
input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0,
input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0
];
padding = [ padding = [
[0, 0], [0, 0],
height, height,
width, width,
[0, 0] [0, 0]
]; ];
if (box4) { t.pad = tf12.pad(t.cropped || input, padding);
t.resize = tf12.image.cropAndResize(input, [box4], [0], [size2, size2]); t.resize = tf12.image.resizeBilinear(t.pad, [size2, size2]);
} else {
t.pad = tf12.pad(input, padding);
t.resize = tf12.image.resizeBilinear(t.pad, [size2, size2]);
}
final = tf12.div(t.resize, constants.tf255); final = tf12.div(t.resize, constants.tf255);
} else if (input.shape[1] !== size2) { } else if (input.shape[1] !== size2) {
t.resize = tf12.image.resizeBilinear(input, [size2, size2]); t.resize = tf12.image.resizeBilinear(t.cropped || input, [size2, size2]);
final = tf12.div(t.resize, constants.tf255); final = tf12.div(t.resize, constants.tf255);
} else { } else {
final = tf12.div(input, constants.tf255); final = tf12.div(t.cropped || input, constants.tf255);
} }
Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3])); Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3]));
return final; return final;
@ -5368,19 +5364,21 @@ function rescaleKeypoints(keypoints, outputSize2) {
]; ];
kpt4.positionRaw = [kpt4.position[0] / outputSize2[0], kpt4.position[1] / outputSize2[1], kpt4.position[2]]; kpt4.positionRaw = [kpt4.position[0] / outputSize2[0], kpt4.position[1] / outputSize2[1], kpt4.position[2]];
} }
return keypoints; if (cropBox) {
} for (const kpt4 of keypoints) {
function rescaleBoxes(boxes, outputSize2) { kpt4.positionRaw = [
for (const box4 of boxes) { kpt4.positionRaw[0] + cropBox[1],
box4.box = [ kpt4.positionRaw[1] + cropBox[0],
Math.trunc(box4.box[0] * (outputSize2[0] + padding[2][0] + padding[2][1]) / outputSize2[0]), kpt4.positionRaw[2]
Math.trunc(box4.box[1] * (outputSize2[1] + padding[1][0] + padding[1][1]) / outputSize2[1]), ];
Math.trunc(box4.box[2] * (outputSize2[0] + padding[2][0] + padding[2][1]) / outputSize2[0]), kpt4.position = [
Math.trunc(box4.box[3] * (outputSize2[1] + padding[1][0] + padding[1][1]) / outputSize2[1]) Math.trunc(kpt4.positionRaw[0] * outputSize2[0]),
]; Math.trunc(kpt4.positionRaw[1] * outputSize2[1]),
box4.boxRaw = [box4.box[0] / outputSize2[0], box4.box[1] / outputSize2[1], box4.box[2] / outputSize2[0], box4.box[3] / outputSize2[1]]; kpt4.positionRaw[2]
];
}
} }
return boxes; return keypoints;
} }
async function detectLandmarks(input, config3, outputSize2) { async function detectLandmarks(input, config3, outputSize2) {
var _a; var _a;
@ -5402,7 +5400,8 @@ async function detectLandmarks(input, config3, outputSize2) {
if (poseScore < (config3.body.minConfidence || 0)) if (poseScore < (config3.body.minConfidence || 0))
return null; return null;
const keypoints = rescaleKeypoints(keypointsRelative, outputSize2); const keypoints = rescaleKeypoints(keypointsRelative, outputSize2);
const boxes = calculateBoxes(keypoints, [outputSize2[0], outputSize2[1]]); const kpts = keypoints.map((k) => k.position);
const boxes = calc(kpts, [outputSize2[0], outputSize2[1]]);
const annotations2 = {}; const annotations2 = {};
for (const [name, indexes] of Object.entries(connected)) { for (const [name, indexes] of Object.entries(connected)) {
const pt = []; const pt = [];
@ -5414,22 +5413,9 @@ async function detectLandmarks(input, config3, outputSize2) {
} }
annotations2[name] = pt; annotations2[name] = pt;
} }
const body4 = { id: 0, score: Math.trunc(100 * poseScore) / 100, box: boxes.keypointsBox, boxRaw: boxes.keypointsBoxRaw, keypoints, annotations: annotations2 }; const body4 = { id: 0, score: Math.trunc(100 * poseScore) / 100, box: boxes.box, boxRaw: boxes.boxRaw, keypoints, annotations: annotations2 };
return body4; return body4;
} }
async function detectBoxes(input, config3, outputSize2) {
var _a;
const t = {};
t.res = (_a = models.detector) == null ? void 0 : _a.execute(input, ["Identity"]);
t.logitsRaw = tf12.slice(t.res, [0, 0, 0], [1, -1, 1]);
t.boxesRaw = tf12.slice(t.res, [0, 0, 1], [1, -1, -1]);
t.logits = tf12.squeeze(t.logitsRaw);
t.boxes = tf12.squeeze(t.boxesRaw);
const boxes = await decode(t.boxes, t.logits, config3, outputSize2);
rescaleBoxes(boxes, outputSize2);
Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3]));
return boxes;
}
async function predict5(input, config3) { async function predict5(input, config3) {
const outputSize2 = [input.shape[2] || 0, input.shape[1] || 0]; const outputSize2 = [input.shape[2] || 0, input.shape[1] || 0];
const skipTime = (config3.body.skipTime || 0) > now() - lastTime5; const skipTime = (config3.body.skipTime || 0) > now() - lastTime5;
@ -5438,26 +5424,13 @@ async function predict5(input, config3) {
skipped5++; skipped5++;
} else { } else {
const t = {}; const t = {};
if (config3.body["detector"] && config3.body["detector"]["enabled"]) { t.landmarks = await prepareImage(input, 256);
t.detector = await prepareImage(input, 224); cache = await detectLandmarks(t.landmarks, config3, outputSize2);
const boxes = await detectBoxes(t.detector, config3, outputSize2);
if (boxes && boxes.length === 1) {
t.landmarks = await prepareImage(input, 256, boxes[0].box);
cache = await detectLandmarks(t.landmarks, config3, outputSize2);
}
if (cache)
cache.score = boxes[0].score;
} else {
t.landmarks = await prepareImage(input, 256, lastBox);
cache = await detectLandmarks(t.landmarks, config3, outputSize2);
}
Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3])); Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3]));
lastTime5 = now(); lastTime5 = now();
skipped5 = 0; skipped5 = 0;
} }
if (cache) return cache ? [cache] : [];
return [cache];
return [];
} }
// src/object/centernet.ts // src/object/centernet.ts
@ -5598,13 +5571,13 @@ async function process3(res, outputShape, config3) {
detections[0][id][2] / inputSize4 - x, detections[0][id][2] / inputSize4 - x,
detections[0][id][3] / inputSize4 - y detections[0][id][3] / inputSize4 - y
]; ];
const box4 = [ const box5 = [
Math.trunc(boxRaw[0] * outputShape[0]), Math.trunc(boxRaw[0] * outputShape[0]),
Math.trunc(boxRaw[1] * outputShape[1]), Math.trunc(boxRaw[1] * outputShape[1]),
Math.trunc(boxRaw[2] * outputShape[0]), Math.trunc(boxRaw[2] * outputShape[0]),
Math.trunc(boxRaw[3] * outputShape[1]) Math.trunc(boxRaw[3] * outputShape[1])
]; ];
results.push({ id: i++, score, class: classVal, label, box: box4, boxRaw }); results.push({ id: i++, score, class: classVal, label, box: box5, boxRaw });
} }
Object.keys(t).forEach((tensor3) => tf13.dispose(t[tensor3])); Object.keys(t).forEach((tensor3) => tf13.dispose(t[tensor3]));
return results; return results;
@ -5725,10 +5698,10 @@ async function predict7(image29, config3) {
tf14.dispose(tensor3); tf14.dispose(tensor3);
if (resT) { if (resT) {
cache2.keypoints.length = 0; cache2.keypoints.length = 0;
const squeeze11 = resT.squeeze(); const squeeze10 = resT.squeeze();
tf14.dispose(resT); tf14.dispose(resT);
const stack5 = squeeze11.unstack(2); const stack5 = squeeze10.unstack(2);
tf14.dispose(squeeze11); tf14.dispose(squeeze10);
for (let id = 0; id < stack5.length; id++) { for (let id = 0; id < stack5.length; id++) {
const [x2, y2, partScore] = await max2d(stack5[id], config3.body.minConfidence); const [x2, y2, partScore] = await max2d(stack5[id], config3.body.minConfidence);
if (partScore > (((_a = config3.body) == null ? void 0 : _a.minConfidence) || 0)) { if (partScore > (((_a = config3.body) == null ? void 0 : _a.minConfidence) || 0)) {
@ -5946,20 +5919,20 @@ var getLeftToRightEyeDepthDifference = (rawCoords) => {
return leftEyeZ - rightEyeZ; return leftEyeZ - rightEyeZ;
}; };
var getEyeBox = (rawCoords, face5, eyeInnerCornerIndex, eyeOuterCornerIndex, meshSize, flip = false) => { var getEyeBox = (rawCoords, face5, eyeInnerCornerIndex, eyeOuterCornerIndex, meshSize, flip = false) => {
const box4 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge)); const box5 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge));
const boxSize = getBoxSize(box4); const boxSize = getBoxSize(box5);
let crop2 = tf17.image.cropAndResize(face5, [[ let crop2 = tf17.image.cropAndResize(face5, [[
box4.startPoint[1] / meshSize, box5.startPoint[1] / meshSize,
box4.startPoint[0] / meshSize, box5.startPoint[0] / meshSize,
box4.endPoint[1] / meshSize, box5.endPoint[1] / meshSize,
box4.endPoint[0] / meshSize box5.endPoint[0] / meshSize
]], [0], [inputSize5, inputSize5]); ]], [0], [inputSize5, inputSize5]);
if (flip && env.kernels.includes("flipleftright")) { if (flip && env.kernels.includes("flipleftright")) {
const flipped = tf17.image.flipLeftRight(crop2); const flipped = tf17.image.flipLeftRight(crop2);
tf17.dispose(crop2); tf17.dispose(crop2);
crop2 = flipped; crop2 = flipped;
} }
return { box: box4, boxSize, crop: crop2 }; return { box: box5, boxSize, crop: crop2 };
}; };
var getEyeCoords = (eyeData, eyeBox, eyeBoxSize, flip = false) => { var getEyeCoords = (eyeData, eyeBox, eyeBoxSize, flip = false) => {
const eyeRawCoords = []; const eyeRawCoords = [];
@ -6053,7 +6026,7 @@ async function predict10(input, config3) {
const newCache = []; const newCache = [];
let id = 0; let id = 0;
for (let i = 0; i < boxCache.length; i++) { for (let i = 0; i < boxCache.length; i++) {
let box4 = boxCache[i]; let box5 = boxCache[i];
let angle = 0; let angle = 0;
let rotationMatrix; let rotationMatrix;
const face5 = { const face5 = {
@ -6067,20 +6040,20 @@ async function predict10(input, config3) {
faceScore: 0, faceScore: 0,
annotations: {} annotations: {}
}; };
[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) ? inputSize6 : size()); [angle, rotationMatrix, face5.tensor] = correctFaceRotation((_d = config3.face.detector) == null ? void 0 : _d.rotation, box5, input, ((_e = config3.face.mesh) == null ? void 0 : _e.enabled) ? inputSize6 : size());
if ((_f = config3 == null ? void 0 : config3.filter) == null ? void 0 : _f.equalization) { if ((_f = config3 == null ? void 0 : config3.filter) == null ? void 0 : _f.equalization) {
const equilized = await histogramEqualization(face5.tensor); const equilized = await histogramEqualization(face5.tensor);
tf18.dispose(face5.tensor); tf18.dispose(face5.tensor);
face5.tensor = equilized; face5.tensor = equilized;
} }
face5.boxScore = Math.round(100 * box4.confidence) / 100; face5.boxScore = Math.round(100 * box5.confidence) / 100;
if (!((_g = config3.face.mesh) == null ? void 0 : _g.enabled)) { if (!((_g = config3.face.mesh) == null ? void 0 : _g.enabled)) {
face5.box = getClampedBox(box4, input); face5.box = getClampedBox(box5, input);
face5.boxRaw = getRawBox(box4, input); face5.boxRaw = getRawBox(box5, input);
face5.score = face5.boxScore; face5.score = face5.boxScore;
face5.mesh = box4.landmarks.map((pt) => [ face5.mesh = box5.landmarks.map((pt) => [
(box4.startPoint[0] + box4.endPoint[0]) / 2 + (box4.endPoint[0] + box4.startPoint[0]) * pt[0] / size(), (box5.startPoint[0] + box5.endPoint[0]) / 2 + (box5.endPoint[0] + box5.startPoint[0]) * pt[0] / size(),
(box4.startPoint[1] + box4.endPoint[1]) / 2 + (box4.endPoint[1] + box4.startPoint[1]) * pt[1] / size() (box5.startPoint[1] + box5.endPoint[1]) / 2 + (box5.endPoint[1] + box5.startPoint[1]) * pt[1] / size()
]); ]);
face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]); face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]);
for (const key of Object.keys(blazeFaceLandmarks)) for (const key of Object.keys(blazeFaceLandmarks))
@ -6096,24 +6069,24 @@ async function predict10(input, config3) {
let rawCoords = await coordsReshaped.array(); let rawCoords = await coordsReshaped.array();
tf18.dispose([contourCoords, coordsReshaped, confidence, contours]); tf18.dispose([contourCoords, coordsReshaped, confidence, contours]);
if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) { if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
box4.confidence = face5.faceScore; box5.confidence = face5.faceScore;
} else { } else {
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled) if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize6); rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize6);
face5.mesh = transformRawCoords(rawCoords, box4, angle, rotationMatrix, inputSize6); face5.mesh = transformRawCoords(rawCoords, box5, angle, rotationMatrix, inputSize6);
face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]); face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]);
for (const key of Object.keys(meshAnnotations)) for (const key of Object.keys(meshAnnotations))
face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]); face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]);
const boxCalculated = calculateLandmarksBoundingBox(face5.mesh); const boxCalculated = calculateLandmarksBoundingBox(face5.mesh);
const boxEnlarged = enlargeBox(boxCalculated, ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6); const boxEnlarged = enlargeBox(boxCalculated, ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6);
const boxSquared = squarifyBox(boxEnlarged); const boxSquared = squarifyBox(boxEnlarged);
box4 = { ...boxSquared, confidence: box4.confidence }; box5 = { ...boxSquared, confidence: box5.confidence };
face5.box = getClampedBox(box4, input); face5.box = getClampedBox(box5, input);
face5.boxRaw = getRawBox(box4, input); face5.boxRaw = getRawBox(box5, input);
face5.score = face5.faceScore; face5.score = face5.faceScore;
newCache.push(box4); newCache.push(box5);
tf18.dispose(face5.tensor); tf18.dispose(face5.tensor);
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_k = config3.face.detector) == null ? void 0 : _k.rotation, box4, input, inputSize6); [angle, rotationMatrix, face5.tensor] = correctFaceRotation((_k = config3.face.detector) == null ? void 0 : _k.rotation, box5, input, inputSize6);
} }
} }
faces.push(face5); faces.push(face5);
@ -6226,54 +6199,54 @@ var tf21 = __toModule(require_tfjs_esm());
// src/hand/handposeutil.ts // src/hand/handposeutil.ts
var tf20 = __toModule(require_tfjs_esm()); var tf20 = __toModule(require_tfjs_esm());
function getBoxSize2(box4) { function getBoxSize2(box5) {
return [ return [
Math.abs(box4.endPoint[0] - box4.startPoint[0]), Math.abs(box5.endPoint[0] - box5.startPoint[0]),
Math.abs(box4.endPoint[1] - box4.startPoint[1]) Math.abs(box5.endPoint[1] - box5.startPoint[1])
]; ];
} }
function getBoxCenter2(box4) { function getBoxCenter2(box5) {
return [ return [
box4.startPoint[0] + (box4.endPoint[0] - box4.startPoint[0]) / 2, box5.startPoint[0] + (box5.endPoint[0] - box5.startPoint[0]) / 2,
box4.startPoint[1] + (box4.endPoint[1] - box4.startPoint[1]) / 2 box5.startPoint[1] + (box5.endPoint[1] - box5.startPoint[1]) / 2
]; ];
} }
function cutBoxFromImageAndResize2(box4, image29, cropSize) { function cutBoxFromImageAndResize2(box5, image29, cropSize) {
const h = image29.shape[1]; const h = image29.shape[1];
const w = image29.shape[2]; const w = image29.shape[2];
const boxes = [[ const boxes = [[
box4.startPoint[1] / h, box5.startPoint[1] / h,
box4.startPoint[0] / w, box5.startPoint[0] / w,
box4.endPoint[1] / h, box5.endPoint[1] / h,
box4.endPoint[0] / w box5.endPoint[0] / w
]]; ]];
return tf20.image.cropAndResize(image29, boxes, [0], cropSize); return tf20.image.cropAndResize(image29, boxes, [0], cropSize);
} }
function scaleBoxCoordinates2(box4, factor) { function scaleBoxCoordinates2(box5, factor) {
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]]; const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]]; const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
const palmLandmarks = box4.palmLandmarks.map((coord) => { const palmLandmarks = box5.palmLandmarks.map((coord) => {
const scaledCoord = [coord[0] * factor[0], coord[1] * factor[1]]; const scaledCoord = [coord[0] * factor[0], coord[1] * factor[1]];
return scaledCoord; return scaledCoord;
}); });
return { startPoint, endPoint, palmLandmarks, confidence: box4.confidence }; return { startPoint, endPoint, palmLandmarks, confidence: box5.confidence };
} }
function enlargeBox2(box4, factor = 1.5) { function enlargeBox2(box5, factor = 1.5) {
const center = getBoxCenter2(box4); const center = getBoxCenter2(box5);
const size2 = getBoxSize2(box4); const size2 = getBoxSize2(box5);
const newHalfSize = [factor * size2[0] / 2, factor * size2[1] / 2]; const newHalfSize = [factor * size2[0] / 2, factor * size2[1] / 2];
const startPoint = [center[0] - newHalfSize[0], center[1] - newHalfSize[1]]; const startPoint = [center[0] - newHalfSize[0], center[1] - newHalfSize[1]];
const endPoint = [center[0] + newHalfSize[0], center[1] + newHalfSize[1]]; const endPoint = [center[0] + newHalfSize[0], center[1] + newHalfSize[1]];
return { startPoint, endPoint, palmLandmarks: box4.palmLandmarks }; return { startPoint, endPoint, palmLandmarks: box5.palmLandmarks };
} }
function squarifyBox2(box4) { function squarifyBox2(box5) {
const centers = getBoxCenter2(box4); const centers = getBoxCenter2(box5);
const size2 = getBoxSize2(box4); const size2 = getBoxSize2(box5);
const maxEdge = Math.max(...size2); const maxEdge = Math.max(...size2);
const halfSize = maxEdge / 2; const halfSize = maxEdge / 2;
const startPoint = [centers[0] - halfSize, centers[1] - halfSize]; const startPoint = [centers[0] - halfSize, centers[1] - halfSize];
const endPoint = [centers[0] + halfSize, centers[1] + halfSize]; const endPoint = [centers[0] + halfSize, centers[1] + halfSize];
return { startPoint, endPoint, palmLandmarks: box4.palmLandmarks }; return { startPoint, endPoint, palmLandmarks: box5.palmLandmarks };
} }
function normalizeRadians2(angle) { function normalizeRadians2(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));
@ -9347,9 +9320,9 @@ var HandDetector = class {
p.slice = tf21.slice(t.predictions, [index2, 5], [1, 14]); p.slice = tf21.slice(t.predictions, [index2, 5], [1, 14]);
p.norm = this.normalizeLandmarks(p.slice, index2); p.norm = this.normalizeLandmarks(p.slice, index2);
p.palmLandmarks = tf21.reshape(p.norm, [-1, 2]); p.palmLandmarks = tf21.reshape(p.norm, [-1, 2]);
const box4 = await p.box.data(); const box5 = await p.box.data();
const startPoint = box4.slice(0, 2); const startPoint = box5.slice(0, 2);
const endPoint = box4.slice(2, 4); const endPoint = box5.slice(2, 4);
const palmLandmarks = await p.palmLandmarks.array(); const palmLandmarks = await p.palmLandmarks.array();
const hand3 = { startPoint, endPoint, palmLandmarks, confidence: scores[index2] }; const hand3 = { startPoint, endPoint, palmLandmarks, confidence: scores[index2] };
const scaled = scaleBoxCoordinates2(hand3, [input.shape[2] / this.inputSize, input.shape[1] / this.inputSize]); const scaled = scaleBoxCoordinates2(hand3, [input.shape[2] / this.inputSize, input.shape[1] / this.inputSize]);
@ -9936,24 +9909,24 @@ async function predict12(input, config3) {
} }
} }
const keypoints = predictions[i].landmarks; const keypoints = predictions[i].landmarks;
let box4 = [Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, 0, 0]; let box5 = [Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, 0, 0];
let boxRaw = [0, 0, 0, 0]; let boxRaw = [0, 0, 0, 0];
if (keypoints && keypoints.length > 0) { if (keypoints && keypoints.length > 0) {
for (const pt of keypoints) { for (const pt of keypoints) {
if (pt[0] < box4[0]) if (pt[0] < box5[0])
box4[0] = pt[0]; box5[0] = pt[0];
if (pt[1] < box4[1]) if (pt[1] < box5[1])
box4[1] = pt[1]; box5[1] = pt[1];
if (pt[0] > box4[2]) if (pt[0] > box5[2])
box4[2] = pt[0]; box5[2] = pt[0];
if (pt[1] > box4[3]) if (pt[1] > box5[3])
box4[3] = pt[1]; box5[3] = pt[1];
} }
box4[2] -= box4[0]; box5[2] -= box5[0];
box4[3] -= box4[1]; box5[3] -= box5[1];
boxRaw = [box4[0] / (input.shape[2] || 0), box4[1] / (input.shape[1] || 0), box4[2] / (input.shape[2] || 0), box4[3] / (input.shape[1] || 0)]; boxRaw = [box5[0] / (input.shape[2] || 0), box5[1] / (input.shape[1] || 0), box5[2] / (input.shape[2] || 0), box5[3] / (input.shape[1] || 0)];
} else { } else {
box4 = predictions[i].box ? [ box5 = predictions[i].box ? [
Math.trunc(Math.max(0, predictions[i].box.topLeft[0])), Math.trunc(Math.max(0, predictions[i].box.topLeft[0])),
Math.trunc(Math.max(0, predictions[i].box.topLeft[1])), Math.trunc(Math.max(0, predictions[i].box.topLeft[1])),
Math.trunc(Math.min(input.shape[2] || 0, predictions[i].box.bottomRight[0]) - Math.max(0, predictions[i].box.topLeft[0])), Math.trunc(Math.min(input.shape[2] || 0, predictions[i].box.bottomRight[0]) - Math.max(0, predictions[i].box.topLeft[0])),
@ -9973,7 +9946,7 @@ async function predict12(input, config3) {
boxScore: Math.round(100 * predictions[i].boxConfidence) / 100, boxScore: Math.round(100 * predictions[i].boxConfidence) / 100,
fingerScore: Math.round(100 * predictions[i].fingerConfidence) / 100, fingerScore: Math.round(100 * predictions[i].fingerConfidence) / 100,
label: "hand", label: "hand",
box: box4, box: box5,
boxRaw, boxRaw,
keypoints, keypoints,
annotations: annotations2, annotations: annotations2,
@ -10014,40 +9987,6 @@ async function load13(config3) {
return [handDetectorModel, handPoseModel]; return [handDetectorModel, handPoseModel];
} }
// src/util/box.ts
function calc(keypoints, outputSize2 = [1, 1]) {
const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
const box4 = [min2[0], min2[1], max4[0] - min2[0], max4[1] - min2[1]];
const boxRaw = [box4[0] / outputSize2[0], box4[1] / outputSize2[1], box4[2] / outputSize2[0], box4[3] / outputSize2[1]];
return { box: box4, boxRaw };
}
function square(keypoints, outputSize2 = [1, 1]) {
const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
const center = [(min2[0] + max4[0]) / 2, (min2[1] + max4[1]) / 2];
const dist = Math.max(center[0] - min2[0], center[1] - min2[1], -center[0] + max4[0], -center[1] + max4[1]);
const box4 = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];
const boxRaw = [box4[0] / outputSize2[0], box4[1] / outputSize2[1], box4[2] / outputSize2[0], box4[3] / outputSize2[1]];
return { box: box4, boxRaw };
}
function scale(box4, scaleFact) {
const dist = [box4[2] * scaleFact, box4[3] * scaleFact];
const newBox = [
box4[0] - (dist[0] - box4[2]) / 2,
box4[1] - (dist[1] - box4[3]) / 2,
dist[0],
dist[1]
];
return newBox;
}
function crop(box4) {
const yxBox = [Math.max(0, box4[1]), Math.max(0, box4[0]), Math.min(1, box4[3] + box4[1]), Math.min(1, box4[2] + box4[0])];
return yxBox;
}
// src/hand/handtrack.ts // src/hand/handtrack.ts
var tf24 = __toModule(require_tfjs_esm()); var tf24 = __toModule(require_tfjs_esm());
var models2 = [null, null]; var models2 = [null, null];
@ -10066,11 +10005,11 @@ var cache3 = {
hands: [] hands: []
}; };
var fingerMap = { var fingerMap = {
thumb: [1, 2, 3, 4], thumb: [0, 1, 2, 3, 4],
index: [5, 6, 7, 8], index: [0, 5, 6, 7, 8],
middle: [9, 10, 11, 12], middle: [0, 9, 10, 11, 12],
ring: [13, 14, 15, 16], ring: [0, 13, 14, 15, 16],
pinky: [17, 18, 19, 20], pinky: [0, 17, 18, 19, 20],
palm: [0] palm: [0]
}; };
async function loadDetect2(config3) { async function loadDetect2(config3) {
@ -10621,7 +10560,7 @@ async function process4(res, inputSize9, outputShape, config3) {
]; ];
let boxRaw = [x, y, w, h]; let boxRaw = [x, y, w, h];
boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1))); boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1)));
const box4 = [ const box5 = [
boxRaw[0] * outputShape[0], boxRaw[0] * outputShape[0],
boxRaw[1] * outputShape[1], boxRaw[1] * outputShape[1],
boxRaw[2] * outputShape[0], boxRaw[2] * outputShape[0],
@ -10632,7 +10571,7 @@ async function process4(res, inputSize9, outputShape, config3) {
score: Math.round(100 * score) / 100, score: Math.round(100 * score) / 100,
class: j + 1, class: j + 1,
label: labels[j].label, label: labels[j].label,
box: box4.map((a) => Math.trunc(a)), box: box5.map((a) => Math.trunc(a)),
boxRaw boxRaw
}; };
results.push(result); results.push(result);
@ -10975,7 +10914,7 @@ function getInstanceScore(existingPoses, keypoints) {
}, 0); }, 0);
return notOverlappedKeypointScores / keypoints.length; return notOverlappedKeypointScores / keypoints.length;
} }
function decode2(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) { function decode(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) {
const poses = []; const poses = [];
const queue = buildPartWithScoreQueue(minConfidence2, scores); const queue = buildPartWithScoreQueue(minConfidence2, scores);
while (poses.length < maxDetected && !queue.empty()) { while (poses.length < maxDetected && !queue.empty()) {
@ -10986,9 +10925,9 @@ function decode2(offsets, scores, displacementsFwd, displacementsBwd, maxDetecte
let keypoints = decodePose(root, scores, offsets, displacementsFwd, displacementsBwd); let keypoints = decodePose(root, scores, offsets, displacementsFwd, displacementsBwd);
keypoints = keypoints.filter((a) => a.score > minConfidence2); keypoints = keypoints.filter((a) => a.score > minConfidence2);
const score = getInstanceScore(poses, keypoints); const score = getInstanceScore(poses, keypoints);
const box4 = getBoundingBox(keypoints); const box5 = getBoundingBox(keypoints);
if (score > minConfidence2) if (score > minConfidence2)
poses.push({ keypoints, box: box4, score: Math.round(100 * score) / 100 }); poses.push({ keypoints, box: box5, score: Math.round(100 * score) / 100 });
} }
return poses; return poses;
} }
@ -11006,7 +10945,7 @@ async function predict17(input, config3) {
const buffers = await Promise.all(res.map((tensor3) => tensor3.buffer())); const buffers = await Promise.all(res.map((tensor3) => tensor3.buffer()));
for (const t of res) for (const t of res)
tf29.dispose(t); tf29.dispose(t);
const decoded = await decode2(buffers[0], buffers[1], buffers[2], buffers[3], config3.body.maxDetected, config3.body.minConfidence); const decoded = await decode(buffers[0], buffers[1], buffers[2], buffers[3], config3.body.maxDetected, config3.body.minConfidence);
if (!model16.inputs[0].shape) if (!model16.inputs[0].shape)
return []; return [];
const scaled = scalePoses(decoded, [input.shape[1], input.shape[2]], [model16.inputs[0].shape[2], model16.inputs[0].shape[1]]); const scaled = scalePoses(decoded, [input.shape[1], input.shape[2]], [model16.inputs[0].shape[2], model16.inputs[0].shape[1]]);
@ -12065,7 +12004,7 @@ var calculateFaceAngle = (face5, imageSize) => {
thetaY = 0; thetaY = 0;
if (isNaN(thetaZ)) if (isNaN(thetaZ))
thetaZ = 0; thetaZ = 0;
return { pitch: 2 * -thetaX, yaw: 2 * -thetaY, roll: 2 * -thetaZ }; return { pitch: -thetaX, yaw: -thetaY, roll: -thetaZ };
}; };
const meshToEulerAngle = (mesh2) => { const meshToEulerAngle = (mesh2) => {
const radians = (a1, a2, b1, b2) => Math.atan2(b2 - a2, b1 - a1); const radians = (a1, a2, b1, b2) => Math.atan2(b2 - a2, b1 - a1);
@ -12411,7 +12350,7 @@ function calc2(newResult, config3) {
bufferedResult.body = JSON.parse(JSON.stringify(newResult.body)); bufferedResult.body = JSON.parse(JSON.stringify(newResult.body));
} else { } else {
for (let i = 0; i < newResult.body.length; i++) { for (let i = 0; i < newResult.body.length; i++) {
const box4 = newResult.body[i].box.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor); const box5 = newResult.body[i].box.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor);
const boxRaw = newResult.body[i].boxRaw.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + newBoxCoord) / bufferedFactor); const boxRaw = newResult.body[i].boxRaw.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + newBoxCoord) / bufferedFactor);
const keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({ const keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({
score: newKpt.score, score: newKpt.score,
@ -12445,14 +12384,14 @@ function calc2(newResult, config3) {
} }
annotations2[name] = pt; annotations2[name] = pt;
} }
bufferedResult.body[i] = { ...newResult.body[i], box: box4, boxRaw, keypoints, annotations: annotations2 }; bufferedResult.body[i] = { ...newResult.body[i], box: box5, boxRaw, keypoints, annotations: annotations2 };
} }
} }
if (!bufferedResult.hand || newResult.hand.length !== bufferedResult.hand.length) { if (!bufferedResult.hand || newResult.hand.length !== bufferedResult.hand.length) {
bufferedResult.hand = JSON.parse(JSON.stringify(newResult.hand)); bufferedResult.hand = JSON.parse(JSON.stringify(newResult.hand));
} else { } else {
for (let i = 0; i < newResult.hand.length; i++) { for (let i = 0; i < newResult.hand.length; i++) {
const box4 = newResult.hand[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].box[j] + b) / bufferedFactor); const box5 = newResult.hand[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].box[j] + b) / bufferedFactor);
const boxRaw = newResult.hand[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].boxRaw[j] + b) / bufferedFactor); const boxRaw = newResult.hand[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].boxRaw[j] + b) / bufferedFactor);
if (bufferedResult.hand[i].keypoints.length !== newResult.hand[i].keypoints.length) if (bufferedResult.hand[i].keypoints.length !== newResult.hand[i].keypoints.length)
bufferedResult.hand[i].keypoints = newResult.hand[i].keypoints; bufferedResult.hand[i].keypoints = newResult.hand[i].keypoints;
@ -12466,14 +12405,14 @@ function calc2(newResult, config3) {
annotations2[key] = newResult.hand[i].annotations[key] && newResult.hand[i].annotations[key][0] ? newResult.hand[i].annotations[key].map((val, j) => val.map((coord, k) => ((bufferedFactor - 1) * bufferedResult.hand[i].annotations[key][j][k] + coord) / bufferedFactor)) : null; annotations2[key] = newResult.hand[i].annotations[key] && newResult.hand[i].annotations[key][0] ? newResult.hand[i].annotations[key].map((val, j) => val.map((coord, k) => ((bufferedFactor - 1) * bufferedResult.hand[i].annotations[key][j][k] + coord) / bufferedFactor)) : null;
} }
} }
bufferedResult.hand[i] = { ...newResult.hand[i], box: box4, boxRaw, keypoints, annotations: annotations2 }; bufferedResult.hand[i] = { ...newResult.hand[i], box: box5, boxRaw, keypoints, annotations: annotations2 };
} }
} }
if (!bufferedResult.face || newResult.face.length !== bufferedResult.face.length) { if (!bufferedResult.face || newResult.face.length !== bufferedResult.face.length) {
bufferedResult.face = JSON.parse(JSON.stringify(newResult.face)); bufferedResult.face = JSON.parse(JSON.stringify(newResult.face));
} else { } else {
for (let i = 0; i < newResult.face.length; i++) { for (let i = 0; i < newResult.face.length; i++) {
const box4 = newResult.face[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].box[j] + b) / bufferedFactor); const box5 = newResult.face[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].box[j] + b) / bufferedFactor);
const boxRaw = newResult.face[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].boxRaw[j] + b) / bufferedFactor); const boxRaw = newResult.face[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].boxRaw[j] + b) / bufferedFactor);
if (newResult.face[i].rotation) { if (newResult.face[i].rotation) {
const rotation = { matrix: [0, 0, 0, 0, 0, 0, 0, 0, 0], angle: { roll: 0, yaw: 0, pitch: 0 }, gaze: { bearing: 0, strength: 0 } }; const rotation = { matrix: [0, 0, 0, 0, 0, 0, 0, 0, 0], angle: { roll: 0, yaw: 0, pitch: 0 }, gaze: { bearing: 0, strength: 0 } };
@ -12487,18 +12426,18 @@ function calc2(newResult, config3) {
bearing: ((bufferedFactor - 1) * (((_u = (_t = bufferedResult.face[i].rotation) == null ? void 0 : _t.gaze) == null ? void 0 : _u.bearing) || 0) + (((_w = (_v = newResult.face[i].rotation) == null ? void 0 : _v.gaze) == null ? void 0 : _w.bearing) || 0)) / bufferedFactor, bearing: ((bufferedFactor - 1) * (((_u = (_t = bufferedResult.face[i].rotation) == null ? void 0 : _t.gaze) == null ? void 0 : _u.bearing) || 0) + (((_w = (_v = newResult.face[i].rotation) == null ? void 0 : _v.gaze) == null ? void 0 : _w.bearing) || 0)) / bufferedFactor,
strength: ((bufferedFactor - 1) * (((_y = (_x = bufferedResult.face[i].rotation) == null ? void 0 : _x.gaze) == null ? void 0 : _y.strength) || 0) + (((_A = (_z = newResult.face[i].rotation) == null ? void 0 : _z.gaze) == null ? void 0 : _A.strength) || 0)) / bufferedFactor strength: ((bufferedFactor - 1) * (((_y = (_x = bufferedResult.face[i].rotation) == null ? void 0 : _x.gaze) == null ? void 0 : _y.strength) || 0) + (((_A = (_z = newResult.face[i].rotation) == null ? void 0 : _z.gaze) == null ? void 0 : _A.strength) || 0)) / bufferedFactor
}; };
bufferedResult.face[i] = { ...newResult.face[i], rotation, box: box4, boxRaw }; bufferedResult.face[i] = { ...newResult.face[i], rotation, box: box5, boxRaw };
} }
bufferedResult.face[i] = { ...newResult.face[i], box: box4, boxRaw }; bufferedResult.face[i] = { ...newResult.face[i], box: box5, boxRaw };
} }
} }
if (!bufferedResult.object || newResult.object.length !== bufferedResult.object.length) { if (!bufferedResult.object || newResult.object.length !== bufferedResult.object.length) {
bufferedResult.object = JSON.parse(JSON.stringify(newResult.object)); bufferedResult.object = JSON.parse(JSON.stringify(newResult.object));
} else { } else {
for (let i = 0; i < newResult.object.length; i++) { for (let i = 0; i < newResult.object.length; i++) {
const box4 = newResult.object[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].box[j] + b) / bufferedFactor); const box5 = newResult.object[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].box[j] + b) / bufferedFactor);
const boxRaw = newResult.object[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].boxRaw[j] + b) / bufferedFactor); const boxRaw = newResult.object[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].boxRaw[j] + b) / bufferedFactor);
bufferedResult.object[i] = { ...newResult.object[i], box: box4, boxRaw }; bufferedResult.object[i] = { ...newResult.object[i], box: box5, boxRaw };
} }
} }
if (newResult.persons) { if (newResult.persons) {
@ -12507,7 +12446,7 @@ function calc2(newResult, config3) {
bufferedResult.persons = JSON.parse(JSON.stringify(newPersons)); bufferedResult.persons = JSON.parse(JSON.stringify(newPersons));
} else { } else {
for (let i = 0; i < newPersons.length; i++) { for (let i = 0; i < newPersons.length; i++) {
bufferedResult.persons[i].box = newPersons[i].box.map((box4, j) => ((bufferedFactor - 1) * bufferedResult.persons[i].box[j] + box4) / bufferedFactor); bufferedResult.persons[i].box = newPersons[i].box.map((box5, j) => ((bufferedFactor - 1) * bufferedResult.persons[i].box[j] + box5) / bufferedFactor);
} }
} }
} }
@ -12598,10 +12537,10 @@ function join2(faces, bodies, hands, gestures, shape) {
} }
const x = []; const x = [];
const y = []; const y = [];
const extractXY = (box4) => { const extractXY = (box5) => {
if (box4 && box4.length === 4) { if (box5 && box5.length === 4) {
x.push(box4[0], box4[0] + box4[2]); x.push(box5[0], box5[0] + box5[2]);
y.push(box4[1], box4[1] + box4[3]); y.push(box5[1], box5[1] + box5[3]);
} }
}; };
extractXY((_k = person2.face) == null ? void 0 : _k.box); extractXY((_k = person2.face) == null ? void 0 : _k.box);

View File

@ -981,8 +981,8 @@ function GLImageFilter() {
// src/image/enhance.ts // src/image/enhance.ts
var tf = __toModule(require_tfjs_esm()); var tf = __toModule(require_tfjs_esm());
async function histogramEqualization(inputImage) { async function histogramEqualization(inputImage) {
const squeeze11 = inputImage.shape.length === 4 ? tf.squeeze(inputImage) : inputImage; const squeeze10 = inputImage.shape.length === 4 ? tf.squeeze(inputImage) : inputImage;
const channels = tf.split(squeeze11, 3, 2); const channels = tf.split(squeeze10, 3, 2);
const min2 = [tf.min(channels[0]), tf.min(channels[1]), tf.min(channels[2])]; const min2 = [tf.min(channels[0]), tf.min(channels[1]), tf.min(channels[2])];
const max4 = [tf.max(channels[0]), tf.max(channels[1]), tf.max(channels[2])]; const max4 = [tf.max(channels[0]), tf.max(channels[1]), tf.max(channels[2])];
const absMax = await Promise.all(max4.map((channel) => channel.data())); const absMax = await Promise.all(max4.map((channel) => channel.data()));
@ -992,8 +992,8 @@ async function histogramEqualization(inputImage) {
const fact = [tf.div(maxValue, range[0]), tf.div(maxValue, range[1]), tf.div(maxValue, range[2])]; const fact = [tf.div(maxValue, range[0]), tf.div(maxValue, range[1]), tf.div(maxValue, range[2])];
const enh = [tf.mul(sub10[0], fact[0]), tf.mul(sub10[1], fact[1]), tf.mul(sub10[2], fact[2])]; const enh = [tf.mul(sub10[0], fact[0]), tf.mul(sub10[1], fact[1]), tf.mul(sub10[2], fact[2])];
const rgb2 = tf.stack([enh[0], enh[1], enh[2]], 2); const rgb2 = tf.stack([enh[0], enh[1], enh[2]], 2);
const reshape8 = tf.reshape(rgb2, [1, squeeze11.shape[0], squeeze11.shape[1], 3]); const reshape8 = tf.reshape(rgb2, [1, squeeze10.shape[0], squeeze10.shape[1], 3]);
tf.dispose([...channels, ...min2, ...max4, ...sub10, ...range, ...fact, ...enh, rgb2, squeeze11]); tf.dispose([...channels, ...min2, ...max4, ...sub10, ...range, ...fact, ...enh, rgb2, squeeze10]);
return reshape8; return reshape8;
} }
@ -1415,8 +1415,8 @@ async function predict(image29, config3, idx, count2) {
if (!(model == null ? void 0 : model.inputs[0].shape)) if (!(model == null ? void 0 : model.inputs[0].shape))
return; return;
const t = {}; const t = {};
const box4 = [[0, 0.1, 0.9, 0.9]]; const box5 = [[0, 0.1, 0.9, 0.9]];
t.resize = tf4.image.cropAndResize(image29, box4, [0], [model.inputs[0].shape[2], model.inputs[0].shape[1]]); t.resize = tf4.image.cropAndResize(image29, box5, [0], [model.inputs[0].shape[2], model.inputs[0].shape[1]]);
const obj = { age: 0, gender: "unknown", genderScore: 0, race: [] }; const obj = { age: 0, gender: "unknown", genderScore: 0, race: [] };
if ((_a2 = config3.face["gear"]) == null ? void 0 : _a2.enabled) if ((_a2 = config3.face["gear"]) == null ? void 0 : _a2.enabled)
[t.age, t.gender, t.race] = model.execute(t.resize, ["age_output", "gender_output", "race_output"]); [t.age, t.gender, t.race] = model.execute(t.resize, ["age_output", "gender_output", "race_output"]);
@ -4912,44 +4912,44 @@ var UV33 = VTX33.map((x) => UV468[x]);
var UV7 = VTX7.map((x) => UV468[x]); var UV7 = VTX7.map((x) => UV468[x]);
// src/face/facemeshutil.ts // src/face/facemeshutil.ts
var getBoxSize = (box4) => [Math.abs(box4.endPoint[0] - box4.startPoint[0]), Math.abs(box4.endPoint[1] - box4.startPoint[1])]; var getBoxSize = (box5) => [Math.abs(box5.endPoint[0] - box5.startPoint[0]), Math.abs(box5.endPoint[1] - box5.startPoint[1])];
var getBoxCenter = (box4) => [box4.startPoint[0] + (box4.endPoint[0] - box4.startPoint[0]) / 2, box4.startPoint[1] + (box4.endPoint[1] - box4.startPoint[1]) / 2]; var getBoxCenter = (box5) => [box5.startPoint[0] + (box5.endPoint[0] - box5.startPoint[0]) / 2, box5.startPoint[1] + (box5.endPoint[1] - box5.startPoint[1]) / 2];
var getClampedBox = (box4, input) => box4 ? [ var getClampedBox = (box5, input) => box5 ? [
Math.trunc(Math.max(0, box4.startPoint[0])), Math.trunc(Math.max(0, box5.startPoint[0])),
Math.trunc(Math.max(0, box4.startPoint[1])), Math.trunc(Math.max(0, box5.startPoint[1])),
Math.trunc(Math.min(input.shape[2] || 0, box4.endPoint[0]) - Math.max(0, box4.startPoint[0])), Math.trunc(Math.min(input.shape[2] || 0, box5.endPoint[0]) - Math.max(0, box5.startPoint[0])),
Math.trunc(Math.min(input.shape[1] || 0, box4.endPoint[1]) - Math.max(0, box4.startPoint[1])) Math.trunc(Math.min(input.shape[1] || 0, box5.endPoint[1]) - Math.max(0, box5.startPoint[1]))
] : [0, 0, 0, 0]; ] : [0, 0, 0, 0];
var getRawBox = (box4, input) => box4 ? [ var getRawBox = (box5, input) => box5 ? [
box4.startPoint[0] / (input.shape[2] || 0), box5.startPoint[0] / (input.shape[2] || 0),
box4.startPoint[1] / (input.shape[1] || 0), box5.startPoint[1] / (input.shape[1] || 0),
(box4.endPoint[0] - box4.startPoint[0]) / (input.shape[2] || 0), (box5.endPoint[0] - box5.startPoint[0]) / (input.shape[2] || 0),
(box4.endPoint[1] - box4.startPoint[1]) / (input.shape[1] || 0) (box5.endPoint[1] - box5.startPoint[1]) / (input.shape[1] || 0)
] : [0, 0, 0, 0]; ] : [0, 0, 0, 0];
var scaleBoxCoordinates = (box4, factor) => { var scaleBoxCoordinates = (box5, factor) => {
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]]; const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]]; const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
return { startPoint, endPoint, landmarks: box4.landmarks, confidence: box4.confidence }; return { startPoint, endPoint, landmarks: box5.landmarks, confidence: box5.confidence };
}; };
var cutBoxFromImageAndResize = (box4, image29, cropSize) => { var cutBoxFromImageAndResize = (box5, image29, cropSize) => {
const h = image29.shape[1]; const h = image29.shape[1];
const w = image29.shape[2]; const w = image29.shape[2];
const crop2 = tf9.image.cropAndResize(image29, [[box4.startPoint[1] / h, box4.startPoint[0] / w, box4.endPoint[1] / h, box4.endPoint[0] / w]], [0], cropSize); const crop2 = tf9.image.cropAndResize(image29, [[box5.startPoint[1] / h, box5.startPoint[0] / w, box5.endPoint[1] / h, box5.endPoint[0] / w]], [0], cropSize);
const norm = tf9.div(crop2, constants.tf255); const norm = tf9.div(crop2, constants.tf255);
tf9.dispose(crop2); tf9.dispose(crop2);
return norm; return norm;
}; };
var enlargeBox = (box4, factor) => { var enlargeBox = (box5, factor) => {
const center = getBoxCenter(box4); const center = getBoxCenter(box5);
const size2 = getBoxSize(box4); const size2 = getBoxSize(box5);
const halfSize = [factor * size2[0] / 2, factor * size2[1] / 2]; const halfSize = [factor * size2[0] / 2, factor * size2[1] / 2];
return { startPoint: [center[0] - halfSize[0], center[1] - halfSize[1]], endPoint: [center[0] + halfSize[0], center[1] + halfSize[1]], landmarks: box4.landmarks, confidence: box4.confidence }; return { startPoint: [center[0] - halfSize[0], center[1] - halfSize[1]], endPoint: [center[0] + halfSize[0], center[1] + halfSize[1]], landmarks: box5.landmarks, confidence: box5.confidence };
}; };
var squarifyBox = (box4) => { var squarifyBox = (box5) => {
const centers = getBoxCenter(box4); const centers = getBoxCenter(box5);
const size2 = getBoxSize(box4); const size2 = getBoxSize(box5);
const halfSize = Math.max(...size2) / 2; const halfSize = Math.max(...size2) / 2;
return { startPoint: [Math.round(centers[0] - halfSize), Math.round(centers[1] - halfSize)], endPoint: [Math.round(centers[0] + halfSize), Math.round(centers[1] + halfSize)], landmarks: box4.landmarks, confidence: box4.confidence }; return { startPoint: [Math.round(centers[0] - halfSize), Math.round(centers[1] - halfSize)], endPoint: [Math.round(centers[0] + halfSize), Math.round(centers[1] + halfSize)], landmarks: box5.landmarks, confidence: box5.confidence };
}; };
var calculateLandmarksBoundingBox = (landmarks) => { var calculateLandmarksBoundingBox = (landmarks) => {
const xs = landmarks.map((d) => d[0]); const xs = landmarks.map((d) => d[0]);
@ -5017,8 +5017,8 @@ function generateAnchors(inputSize9) {
} }
return anchors4; return anchors4;
} }
function transformRawCoords(coordsRaw, box4, angle, rotationMatrix, inputSize9) { function transformRawCoords(coordsRaw, box5, angle, rotationMatrix, inputSize9) {
const boxSize = getBoxSize(box4); const boxSize = getBoxSize(box5);
const coordsScaled = coordsRaw.map((coord) => [ const coordsScaled = coordsRaw.map((coord) => [
boxSize[0] / inputSize9 * (coord[0] - inputSize9 / 2), boxSize[0] / inputSize9 * (coord[0] - inputSize9 / 2),
boxSize[1] / inputSize9 * (coord[1] - inputSize9 / 2), boxSize[1] / inputSize9 * (coord[1] - inputSize9 / 2),
@ -5028,33 +5028,33 @@ function transformRawCoords(coordsRaw, box4, angle, rotationMatrix, inputSize9)
const coordsRotationMatrix = largeAngle ? buildRotationMatrix(angle, [0, 0]) : fixedRotationMatrix; const coordsRotationMatrix = largeAngle ? buildRotationMatrix(angle, [0, 0]) : fixedRotationMatrix;
const coordsRotated = largeAngle ? coordsScaled.map((coord) => [...rotatePoint(coord, coordsRotationMatrix), coord[2]]) : coordsScaled; const coordsRotated = largeAngle ? coordsScaled.map((coord) => [...rotatePoint(coord, coordsRotationMatrix), coord[2]]) : coordsScaled;
const inverseRotationMatrix = largeAngle ? invertTransformMatrix(rotationMatrix) : fixedRotationMatrix; const inverseRotationMatrix = largeAngle ? invertTransformMatrix(rotationMatrix) : fixedRotationMatrix;
const boxCenter = [...getBoxCenter({ startPoint: box4.startPoint, endPoint: box4.endPoint }), 1]; const boxCenter = [...getBoxCenter({ startPoint: box5.startPoint, endPoint: box5.endPoint }), 1];
return coordsRotated.map((coord) => [ return coordsRotated.map((coord) => [
Math.round(coord[0] + dot(boxCenter, inverseRotationMatrix[0])), Math.round(coord[0] + dot(boxCenter, inverseRotationMatrix[0])),
Math.round(coord[1] + dot(boxCenter, inverseRotationMatrix[1])), Math.round(coord[1] + dot(boxCenter, inverseRotationMatrix[1])),
Math.round(coord[2] || 0) Math.round(coord[2] || 0)
]); ]);
} }
function correctFaceRotation(rotate, box4, input, inputSize9) { function correctFaceRotation(rotate, box5, input, inputSize9) {
const symmetryLine = box4.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine; const symmetryLine = box5.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine;
let angle = 0; let angle = 0;
let rotationMatrix = fixedRotationMatrix; let rotationMatrix = fixedRotationMatrix;
let face5; let face5;
if (rotate && env.kernels.includes("rotatewithoffset")) { if (rotate && env.kernels.includes("rotatewithoffset")) {
angle = computeRotation(box4.landmarks[symmetryLine[0]], box4.landmarks[symmetryLine[1]]); angle = computeRotation(box5.landmarks[symmetryLine[0]], box5.landmarks[symmetryLine[1]]);
const largeAngle = angle && angle !== 0 && Math.abs(angle) > 0.2; const largeAngle = angle && angle !== 0 && Math.abs(angle) > 0.2;
if (largeAngle) { if (largeAngle) {
const center = getBoxCenter({ startPoint: box4.startPoint, endPoint: box4.endPoint }); const center = getBoxCenter({ startPoint: box5.startPoint, endPoint: box5.endPoint });
const centerRaw = [center[0] / input.shape[2], center[1] / input.shape[1]]; const centerRaw = [center[0] / input.shape[2], center[1] / input.shape[1]];
const rotated = tf9.image.rotateWithOffset(input, angle, 0, centerRaw); const rotated = tf9.image.rotateWithOffset(input, angle, 0, centerRaw);
rotationMatrix = buildRotationMatrix(-angle, center); rotationMatrix = buildRotationMatrix(-angle, center);
face5 = cutBoxFromImageAndResize(box4, rotated, [inputSize9, inputSize9]); face5 = cutBoxFromImageAndResize(box5, rotated, [inputSize9, inputSize9]);
tf9.dispose(rotated); tf9.dispose(rotated);
} else { } else {
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]); face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
} }
} else { } else {
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]); face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
} }
return [angle, rotationMatrix, face5]; return [angle, rotationMatrix, face5];
} }
@ -5239,41 +5239,39 @@ async function createAnchors() {
} }
anchorTensor = { x: tf11.tensor1d(anchors4.map((a) => a.x)), y: tf11.tensor1d(anchors4.map((a) => a.y)) }; anchorTensor = { x: tf11.tensor1d(anchors4.map((a) => a.x)), y: tf11.tensor1d(anchors4.map((a) => a.y)) };
} }
var cropFactor = [5, 5];
function decodeBoxes(boxesTensor, anchor) { // src/util/box.ts
return tf11.tidy(() => { function calc(keypoints, outputSize2 = [1, 1]) {
const split5 = tf11.split(boxesTensor, 12, 1); const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
let xCenter = tf11.squeeze(split5[0]); const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
let yCenter = tf11.squeeze(split5[1]); const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
let width = tf11.squeeze(split5[2]); const box5 = [min2[0], min2[1], max4[0] - min2[0], max4[1] - min2[1]];
let height = tf11.squeeze(split5[3]); const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
xCenter = tf11.add(tf11.div(xCenter, inputSize2), anchor.x); return { box: box5, boxRaw };
yCenter = tf11.add(tf11.div(yCenter, inputSize2), anchor.y);
width = tf11.mul(tf11.div(width, inputSize2), cropFactor[0]);
height = tf11.mul(tf11.div(height, inputSize2), cropFactor[1]);
const xMin = tf11.sub(xCenter, tf11.div(width, 2));
const yMin = tf11.sub(yCenter, tf11.div(height, 2));
const boxes = tf11.stack([xMin, yMin, width, height], 1);
return boxes;
});
} }
async function decode(boxesTensor, logitsTensor, config3, outputSize2) { function square(keypoints, outputSize2 = [1, 1]) {
const t = {}; const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
t.boxes = decodeBoxes(boxesTensor, anchorTensor); const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
t.scores = tf11.sigmoid(logitsTensor); const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
t.argmax = tf11.argMax(t.scores); const center = [(min2[0] + max4[0]) / 2, (min2[1] + max4[1]) / 2];
const i = (await t.argmax.data())[0]; const dist = Math.max(center[0] - min2[0], center[1] - min2[1], -center[0] + max4[0], -center[1] + max4[1]);
const scores = await t.scores.data(); const box5 = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];
const detected = []; const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
const minScore = config3.body["detector"] && config3.body["detector"]["minConfidence"] ? config3.body["detector"]["minConfidence"] : 0; return { box: box5, boxRaw };
if (scores[i] >= minScore) { }
const boxes = await t.boxes.array(); function scale(box5, scaleFact) {
const boxRaw = boxes[i]; const dist = [box5[2] * scaleFact, box5[3] * scaleFact];
const box4 = [boxRaw[0] * outputSize2[0], boxRaw[1] * outputSize2[1], boxRaw[2] * outputSize2[0], boxRaw[3] * outputSize2[1]]; const newBox = [
detected.push({ box: box4, boxRaw, score: scores[i] }); box5[0] - (dist[0] - box5[2]) / 2,
} box5[1] - (dist[1] - box5[3]) / 2,
Object.keys(t).forEach((tensor3) => tf11.dispose(t[tensor3])); dist[0],
return detected; dist[1]
];
return newBox;
}
function crop(box5) {
const yxBox = [Math.max(0, box5[1]), Math.max(0, box5[0]), Math.min(1, box5[3] + box5[1]), Math.min(1, box5[2] + box5[0])];
return yxBox;
} }
// src/body/blazepose.ts // src/body/blazepose.ts
@ -5286,7 +5284,7 @@ var outputNodes = {
detector: [] detector: []
}; };
var cache = null; var cache = null;
var lastBox; var cropBox;
var padding = [[0, 0], [0, 0], [0, 0], [0, 0]]; var padding = [[0, 0], [0, 0], [0, 0], [0, 0]];
var lastTime5 = 0; var lastTime5 = 0;
var sigmoid3 = (x) => 1 - 1 / (1 + Math.exp(x)); var sigmoid3 = (x) => 1 - 1 / (1 + Math.exp(x));
@ -5323,39 +5321,37 @@ async function loadPose(config3) {
log("cached model:", models.landmarks["modelUrl"]); log("cached model:", models.landmarks["modelUrl"]);
return models.landmarks; return models.landmarks;
} }
function calculateBoxes(keypoints, outputSize2) { async function prepareImage(input, size2) {
const x = keypoints.map((a) => a.position[0]);
const y = keypoints.map((a) => a.position[1]);
const keypointsBox = [Math.min(...x), Math.min(...y), Math.max(...x) - Math.min(...x), Math.max(...y) - Math.min(...y)];
const keypointsBoxRaw = [keypointsBox[0] / outputSize2[0], keypointsBox[1] / outputSize2[1], keypointsBox[2] / outputSize2[0], keypointsBox[3] / outputSize2[1]];
return { keypointsBox, keypointsBoxRaw };
}
async function prepareImage(input, size2, box4) {
const t = {}; const t = {};
if (!input.shape || !input.shape[1] || !input.shape[2]) if (!input.shape || !input.shape[1] || !input.shape[2])
return input; return input;
let final; let final;
if (cropBox) {
t.cropped = tf12.image.cropAndResize(input, [cropBox], [0], [input.shape[1], input.shape[2]]);
}
if (input.shape[1] !== input.shape[2]) { if (input.shape[1] !== input.shape[2]) {
const height = box4 ? [Math.trunc(input.shape[1] * box4[1]), Math.trunc(input.shape[1] * (box4[1] + box4[3]))] : [input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0, input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0]; const height = [
const width = box4 ? [Math.trunc(input.shape[2] * box4[0]), Math.trunc(input.shape[2] * (box4[0] + box4[2]))] : [input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0, input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0]; input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0,
input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0
];
const width = [
input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0,
input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0
];
padding = [ padding = [
[0, 0], [0, 0],
height, height,
width, width,
[0, 0] [0, 0]
]; ];
if (box4) { t.pad = tf12.pad(t.cropped || input, padding);
t.resize = tf12.image.cropAndResize(input, [box4], [0], [size2, size2]); t.resize = tf12.image.resizeBilinear(t.pad, [size2, size2]);
} else {
t.pad = tf12.pad(input, padding);
t.resize = tf12.image.resizeBilinear(t.pad, [size2, size2]);
}
final = tf12.div(t.resize, constants.tf255); final = tf12.div(t.resize, constants.tf255);
} else if (input.shape[1] !== size2) { } else if (input.shape[1] !== size2) {
t.resize = tf12.image.resizeBilinear(input, [size2, size2]); t.resize = tf12.image.resizeBilinear(t.cropped || input, [size2, size2]);
final = tf12.div(t.resize, constants.tf255); final = tf12.div(t.resize, constants.tf255);
} else { } else {
final = tf12.div(input, constants.tf255); final = tf12.div(t.cropped || input, constants.tf255);
} }
Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3])); Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3]));
return final; return final;
@ -5369,19 +5365,21 @@ function rescaleKeypoints(keypoints, outputSize2) {
]; ];
kpt4.positionRaw = [kpt4.position[0] / outputSize2[0], kpt4.position[1] / outputSize2[1], kpt4.position[2]]; kpt4.positionRaw = [kpt4.position[0] / outputSize2[0], kpt4.position[1] / outputSize2[1], kpt4.position[2]];
} }
return keypoints; if (cropBox) {
} for (const kpt4 of keypoints) {
function rescaleBoxes(boxes, outputSize2) { kpt4.positionRaw = [
for (const box4 of boxes) { kpt4.positionRaw[0] + cropBox[1],
box4.box = [ kpt4.positionRaw[1] + cropBox[0],
Math.trunc(box4.box[0] * (outputSize2[0] + padding[2][0] + padding[2][1]) / outputSize2[0]), kpt4.positionRaw[2]
Math.trunc(box4.box[1] * (outputSize2[1] + padding[1][0] + padding[1][1]) / outputSize2[1]), ];
Math.trunc(box4.box[2] * (outputSize2[0] + padding[2][0] + padding[2][1]) / outputSize2[0]), kpt4.position = [
Math.trunc(box4.box[3] * (outputSize2[1] + padding[1][0] + padding[1][1]) / outputSize2[1]) Math.trunc(kpt4.positionRaw[0] * outputSize2[0]),
]; Math.trunc(kpt4.positionRaw[1] * outputSize2[1]),
box4.boxRaw = [box4.box[0] / outputSize2[0], box4.box[1] / outputSize2[1], box4.box[2] / outputSize2[0], box4.box[3] / outputSize2[1]]; kpt4.positionRaw[2]
];
}
} }
return boxes; return keypoints;
} }
async function detectLandmarks(input, config3, outputSize2) { async function detectLandmarks(input, config3, outputSize2) {
var _a; var _a;
@ -5403,7 +5401,8 @@ async function detectLandmarks(input, config3, outputSize2) {
if (poseScore < (config3.body.minConfidence || 0)) if (poseScore < (config3.body.minConfidence || 0))
return null; return null;
const keypoints = rescaleKeypoints(keypointsRelative, outputSize2); const keypoints = rescaleKeypoints(keypointsRelative, outputSize2);
const boxes = calculateBoxes(keypoints, [outputSize2[0], outputSize2[1]]); const kpts = keypoints.map((k) => k.position);
const boxes = calc(kpts, [outputSize2[0], outputSize2[1]]);
const annotations2 = {}; const annotations2 = {};
for (const [name, indexes] of Object.entries(connected)) { for (const [name, indexes] of Object.entries(connected)) {
const pt = []; const pt = [];
@ -5415,22 +5414,9 @@ async function detectLandmarks(input, config3, outputSize2) {
} }
annotations2[name] = pt; annotations2[name] = pt;
} }
const body4 = { id: 0, score: Math.trunc(100 * poseScore) / 100, box: boxes.keypointsBox, boxRaw: boxes.keypointsBoxRaw, keypoints, annotations: annotations2 }; const body4 = { id: 0, score: Math.trunc(100 * poseScore) / 100, box: boxes.box, boxRaw: boxes.boxRaw, keypoints, annotations: annotations2 };
return body4; return body4;
} }
async function detectBoxes(input, config3, outputSize2) {
var _a;
const t = {};
t.res = (_a = models.detector) == null ? void 0 : _a.execute(input, ["Identity"]);
t.logitsRaw = tf12.slice(t.res, [0, 0, 0], [1, -1, 1]);
t.boxesRaw = tf12.slice(t.res, [0, 0, 1], [1, -1, -1]);
t.logits = tf12.squeeze(t.logitsRaw);
t.boxes = tf12.squeeze(t.boxesRaw);
const boxes = await decode(t.boxes, t.logits, config3, outputSize2);
rescaleBoxes(boxes, outputSize2);
Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3]));
return boxes;
}
async function predict5(input, config3) { async function predict5(input, config3) {
const outputSize2 = [input.shape[2] || 0, input.shape[1] || 0]; const outputSize2 = [input.shape[2] || 0, input.shape[1] || 0];
const skipTime = (config3.body.skipTime || 0) > now() - lastTime5; const skipTime = (config3.body.skipTime || 0) > now() - lastTime5;
@ -5439,26 +5425,13 @@ async function predict5(input, config3) {
skipped5++; skipped5++;
} else { } else {
const t = {}; const t = {};
if (config3.body["detector"] && config3.body["detector"]["enabled"]) { t.landmarks = await prepareImage(input, 256);
t.detector = await prepareImage(input, 224); cache = await detectLandmarks(t.landmarks, config3, outputSize2);
const boxes = await detectBoxes(t.detector, config3, outputSize2);
if (boxes && boxes.length === 1) {
t.landmarks = await prepareImage(input, 256, boxes[0].box);
cache = await detectLandmarks(t.landmarks, config3, outputSize2);
}
if (cache)
cache.score = boxes[0].score;
} else {
t.landmarks = await prepareImage(input, 256, lastBox);
cache = await detectLandmarks(t.landmarks, config3, outputSize2);
}
Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3])); Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3]));
lastTime5 = now(); lastTime5 = now();
skipped5 = 0; skipped5 = 0;
} }
if (cache) return cache ? [cache] : [];
return [cache];
return [];
} }
// src/object/centernet.ts // src/object/centernet.ts
@ -5599,13 +5572,13 @@ async function process3(res, outputShape, config3) {
detections[0][id][2] / inputSize4 - x, detections[0][id][2] / inputSize4 - x,
detections[0][id][3] / inputSize4 - y detections[0][id][3] / inputSize4 - y
]; ];
const box4 = [ const box5 = [
Math.trunc(boxRaw[0] * outputShape[0]), Math.trunc(boxRaw[0] * outputShape[0]),
Math.trunc(boxRaw[1] * outputShape[1]), Math.trunc(boxRaw[1] * outputShape[1]),
Math.trunc(boxRaw[2] * outputShape[0]), Math.trunc(boxRaw[2] * outputShape[0]),
Math.trunc(boxRaw[3] * outputShape[1]) Math.trunc(boxRaw[3] * outputShape[1])
]; ];
results.push({ id: i++, score, class: classVal, label, box: box4, boxRaw }); results.push({ id: i++, score, class: classVal, label, box: box5, boxRaw });
} }
Object.keys(t).forEach((tensor3) => tf13.dispose(t[tensor3])); Object.keys(t).forEach((tensor3) => tf13.dispose(t[tensor3]));
return results; return results;
@ -5726,10 +5699,10 @@ async function predict7(image29, config3) {
tf14.dispose(tensor3); tf14.dispose(tensor3);
if (resT) { if (resT) {
cache2.keypoints.length = 0; cache2.keypoints.length = 0;
const squeeze11 = resT.squeeze(); const squeeze10 = resT.squeeze();
tf14.dispose(resT); tf14.dispose(resT);
const stack5 = squeeze11.unstack(2); const stack5 = squeeze10.unstack(2);
tf14.dispose(squeeze11); tf14.dispose(squeeze10);
for (let id = 0; id < stack5.length; id++) { for (let id = 0; id < stack5.length; id++) {
const [x2, y2, partScore] = await max2d(stack5[id], config3.body.minConfidence); const [x2, y2, partScore] = await max2d(stack5[id], config3.body.minConfidence);
if (partScore > (((_a = config3.body) == null ? void 0 : _a.minConfidence) || 0)) { if (partScore > (((_a = config3.body) == null ? void 0 : _a.minConfidence) || 0)) {
@ -5947,20 +5920,20 @@ var getLeftToRightEyeDepthDifference = (rawCoords) => {
return leftEyeZ - rightEyeZ; return leftEyeZ - rightEyeZ;
}; };
var getEyeBox = (rawCoords, face5, eyeInnerCornerIndex, eyeOuterCornerIndex, meshSize, flip = false) => { var getEyeBox = (rawCoords, face5, eyeInnerCornerIndex, eyeOuterCornerIndex, meshSize, flip = false) => {
const box4 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge)); const box5 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge));
const boxSize = getBoxSize(box4); const boxSize = getBoxSize(box5);
let crop2 = tf17.image.cropAndResize(face5, [[ let crop2 = tf17.image.cropAndResize(face5, [[
box4.startPoint[1] / meshSize, box5.startPoint[1] / meshSize,
box4.startPoint[0] / meshSize, box5.startPoint[0] / meshSize,
box4.endPoint[1] / meshSize, box5.endPoint[1] / meshSize,
box4.endPoint[0] / meshSize box5.endPoint[0] / meshSize
]], [0], [inputSize5, inputSize5]); ]], [0], [inputSize5, inputSize5]);
if (flip && env.kernels.includes("flipleftright")) { if (flip && env.kernels.includes("flipleftright")) {
const flipped = tf17.image.flipLeftRight(crop2); const flipped = tf17.image.flipLeftRight(crop2);
tf17.dispose(crop2); tf17.dispose(crop2);
crop2 = flipped; crop2 = flipped;
} }
return { box: box4, boxSize, crop: crop2 }; return { box: box5, boxSize, crop: crop2 };
}; };
var getEyeCoords = (eyeData, eyeBox, eyeBoxSize, flip = false) => { var getEyeCoords = (eyeData, eyeBox, eyeBoxSize, flip = false) => {
const eyeRawCoords = []; const eyeRawCoords = [];
@ -6054,7 +6027,7 @@ async function predict10(input, config3) {
const newCache = []; const newCache = [];
let id = 0; let id = 0;
for (let i = 0; i < boxCache.length; i++) { for (let i = 0; i < boxCache.length; i++) {
let box4 = boxCache[i]; let box5 = boxCache[i];
let angle = 0; let angle = 0;
let rotationMatrix; let rotationMatrix;
const face5 = { const face5 = {
@ -6068,20 +6041,20 @@ async function predict10(input, config3) {
faceScore: 0, faceScore: 0,
annotations: {} annotations: {}
}; };
[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) ? inputSize6 : size()); [angle, rotationMatrix, face5.tensor] = correctFaceRotation((_d = config3.face.detector) == null ? void 0 : _d.rotation, box5, input, ((_e = config3.face.mesh) == null ? void 0 : _e.enabled) ? inputSize6 : size());
if ((_f = config3 == null ? void 0 : config3.filter) == null ? void 0 : _f.equalization) { if ((_f = config3 == null ? void 0 : config3.filter) == null ? void 0 : _f.equalization) {
const equilized = await histogramEqualization(face5.tensor); const equilized = await histogramEqualization(face5.tensor);
tf18.dispose(face5.tensor); tf18.dispose(face5.tensor);
face5.tensor = equilized; face5.tensor = equilized;
} }
face5.boxScore = Math.round(100 * box4.confidence) / 100; face5.boxScore = Math.round(100 * box5.confidence) / 100;
if (!((_g = config3.face.mesh) == null ? void 0 : _g.enabled)) { if (!((_g = config3.face.mesh) == null ? void 0 : _g.enabled)) {
face5.box = getClampedBox(box4, input); face5.box = getClampedBox(box5, input);
face5.boxRaw = getRawBox(box4, input); face5.boxRaw = getRawBox(box5, input);
face5.score = face5.boxScore; face5.score = face5.boxScore;
face5.mesh = box4.landmarks.map((pt) => [ face5.mesh = box5.landmarks.map((pt) => [
(box4.startPoint[0] + box4.endPoint[0]) / 2 + (box4.endPoint[0] + box4.startPoint[0]) * pt[0] / size(), (box5.startPoint[0] + box5.endPoint[0]) / 2 + (box5.endPoint[0] + box5.startPoint[0]) * pt[0] / size(),
(box4.startPoint[1] + box4.endPoint[1]) / 2 + (box4.endPoint[1] + box4.startPoint[1]) * pt[1] / size() (box5.startPoint[1] + box5.endPoint[1]) / 2 + (box5.endPoint[1] + box5.startPoint[1]) * pt[1] / size()
]); ]);
face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]); face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]);
for (const key of Object.keys(blazeFaceLandmarks)) for (const key of Object.keys(blazeFaceLandmarks))
@ -6097,24 +6070,24 @@ async function predict10(input, config3) {
let rawCoords = await coordsReshaped.array(); let rawCoords = await coordsReshaped.array();
tf18.dispose([contourCoords, coordsReshaped, confidence, contours]); tf18.dispose([contourCoords, coordsReshaped, confidence, contours]);
if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) { if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
box4.confidence = face5.faceScore; box5.confidence = face5.faceScore;
} else { } else {
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled) if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize6); rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize6);
face5.mesh = transformRawCoords(rawCoords, box4, angle, rotationMatrix, inputSize6); face5.mesh = transformRawCoords(rawCoords, box5, angle, rotationMatrix, inputSize6);
face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]); face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]);
for (const key of Object.keys(meshAnnotations)) for (const key of Object.keys(meshAnnotations))
face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]); face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]);
const boxCalculated = calculateLandmarksBoundingBox(face5.mesh); const boxCalculated = calculateLandmarksBoundingBox(face5.mesh);
const boxEnlarged = enlargeBox(boxCalculated, ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6); const boxEnlarged = enlargeBox(boxCalculated, ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6);
const boxSquared = squarifyBox(boxEnlarged); const boxSquared = squarifyBox(boxEnlarged);
box4 = { ...boxSquared, confidence: box4.confidence }; box5 = { ...boxSquared, confidence: box5.confidence };
face5.box = getClampedBox(box4, input); face5.box = getClampedBox(box5, input);
face5.boxRaw = getRawBox(box4, input); face5.boxRaw = getRawBox(box5, input);
face5.score = face5.faceScore; face5.score = face5.faceScore;
newCache.push(box4); newCache.push(box5);
tf18.dispose(face5.tensor); tf18.dispose(face5.tensor);
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_k = config3.face.detector) == null ? void 0 : _k.rotation, box4, input, inputSize6); [angle, rotationMatrix, face5.tensor] = correctFaceRotation((_k = config3.face.detector) == null ? void 0 : _k.rotation, box5, input, inputSize6);
} }
} }
faces.push(face5); faces.push(face5);
@ -6227,54 +6200,54 @@ var tf21 = __toModule(require_tfjs_esm());
// src/hand/handposeutil.ts // src/hand/handposeutil.ts
var tf20 = __toModule(require_tfjs_esm()); var tf20 = __toModule(require_tfjs_esm());
function getBoxSize2(box4) { function getBoxSize2(box5) {
return [ return [
Math.abs(box4.endPoint[0] - box4.startPoint[0]), Math.abs(box5.endPoint[0] - box5.startPoint[0]),
Math.abs(box4.endPoint[1] - box4.startPoint[1]) Math.abs(box5.endPoint[1] - box5.startPoint[1])
]; ];
} }
function getBoxCenter2(box4) { function getBoxCenter2(box5) {
return [ return [
box4.startPoint[0] + (box4.endPoint[0] - box4.startPoint[0]) / 2, box5.startPoint[0] + (box5.endPoint[0] - box5.startPoint[0]) / 2,
box4.startPoint[1] + (box4.endPoint[1] - box4.startPoint[1]) / 2 box5.startPoint[1] + (box5.endPoint[1] - box5.startPoint[1]) / 2
]; ];
} }
function cutBoxFromImageAndResize2(box4, image29, cropSize) { function cutBoxFromImageAndResize2(box5, image29, cropSize) {
const h = image29.shape[1]; const h = image29.shape[1];
const w = image29.shape[2]; const w = image29.shape[2];
const boxes = [[ const boxes = [[
box4.startPoint[1] / h, box5.startPoint[1] / h,
box4.startPoint[0] / w, box5.startPoint[0] / w,
box4.endPoint[1] / h, box5.endPoint[1] / h,
box4.endPoint[0] / w box5.endPoint[0] / w
]]; ]];
return tf20.image.cropAndResize(image29, boxes, [0], cropSize); return tf20.image.cropAndResize(image29, boxes, [0], cropSize);
} }
function scaleBoxCoordinates2(box4, factor) { function scaleBoxCoordinates2(box5, factor) {
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]]; const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]]; const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
const palmLandmarks = box4.palmLandmarks.map((coord) => { const palmLandmarks = box5.palmLandmarks.map((coord) => {
const scaledCoord = [coord[0] * factor[0], coord[1] * factor[1]]; const scaledCoord = [coord[0] * factor[0], coord[1] * factor[1]];
return scaledCoord; return scaledCoord;
}); });
return { startPoint, endPoint, palmLandmarks, confidence: box4.confidence }; return { startPoint, endPoint, palmLandmarks, confidence: box5.confidence };
} }
function enlargeBox2(box4, factor = 1.5) { function enlargeBox2(box5, factor = 1.5) {
const center = getBoxCenter2(box4); const center = getBoxCenter2(box5);
const size2 = getBoxSize2(box4); const size2 = getBoxSize2(box5);
const newHalfSize = [factor * size2[0] / 2, factor * size2[1] / 2]; const newHalfSize = [factor * size2[0] / 2, factor * size2[1] / 2];
const startPoint = [center[0] - newHalfSize[0], center[1] - newHalfSize[1]]; const startPoint = [center[0] - newHalfSize[0], center[1] - newHalfSize[1]];
const endPoint = [center[0] + newHalfSize[0], center[1] + newHalfSize[1]]; const endPoint = [center[0] + newHalfSize[0], center[1] + newHalfSize[1]];
return { startPoint, endPoint, palmLandmarks: box4.palmLandmarks }; return { startPoint, endPoint, palmLandmarks: box5.palmLandmarks };
} }
function squarifyBox2(box4) { function squarifyBox2(box5) {
const centers = getBoxCenter2(box4); const centers = getBoxCenter2(box5);
const size2 = getBoxSize2(box4); const size2 = getBoxSize2(box5);
const maxEdge = Math.max(...size2); const maxEdge = Math.max(...size2);
const halfSize = maxEdge / 2; const halfSize = maxEdge / 2;
const startPoint = [centers[0] - halfSize, centers[1] - halfSize]; const startPoint = [centers[0] - halfSize, centers[1] - halfSize];
const endPoint = [centers[0] + halfSize, centers[1] + halfSize]; const endPoint = [centers[0] + halfSize, centers[1] + halfSize];
return { startPoint, endPoint, palmLandmarks: box4.palmLandmarks }; return { startPoint, endPoint, palmLandmarks: box5.palmLandmarks };
} }
function normalizeRadians2(angle) { function normalizeRadians2(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));
@ -9348,9 +9321,9 @@ var HandDetector = class {
p.slice = tf21.slice(t.predictions, [index2, 5], [1, 14]); p.slice = tf21.slice(t.predictions, [index2, 5], [1, 14]);
p.norm = this.normalizeLandmarks(p.slice, index2); p.norm = this.normalizeLandmarks(p.slice, index2);
p.palmLandmarks = tf21.reshape(p.norm, [-1, 2]); p.palmLandmarks = tf21.reshape(p.norm, [-1, 2]);
const box4 = await p.box.data(); const box5 = await p.box.data();
const startPoint = box4.slice(0, 2); const startPoint = box5.slice(0, 2);
const endPoint = box4.slice(2, 4); const endPoint = box5.slice(2, 4);
const palmLandmarks = await p.palmLandmarks.array(); const palmLandmarks = await p.palmLandmarks.array();
const hand3 = { startPoint, endPoint, palmLandmarks, confidence: scores[index2] }; const hand3 = { startPoint, endPoint, palmLandmarks, confidence: scores[index2] };
const scaled = scaleBoxCoordinates2(hand3, [input.shape[2] / this.inputSize, input.shape[1] / this.inputSize]); const scaled = scaleBoxCoordinates2(hand3, [input.shape[2] / this.inputSize, input.shape[1] / this.inputSize]);
@ -9937,24 +9910,24 @@ async function predict12(input, config3) {
} }
} }
const keypoints = predictions[i].landmarks; const keypoints = predictions[i].landmarks;
let box4 = [Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, 0, 0]; let box5 = [Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, 0, 0];
let boxRaw = [0, 0, 0, 0]; let boxRaw = [0, 0, 0, 0];
if (keypoints && keypoints.length > 0) { if (keypoints && keypoints.length > 0) {
for (const pt of keypoints) { for (const pt of keypoints) {
if (pt[0] < box4[0]) if (pt[0] < box5[0])
box4[0] = pt[0]; box5[0] = pt[0];
if (pt[1] < box4[1]) if (pt[1] < box5[1])
box4[1] = pt[1]; box5[1] = pt[1];
if (pt[0] > box4[2]) if (pt[0] > box5[2])
box4[2] = pt[0]; box5[2] = pt[0];
if (pt[1] > box4[3]) if (pt[1] > box5[3])
box4[3] = pt[1]; box5[3] = pt[1];
} }
box4[2] -= box4[0]; box5[2] -= box5[0];
box4[3] -= box4[1]; box5[3] -= box5[1];
boxRaw = [box4[0] / (input.shape[2] || 0), box4[1] / (input.shape[1] || 0), box4[2] / (input.shape[2] || 0), box4[3] / (input.shape[1] || 0)]; boxRaw = [box5[0] / (input.shape[2] || 0), box5[1] / (input.shape[1] || 0), box5[2] / (input.shape[2] || 0), box5[3] / (input.shape[1] || 0)];
} else { } else {
box4 = predictions[i].box ? [ box5 = predictions[i].box ? [
Math.trunc(Math.max(0, predictions[i].box.topLeft[0])), Math.trunc(Math.max(0, predictions[i].box.topLeft[0])),
Math.trunc(Math.max(0, predictions[i].box.topLeft[1])), Math.trunc(Math.max(0, predictions[i].box.topLeft[1])),
Math.trunc(Math.min(input.shape[2] || 0, predictions[i].box.bottomRight[0]) - Math.max(0, predictions[i].box.topLeft[0])), Math.trunc(Math.min(input.shape[2] || 0, predictions[i].box.bottomRight[0]) - Math.max(0, predictions[i].box.topLeft[0])),
@ -9974,7 +9947,7 @@ async function predict12(input, config3) {
boxScore: Math.round(100 * predictions[i].boxConfidence) / 100, boxScore: Math.round(100 * predictions[i].boxConfidence) / 100,
fingerScore: Math.round(100 * predictions[i].fingerConfidence) / 100, fingerScore: Math.round(100 * predictions[i].fingerConfidence) / 100,
label: "hand", label: "hand",
box: box4, box: box5,
boxRaw, boxRaw,
keypoints, keypoints,
annotations: annotations2, annotations: annotations2,
@ -10015,40 +9988,6 @@ async function load13(config3) {
return [handDetectorModel, handPoseModel]; return [handDetectorModel, handPoseModel];
} }
// src/util/box.ts
function calc(keypoints, outputSize2 = [1, 1]) {
const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
const box4 = [min2[0], min2[1], max4[0] - min2[0], max4[1] - min2[1]];
const boxRaw = [box4[0] / outputSize2[0], box4[1] / outputSize2[1], box4[2] / outputSize2[0], box4[3] / outputSize2[1]];
return { box: box4, boxRaw };
}
function square(keypoints, outputSize2 = [1, 1]) {
const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
const center = [(min2[0] + max4[0]) / 2, (min2[1] + max4[1]) / 2];
const dist = Math.max(center[0] - min2[0], center[1] - min2[1], -center[0] + max4[0], -center[1] + max4[1]);
const box4 = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];
const boxRaw = [box4[0] / outputSize2[0], box4[1] / outputSize2[1], box4[2] / outputSize2[0], box4[3] / outputSize2[1]];
return { box: box4, boxRaw };
}
function scale(box4, scaleFact) {
const dist = [box4[2] * scaleFact, box4[3] * scaleFact];
const newBox = [
box4[0] - (dist[0] - box4[2]) / 2,
box4[1] - (dist[1] - box4[3]) / 2,
dist[0],
dist[1]
];
return newBox;
}
function crop(box4) {
const yxBox = [Math.max(0, box4[1]), Math.max(0, box4[0]), Math.min(1, box4[3] + box4[1]), Math.min(1, box4[2] + box4[0])];
return yxBox;
}
// src/hand/handtrack.ts // src/hand/handtrack.ts
var tf24 = __toModule(require_tfjs_esm()); var tf24 = __toModule(require_tfjs_esm());
var models2 = [null, null]; var models2 = [null, null];
@ -10067,11 +10006,11 @@ var cache3 = {
hands: [] hands: []
}; };
var fingerMap = { var fingerMap = {
thumb: [1, 2, 3, 4], thumb: [0, 1, 2, 3, 4],
index: [5, 6, 7, 8], index: [0, 5, 6, 7, 8],
middle: [9, 10, 11, 12], middle: [0, 9, 10, 11, 12],
ring: [13, 14, 15, 16], ring: [0, 13, 14, 15, 16],
pinky: [17, 18, 19, 20], pinky: [0, 17, 18, 19, 20],
palm: [0] palm: [0]
}; };
async function loadDetect2(config3) { async function loadDetect2(config3) {
@ -10622,7 +10561,7 @@ async function process4(res, inputSize9, outputShape, config3) {
]; ];
let boxRaw = [x, y, w, h]; let boxRaw = [x, y, w, h];
boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1))); boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1)));
const box4 = [ const box5 = [
boxRaw[0] * outputShape[0], boxRaw[0] * outputShape[0],
boxRaw[1] * outputShape[1], boxRaw[1] * outputShape[1],
boxRaw[2] * outputShape[0], boxRaw[2] * outputShape[0],
@ -10633,7 +10572,7 @@ async function process4(res, inputSize9, outputShape, config3) {
score: Math.round(100 * score) / 100, score: Math.round(100 * score) / 100,
class: j + 1, class: j + 1,
label: labels[j].label, label: labels[j].label,
box: box4.map((a) => Math.trunc(a)), box: box5.map((a) => Math.trunc(a)),
boxRaw boxRaw
}; };
results.push(result); results.push(result);
@ -10976,7 +10915,7 @@ function getInstanceScore(existingPoses, keypoints) {
}, 0); }, 0);
return notOverlappedKeypointScores / keypoints.length; return notOverlappedKeypointScores / keypoints.length;
} }
function decode2(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) { function decode(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) {
const poses = []; const poses = [];
const queue = buildPartWithScoreQueue(minConfidence2, scores); const queue = buildPartWithScoreQueue(minConfidence2, scores);
while (poses.length < maxDetected && !queue.empty()) { while (poses.length < maxDetected && !queue.empty()) {
@ -10987,9 +10926,9 @@ function decode2(offsets, scores, displacementsFwd, displacementsBwd, maxDetecte
let keypoints = decodePose(root, scores, offsets, displacementsFwd, displacementsBwd); let keypoints = decodePose(root, scores, offsets, displacementsFwd, displacementsBwd);
keypoints = keypoints.filter((a) => a.score > minConfidence2); keypoints = keypoints.filter((a) => a.score > minConfidence2);
const score = getInstanceScore(poses, keypoints); const score = getInstanceScore(poses, keypoints);
const box4 = getBoundingBox(keypoints); const box5 = getBoundingBox(keypoints);
if (score > minConfidence2) if (score > minConfidence2)
poses.push({ keypoints, box: box4, score: Math.round(100 * score) / 100 }); poses.push({ keypoints, box: box5, score: Math.round(100 * score) / 100 });
} }
return poses; return poses;
} }
@ -11007,7 +10946,7 @@ async function predict17(input, config3) {
const buffers = await Promise.all(res.map((tensor3) => tensor3.buffer())); const buffers = await Promise.all(res.map((tensor3) => tensor3.buffer()));
for (const t of res) for (const t of res)
tf29.dispose(t); tf29.dispose(t);
const decoded = await decode2(buffers[0], buffers[1], buffers[2], buffers[3], config3.body.maxDetected, config3.body.minConfidence); const decoded = await decode(buffers[0], buffers[1], buffers[2], buffers[3], config3.body.maxDetected, config3.body.minConfidence);
if (!model16.inputs[0].shape) if (!model16.inputs[0].shape)
return []; return [];
const scaled = scalePoses(decoded, [input.shape[1], input.shape[2]], [model16.inputs[0].shape[2], model16.inputs[0].shape[1]]); const scaled = scalePoses(decoded, [input.shape[1], input.shape[2]], [model16.inputs[0].shape[2], model16.inputs[0].shape[1]]);
@ -12066,7 +12005,7 @@ var calculateFaceAngle = (face5, imageSize) => {
thetaY = 0; thetaY = 0;
if (isNaN(thetaZ)) if (isNaN(thetaZ))
thetaZ = 0; thetaZ = 0;
return { pitch: 2 * -thetaX, yaw: 2 * -thetaY, roll: 2 * -thetaZ }; return { pitch: -thetaX, yaw: -thetaY, roll: -thetaZ };
}; };
const meshToEulerAngle = (mesh2) => { const meshToEulerAngle = (mesh2) => {
const radians = (a1, a2, b1, b2) => Math.atan2(b2 - a2, b1 - a1); const radians = (a1, a2, b1, b2) => Math.atan2(b2 - a2, b1 - a1);
@ -12412,7 +12351,7 @@ function calc2(newResult, config3) {
bufferedResult.body = JSON.parse(JSON.stringify(newResult.body)); bufferedResult.body = JSON.parse(JSON.stringify(newResult.body));
} else { } else {
for (let i = 0; i < newResult.body.length; i++) { for (let i = 0; i < newResult.body.length; i++) {
const box4 = newResult.body[i].box.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor); const box5 = newResult.body[i].box.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor);
const boxRaw = newResult.body[i].boxRaw.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + newBoxCoord) / bufferedFactor); const boxRaw = newResult.body[i].boxRaw.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + newBoxCoord) / bufferedFactor);
const keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({ const keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({
score: newKpt.score, score: newKpt.score,
@ -12446,14 +12385,14 @@ function calc2(newResult, config3) {
} }
annotations2[name] = pt; annotations2[name] = pt;
} }
bufferedResult.body[i] = { ...newResult.body[i], box: box4, boxRaw, keypoints, annotations: annotations2 }; bufferedResult.body[i] = { ...newResult.body[i], box: box5, boxRaw, keypoints, annotations: annotations2 };
} }
} }
if (!bufferedResult.hand || newResult.hand.length !== bufferedResult.hand.length) { if (!bufferedResult.hand || newResult.hand.length !== bufferedResult.hand.length) {
bufferedResult.hand = JSON.parse(JSON.stringify(newResult.hand)); bufferedResult.hand = JSON.parse(JSON.stringify(newResult.hand));
} else { } else {
for (let i = 0; i < newResult.hand.length; i++) { for (let i = 0; i < newResult.hand.length; i++) {
const box4 = newResult.hand[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].box[j] + b) / bufferedFactor); const box5 = newResult.hand[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].box[j] + b) / bufferedFactor);
const boxRaw = newResult.hand[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].boxRaw[j] + b) / bufferedFactor); const boxRaw = newResult.hand[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].boxRaw[j] + b) / bufferedFactor);
if (bufferedResult.hand[i].keypoints.length !== newResult.hand[i].keypoints.length) if (bufferedResult.hand[i].keypoints.length !== newResult.hand[i].keypoints.length)
bufferedResult.hand[i].keypoints = newResult.hand[i].keypoints; bufferedResult.hand[i].keypoints = newResult.hand[i].keypoints;
@ -12467,14 +12406,14 @@ function calc2(newResult, config3) {
annotations2[key] = newResult.hand[i].annotations[key] && newResult.hand[i].annotations[key][0] ? newResult.hand[i].annotations[key].map((val, j) => val.map((coord, k) => ((bufferedFactor - 1) * bufferedResult.hand[i].annotations[key][j][k] + coord) / bufferedFactor)) : null; annotations2[key] = newResult.hand[i].annotations[key] && newResult.hand[i].annotations[key][0] ? newResult.hand[i].annotations[key].map((val, j) => val.map((coord, k) => ((bufferedFactor - 1) * bufferedResult.hand[i].annotations[key][j][k] + coord) / bufferedFactor)) : null;
} }
} }
bufferedResult.hand[i] = { ...newResult.hand[i], box: box4, boxRaw, keypoints, annotations: annotations2 }; bufferedResult.hand[i] = { ...newResult.hand[i], box: box5, boxRaw, keypoints, annotations: annotations2 };
} }
} }
if (!bufferedResult.face || newResult.face.length !== bufferedResult.face.length) { if (!bufferedResult.face || newResult.face.length !== bufferedResult.face.length) {
bufferedResult.face = JSON.parse(JSON.stringify(newResult.face)); bufferedResult.face = JSON.parse(JSON.stringify(newResult.face));
} else { } else {
for (let i = 0; i < newResult.face.length; i++) { for (let i = 0; i < newResult.face.length; i++) {
const box4 = newResult.face[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].box[j] + b) / bufferedFactor); const box5 = newResult.face[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].box[j] + b) / bufferedFactor);
const boxRaw = newResult.face[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].boxRaw[j] + b) / bufferedFactor); const boxRaw = newResult.face[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].boxRaw[j] + b) / bufferedFactor);
if (newResult.face[i].rotation) { if (newResult.face[i].rotation) {
const rotation = { matrix: [0, 0, 0, 0, 0, 0, 0, 0, 0], angle: { roll: 0, yaw: 0, pitch: 0 }, gaze: { bearing: 0, strength: 0 } }; const rotation = { matrix: [0, 0, 0, 0, 0, 0, 0, 0, 0], angle: { roll: 0, yaw: 0, pitch: 0 }, gaze: { bearing: 0, strength: 0 } };
@ -12488,18 +12427,18 @@ function calc2(newResult, config3) {
bearing: ((bufferedFactor - 1) * (((_u = (_t = bufferedResult.face[i].rotation) == null ? void 0 : _t.gaze) == null ? void 0 : _u.bearing) || 0) + (((_w = (_v = newResult.face[i].rotation) == null ? void 0 : _v.gaze) == null ? void 0 : _w.bearing) || 0)) / bufferedFactor, bearing: ((bufferedFactor - 1) * (((_u = (_t = bufferedResult.face[i].rotation) == null ? void 0 : _t.gaze) == null ? void 0 : _u.bearing) || 0) + (((_w = (_v = newResult.face[i].rotation) == null ? void 0 : _v.gaze) == null ? void 0 : _w.bearing) || 0)) / bufferedFactor,
strength: ((bufferedFactor - 1) * (((_y = (_x = bufferedResult.face[i].rotation) == null ? void 0 : _x.gaze) == null ? void 0 : _y.strength) || 0) + (((_A = (_z = newResult.face[i].rotation) == null ? void 0 : _z.gaze) == null ? void 0 : _A.strength) || 0)) / bufferedFactor strength: ((bufferedFactor - 1) * (((_y = (_x = bufferedResult.face[i].rotation) == null ? void 0 : _x.gaze) == null ? void 0 : _y.strength) || 0) + (((_A = (_z = newResult.face[i].rotation) == null ? void 0 : _z.gaze) == null ? void 0 : _A.strength) || 0)) / bufferedFactor
}; };
bufferedResult.face[i] = { ...newResult.face[i], rotation, box: box4, boxRaw }; bufferedResult.face[i] = { ...newResult.face[i], rotation, box: box5, boxRaw };
} }
bufferedResult.face[i] = { ...newResult.face[i], box: box4, boxRaw }; bufferedResult.face[i] = { ...newResult.face[i], box: box5, boxRaw };
} }
} }
if (!bufferedResult.object || newResult.object.length !== bufferedResult.object.length) { if (!bufferedResult.object || newResult.object.length !== bufferedResult.object.length) {
bufferedResult.object = JSON.parse(JSON.stringify(newResult.object)); bufferedResult.object = JSON.parse(JSON.stringify(newResult.object));
} else { } else {
for (let i = 0; i < newResult.object.length; i++) { for (let i = 0; i < newResult.object.length; i++) {
const box4 = newResult.object[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].box[j] + b) / bufferedFactor); const box5 = newResult.object[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].box[j] + b) / bufferedFactor);
const boxRaw = newResult.object[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].boxRaw[j] + b) / bufferedFactor); const boxRaw = newResult.object[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].boxRaw[j] + b) / bufferedFactor);
bufferedResult.object[i] = { ...newResult.object[i], box: box4, boxRaw }; bufferedResult.object[i] = { ...newResult.object[i], box: box5, boxRaw };
} }
} }
if (newResult.persons) { if (newResult.persons) {
@ -12508,7 +12447,7 @@ function calc2(newResult, config3) {
bufferedResult.persons = JSON.parse(JSON.stringify(newPersons)); bufferedResult.persons = JSON.parse(JSON.stringify(newPersons));
} else { } else {
for (let i = 0; i < newPersons.length; i++) { for (let i = 0; i < newPersons.length; i++) {
bufferedResult.persons[i].box = newPersons[i].box.map((box4, j) => ((bufferedFactor - 1) * bufferedResult.persons[i].box[j] + box4) / bufferedFactor); bufferedResult.persons[i].box = newPersons[i].box.map((box5, j) => ((bufferedFactor - 1) * bufferedResult.persons[i].box[j] + box5) / bufferedFactor);
} }
} }
} }
@ -12599,10 +12538,10 @@ function join2(faces, bodies, hands, gestures, shape) {
} }
const x = []; const x = [];
const y = []; const y = [];
const extractXY = (box4) => { const extractXY = (box5) => {
if (box4 && box4.length === 4) { if (box5 && box5.length === 4) {
x.push(box4[0], box4[0] + box4[2]); x.push(box5[0], box5[0] + box5[2]);
y.push(box4[1], box4[1] + box4[3]); y.push(box5[1], box5[1] + box5[3]);
} }
}; };
extractXY((_k = person2.face) == null ? void 0 : _k.box); extractXY((_k = person2.face) == null ? void 0 : _k.box);

471
dist/human.node.js vendored
View File

@ -980,8 +980,8 @@ function GLImageFilter() {
// src/image/enhance.ts // src/image/enhance.ts
var tf = __toModule(require_tfjs_esm()); var tf = __toModule(require_tfjs_esm());
async function histogramEqualization(inputImage) { async function histogramEqualization(inputImage) {
const squeeze11 = inputImage.shape.length === 4 ? tf.squeeze(inputImage) : inputImage; const squeeze10 = inputImage.shape.length === 4 ? tf.squeeze(inputImage) : inputImage;
const channels = tf.split(squeeze11, 3, 2); const channels = tf.split(squeeze10, 3, 2);
const min2 = [tf.min(channels[0]), tf.min(channels[1]), tf.min(channels[2])]; const min2 = [tf.min(channels[0]), tf.min(channels[1]), tf.min(channels[2])];
const max4 = [tf.max(channels[0]), tf.max(channels[1]), tf.max(channels[2])]; const max4 = [tf.max(channels[0]), tf.max(channels[1]), tf.max(channels[2])];
const absMax = await Promise.all(max4.map((channel) => channel.data())); const absMax = await Promise.all(max4.map((channel) => channel.data()));
@ -991,8 +991,8 @@ async function histogramEqualization(inputImage) {
const fact = [tf.div(maxValue, range[0]), tf.div(maxValue, range[1]), tf.div(maxValue, range[2])]; const fact = [tf.div(maxValue, range[0]), tf.div(maxValue, range[1]), tf.div(maxValue, range[2])];
const enh = [tf.mul(sub10[0], fact[0]), tf.mul(sub10[1], fact[1]), tf.mul(sub10[2], fact[2])]; const enh = [tf.mul(sub10[0], fact[0]), tf.mul(sub10[1], fact[1]), tf.mul(sub10[2], fact[2])];
const rgb2 = tf.stack([enh[0], enh[1], enh[2]], 2); const rgb2 = tf.stack([enh[0], enh[1], enh[2]], 2);
const reshape8 = tf.reshape(rgb2, [1, squeeze11.shape[0], squeeze11.shape[1], 3]); const reshape8 = tf.reshape(rgb2, [1, squeeze10.shape[0], squeeze10.shape[1], 3]);
tf.dispose([...channels, ...min2, ...max4, ...sub10, ...range, ...fact, ...enh, rgb2, squeeze11]); tf.dispose([...channels, ...min2, ...max4, ...sub10, ...range, ...fact, ...enh, rgb2, squeeze10]);
return reshape8; return reshape8;
} }
@ -1414,8 +1414,8 @@ async function predict(image29, config3, idx, count2) {
if (!(model == null ? void 0 : model.inputs[0].shape)) if (!(model == null ? void 0 : model.inputs[0].shape))
return; return;
const t = {}; const t = {};
const box4 = [[0, 0.1, 0.9, 0.9]]; const box5 = [[0, 0.1, 0.9, 0.9]];
t.resize = tf4.image.cropAndResize(image29, box4, [0], [model.inputs[0].shape[2], model.inputs[0].shape[1]]); t.resize = tf4.image.cropAndResize(image29, box5, [0], [model.inputs[0].shape[2], model.inputs[0].shape[1]]);
const obj = { age: 0, gender: "unknown", genderScore: 0, race: [] }; const obj = { age: 0, gender: "unknown", genderScore: 0, race: [] };
if ((_a2 = config3.face["gear"]) == null ? void 0 : _a2.enabled) if ((_a2 = config3.face["gear"]) == null ? void 0 : _a2.enabled)
[t.age, t.gender, t.race] = model.execute(t.resize, ["age_output", "gender_output", "race_output"]); [t.age, t.gender, t.race] = model.execute(t.resize, ["age_output", "gender_output", "race_output"]);
@ -4911,44 +4911,44 @@ var UV33 = VTX33.map((x) => UV468[x]);
var UV7 = VTX7.map((x) => UV468[x]); var UV7 = VTX7.map((x) => UV468[x]);
// src/face/facemeshutil.ts // src/face/facemeshutil.ts
var getBoxSize = (box4) => [Math.abs(box4.endPoint[0] - box4.startPoint[0]), Math.abs(box4.endPoint[1] - box4.startPoint[1])]; var getBoxSize = (box5) => [Math.abs(box5.endPoint[0] - box5.startPoint[0]), Math.abs(box5.endPoint[1] - box5.startPoint[1])];
var getBoxCenter = (box4) => [box4.startPoint[0] + (box4.endPoint[0] - box4.startPoint[0]) / 2, box4.startPoint[1] + (box4.endPoint[1] - box4.startPoint[1]) / 2]; var getBoxCenter = (box5) => [box5.startPoint[0] + (box5.endPoint[0] - box5.startPoint[0]) / 2, box5.startPoint[1] + (box5.endPoint[1] - box5.startPoint[1]) / 2];
var getClampedBox = (box4, input) => box4 ? [ var getClampedBox = (box5, input) => box5 ? [
Math.trunc(Math.max(0, box4.startPoint[0])), Math.trunc(Math.max(0, box5.startPoint[0])),
Math.trunc(Math.max(0, box4.startPoint[1])), Math.trunc(Math.max(0, box5.startPoint[1])),
Math.trunc(Math.min(input.shape[2] || 0, box4.endPoint[0]) - Math.max(0, box4.startPoint[0])), Math.trunc(Math.min(input.shape[2] || 0, box5.endPoint[0]) - Math.max(0, box5.startPoint[0])),
Math.trunc(Math.min(input.shape[1] || 0, box4.endPoint[1]) - Math.max(0, box4.startPoint[1])) Math.trunc(Math.min(input.shape[1] || 0, box5.endPoint[1]) - Math.max(0, box5.startPoint[1]))
] : [0, 0, 0, 0]; ] : [0, 0, 0, 0];
var getRawBox = (box4, input) => box4 ? [ var getRawBox = (box5, input) => box5 ? [
box4.startPoint[0] / (input.shape[2] || 0), box5.startPoint[0] / (input.shape[2] || 0),
box4.startPoint[1] / (input.shape[1] || 0), box5.startPoint[1] / (input.shape[1] || 0),
(box4.endPoint[0] - box4.startPoint[0]) / (input.shape[2] || 0), (box5.endPoint[0] - box5.startPoint[0]) / (input.shape[2] || 0),
(box4.endPoint[1] - box4.startPoint[1]) / (input.shape[1] || 0) (box5.endPoint[1] - box5.startPoint[1]) / (input.shape[1] || 0)
] : [0, 0, 0, 0]; ] : [0, 0, 0, 0];
var scaleBoxCoordinates = (box4, factor) => { var scaleBoxCoordinates = (box5, factor) => {
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]]; const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]]; const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
return { startPoint, endPoint, landmarks: box4.landmarks, confidence: box4.confidence }; return { startPoint, endPoint, landmarks: box5.landmarks, confidence: box5.confidence };
}; };
var cutBoxFromImageAndResize = (box4, image29, cropSize) => { var cutBoxFromImageAndResize = (box5, image29, cropSize) => {
const h = image29.shape[1]; const h = image29.shape[1];
const w = image29.shape[2]; const w = image29.shape[2];
const crop2 = tf9.image.cropAndResize(image29, [[box4.startPoint[1] / h, box4.startPoint[0] / w, box4.endPoint[1] / h, box4.endPoint[0] / w]], [0], cropSize); const crop2 = tf9.image.cropAndResize(image29, [[box5.startPoint[1] / h, box5.startPoint[0] / w, box5.endPoint[1] / h, box5.endPoint[0] / w]], [0], cropSize);
const norm = tf9.div(crop2, constants.tf255); const norm = tf9.div(crop2, constants.tf255);
tf9.dispose(crop2); tf9.dispose(crop2);
return norm; return norm;
}; };
var enlargeBox = (box4, factor) => { var enlargeBox = (box5, factor) => {
const center = getBoxCenter(box4); const center = getBoxCenter(box5);
const size2 = getBoxSize(box4); const size2 = getBoxSize(box5);
const halfSize = [factor * size2[0] / 2, factor * size2[1] / 2]; const halfSize = [factor * size2[0] / 2, factor * size2[1] / 2];
return { startPoint: [center[0] - halfSize[0], center[1] - halfSize[1]], endPoint: [center[0] + halfSize[0], center[1] + halfSize[1]], landmarks: box4.landmarks, confidence: box4.confidence }; return { startPoint: [center[0] - halfSize[0], center[1] - halfSize[1]], endPoint: [center[0] + halfSize[0], center[1] + halfSize[1]], landmarks: box5.landmarks, confidence: box5.confidence };
}; };
var squarifyBox = (box4) => { var squarifyBox = (box5) => {
const centers = getBoxCenter(box4); const centers = getBoxCenter(box5);
const size2 = getBoxSize(box4); const size2 = getBoxSize(box5);
const halfSize = Math.max(...size2) / 2; const halfSize = Math.max(...size2) / 2;
return { startPoint: [Math.round(centers[0] - halfSize), Math.round(centers[1] - halfSize)], endPoint: [Math.round(centers[0] + halfSize), Math.round(centers[1] + halfSize)], landmarks: box4.landmarks, confidence: box4.confidence }; return { startPoint: [Math.round(centers[0] - halfSize), Math.round(centers[1] - halfSize)], endPoint: [Math.round(centers[0] + halfSize), Math.round(centers[1] + halfSize)], landmarks: box5.landmarks, confidence: box5.confidence };
}; };
var calculateLandmarksBoundingBox = (landmarks) => { var calculateLandmarksBoundingBox = (landmarks) => {
const xs = landmarks.map((d) => d[0]); const xs = landmarks.map((d) => d[0]);
@ -5016,8 +5016,8 @@ function generateAnchors(inputSize9) {
} }
return anchors4; return anchors4;
} }
function transformRawCoords(coordsRaw, box4, angle, rotationMatrix, inputSize9) { function transformRawCoords(coordsRaw, box5, angle, rotationMatrix, inputSize9) {
const boxSize = getBoxSize(box4); const boxSize = getBoxSize(box5);
const coordsScaled = coordsRaw.map((coord) => [ const coordsScaled = coordsRaw.map((coord) => [
boxSize[0] / inputSize9 * (coord[0] - inputSize9 / 2), boxSize[0] / inputSize9 * (coord[0] - inputSize9 / 2),
boxSize[1] / inputSize9 * (coord[1] - inputSize9 / 2), boxSize[1] / inputSize9 * (coord[1] - inputSize9 / 2),
@ -5027,33 +5027,33 @@ function transformRawCoords(coordsRaw, box4, angle, rotationMatrix, inputSize9)
const coordsRotationMatrix = largeAngle ? buildRotationMatrix(angle, [0, 0]) : fixedRotationMatrix; const coordsRotationMatrix = largeAngle ? buildRotationMatrix(angle, [0, 0]) : fixedRotationMatrix;
const coordsRotated = largeAngle ? coordsScaled.map((coord) => [...rotatePoint(coord, coordsRotationMatrix), coord[2]]) : coordsScaled; const coordsRotated = largeAngle ? coordsScaled.map((coord) => [...rotatePoint(coord, coordsRotationMatrix), coord[2]]) : coordsScaled;
const inverseRotationMatrix = largeAngle ? invertTransformMatrix(rotationMatrix) : fixedRotationMatrix; const inverseRotationMatrix = largeAngle ? invertTransformMatrix(rotationMatrix) : fixedRotationMatrix;
const boxCenter = [...getBoxCenter({ startPoint: box4.startPoint, endPoint: box4.endPoint }), 1]; const boxCenter = [...getBoxCenter({ startPoint: box5.startPoint, endPoint: box5.endPoint }), 1];
return coordsRotated.map((coord) => [ return coordsRotated.map((coord) => [
Math.round(coord[0] + dot(boxCenter, inverseRotationMatrix[0])), Math.round(coord[0] + dot(boxCenter, inverseRotationMatrix[0])),
Math.round(coord[1] + dot(boxCenter, inverseRotationMatrix[1])), Math.round(coord[1] + dot(boxCenter, inverseRotationMatrix[1])),
Math.round(coord[2] || 0) Math.round(coord[2] || 0)
]); ]);
} }
function correctFaceRotation(rotate, box4, input, inputSize9) { function correctFaceRotation(rotate, box5, input, inputSize9) {
const symmetryLine = box4.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine; const symmetryLine = box5.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine;
let angle = 0; let angle = 0;
let rotationMatrix = fixedRotationMatrix; let rotationMatrix = fixedRotationMatrix;
let face5; let face5;
if (rotate && env.kernels.includes("rotatewithoffset")) { if (rotate && env.kernels.includes("rotatewithoffset")) {
angle = computeRotation(box4.landmarks[symmetryLine[0]], box4.landmarks[symmetryLine[1]]); angle = computeRotation(box5.landmarks[symmetryLine[0]], box5.landmarks[symmetryLine[1]]);
const largeAngle = angle && angle !== 0 && Math.abs(angle) > 0.2; const largeAngle = angle && angle !== 0 && Math.abs(angle) > 0.2;
if (largeAngle) { if (largeAngle) {
const center = getBoxCenter({ startPoint: box4.startPoint, endPoint: box4.endPoint }); const center = getBoxCenter({ startPoint: box5.startPoint, endPoint: box5.endPoint });
const centerRaw = [center[0] / input.shape[2], center[1] / input.shape[1]]; const centerRaw = [center[0] / input.shape[2], center[1] / input.shape[1]];
const rotated = tf9.image.rotateWithOffset(input, angle, 0, centerRaw); const rotated = tf9.image.rotateWithOffset(input, angle, 0, centerRaw);
rotationMatrix = buildRotationMatrix(-angle, center); rotationMatrix = buildRotationMatrix(-angle, center);
face5 = cutBoxFromImageAndResize(box4, rotated, [inputSize9, inputSize9]); face5 = cutBoxFromImageAndResize(box5, rotated, [inputSize9, inputSize9]);
tf9.dispose(rotated); tf9.dispose(rotated);
} else { } else {
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]); face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
} }
} else { } else {
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]); face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
} }
return [angle, rotationMatrix, face5]; return [angle, rotationMatrix, face5];
} }
@ -5238,41 +5238,39 @@ async function createAnchors() {
} }
anchorTensor = { x: tf11.tensor1d(anchors4.map((a) => a.x)), y: tf11.tensor1d(anchors4.map((a) => a.y)) }; anchorTensor = { x: tf11.tensor1d(anchors4.map((a) => a.x)), y: tf11.tensor1d(anchors4.map((a) => a.y)) };
} }
var cropFactor = [5, 5];
function decodeBoxes(boxesTensor, anchor) { // src/util/box.ts
return tf11.tidy(() => { function calc(keypoints, outputSize2 = [1, 1]) {
const split5 = tf11.split(boxesTensor, 12, 1); const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
let xCenter = tf11.squeeze(split5[0]); const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
let yCenter = tf11.squeeze(split5[1]); const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
let width = tf11.squeeze(split5[2]); const box5 = [min2[0], min2[1], max4[0] - min2[0], max4[1] - min2[1]];
let height = tf11.squeeze(split5[3]); const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
xCenter = tf11.add(tf11.div(xCenter, inputSize2), anchor.x); return { box: box5, boxRaw };
yCenter = tf11.add(tf11.div(yCenter, inputSize2), anchor.y);
width = tf11.mul(tf11.div(width, inputSize2), cropFactor[0]);
height = tf11.mul(tf11.div(height, inputSize2), cropFactor[1]);
const xMin = tf11.sub(xCenter, tf11.div(width, 2));
const yMin = tf11.sub(yCenter, tf11.div(height, 2));
const boxes = tf11.stack([xMin, yMin, width, height], 1);
return boxes;
});
} }
async function decode(boxesTensor, logitsTensor, config3, outputSize2) { function square(keypoints, outputSize2 = [1, 1]) {
const t = {}; const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
t.boxes = decodeBoxes(boxesTensor, anchorTensor); const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
t.scores = tf11.sigmoid(logitsTensor); const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
t.argmax = tf11.argMax(t.scores); const center = [(min2[0] + max4[0]) / 2, (min2[1] + max4[1]) / 2];
const i = (await t.argmax.data())[0]; const dist = Math.max(center[0] - min2[0], center[1] - min2[1], -center[0] + max4[0], -center[1] + max4[1]);
const scores = await t.scores.data(); const box5 = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];
const detected = []; const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
const minScore = config3.body["detector"] && config3.body["detector"]["minConfidence"] ? config3.body["detector"]["minConfidence"] : 0; return { box: box5, boxRaw };
if (scores[i] >= minScore) { }
const boxes = await t.boxes.array(); function scale(box5, scaleFact) {
const boxRaw = boxes[i]; const dist = [box5[2] * scaleFact, box5[3] * scaleFact];
const box4 = [boxRaw[0] * outputSize2[0], boxRaw[1] * outputSize2[1], boxRaw[2] * outputSize2[0], boxRaw[3] * outputSize2[1]]; const newBox = [
detected.push({ box: box4, boxRaw, score: scores[i] }); box5[0] - (dist[0] - box5[2]) / 2,
} box5[1] - (dist[1] - box5[3]) / 2,
Object.keys(t).forEach((tensor3) => tf11.dispose(t[tensor3])); dist[0],
return detected; dist[1]
];
return newBox;
}
function crop(box5) {
const yxBox = [Math.max(0, box5[1]), Math.max(0, box5[0]), Math.min(1, box5[3] + box5[1]), Math.min(1, box5[2] + box5[0])];
return yxBox;
} }
// src/body/blazepose.ts // src/body/blazepose.ts
@ -5285,7 +5283,7 @@ var outputNodes = {
detector: [] detector: []
}; };
var cache = null; var cache = null;
var lastBox; var cropBox;
var padding = [[0, 0], [0, 0], [0, 0], [0, 0]]; var padding = [[0, 0], [0, 0], [0, 0], [0, 0]];
var lastTime5 = 0; var lastTime5 = 0;
var sigmoid3 = (x) => 1 - 1 / (1 + Math.exp(x)); var sigmoid3 = (x) => 1 - 1 / (1 + Math.exp(x));
@ -5322,39 +5320,37 @@ async function loadPose(config3) {
log("cached model:", models.landmarks["modelUrl"]); log("cached model:", models.landmarks["modelUrl"]);
return models.landmarks; return models.landmarks;
} }
function calculateBoxes(keypoints, outputSize2) { async function prepareImage(input, size2) {
const x = keypoints.map((a) => a.position[0]);
const y = keypoints.map((a) => a.position[1]);
const keypointsBox = [Math.min(...x), Math.min(...y), Math.max(...x) - Math.min(...x), Math.max(...y) - Math.min(...y)];
const keypointsBoxRaw = [keypointsBox[0] / outputSize2[0], keypointsBox[1] / outputSize2[1], keypointsBox[2] / outputSize2[0], keypointsBox[3] / outputSize2[1]];
return { keypointsBox, keypointsBoxRaw };
}
async function prepareImage(input, size2, box4) {
const t = {}; const t = {};
if (!input.shape || !input.shape[1] || !input.shape[2]) if (!input.shape || !input.shape[1] || !input.shape[2])
return input; return input;
let final; let final;
if (cropBox) {
t.cropped = tf12.image.cropAndResize(input, [cropBox], [0], [input.shape[1], input.shape[2]]);
}
if (input.shape[1] !== input.shape[2]) { if (input.shape[1] !== input.shape[2]) {
const height = box4 ? [Math.trunc(input.shape[1] * box4[1]), Math.trunc(input.shape[1] * (box4[1] + box4[3]))] : [input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0, input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0]; const height = [
const width = box4 ? [Math.trunc(input.shape[2] * box4[0]), Math.trunc(input.shape[2] * (box4[0] + box4[2]))] : [input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0, input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0]; input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0,
input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0
];
const width = [
input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0,
input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0
];
padding = [ padding = [
[0, 0], [0, 0],
height, height,
width, width,
[0, 0] [0, 0]
]; ];
if (box4) { t.pad = tf12.pad(t.cropped || input, padding);
t.resize = tf12.image.cropAndResize(input, [box4], [0], [size2, size2]); t.resize = tf12.image.resizeBilinear(t.pad, [size2, size2]);
} else {
t.pad = tf12.pad(input, padding);
t.resize = tf12.image.resizeBilinear(t.pad, [size2, size2]);
}
final = tf12.div(t.resize, constants.tf255); final = tf12.div(t.resize, constants.tf255);
} else if (input.shape[1] !== size2) { } else if (input.shape[1] !== size2) {
t.resize = tf12.image.resizeBilinear(input, [size2, size2]); t.resize = tf12.image.resizeBilinear(t.cropped || input, [size2, size2]);
final = tf12.div(t.resize, constants.tf255); final = tf12.div(t.resize, constants.tf255);
} else { } else {
final = tf12.div(input, constants.tf255); final = tf12.div(t.cropped || input, constants.tf255);
} }
Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3])); Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3]));
return final; return final;
@ -5368,19 +5364,21 @@ function rescaleKeypoints(keypoints, outputSize2) {
]; ];
kpt4.positionRaw = [kpt4.position[0] / outputSize2[0], kpt4.position[1] / outputSize2[1], kpt4.position[2]]; kpt4.positionRaw = [kpt4.position[0] / outputSize2[0], kpt4.position[1] / outputSize2[1], kpt4.position[2]];
} }
return keypoints; if (cropBox) {
} for (const kpt4 of keypoints) {
function rescaleBoxes(boxes, outputSize2) { kpt4.positionRaw = [
for (const box4 of boxes) { kpt4.positionRaw[0] + cropBox[1],
box4.box = [ kpt4.positionRaw[1] + cropBox[0],
Math.trunc(box4.box[0] * (outputSize2[0] + padding[2][0] + padding[2][1]) / outputSize2[0]), kpt4.positionRaw[2]
Math.trunc(box4.box[1] * (outputSize2[1] + padding[1][0] + padding[1][1]) / outputSize2[1]), ];
Math.trunc(box4.box[2] * (outputSize2[0] + padding[2][0] + padding[2][1]) / outputSize2[0]), kpt4.position = [
Math.trunc(box4.box[3] * (outputSize2[1] + padding[1][0] + padding[1][1]) / outputSize2[1]) Math.trunc(kpt4.positionRaw[0] * outputSize2[0]),
]; Math.trunc(kpt4.positionRaw[1] * outputSize2[1]),
box4.boxRaw = [box4.box[0] / outputSize2[0], box4.box[1] / outputSize2[1], box4.box[2] / outputSize2[0], box4.box[3] / outputSize2[1]]; kpt4.positionRaw[2]
];
}
} }
return boxes; return keypoints;
} }
async function detectLandmarks(input, config3, outputSize2) { async function detectLandmarks(input, config3, outputSize2) {
var _a; var _a;
@ -5402,7 +5400,8 @@ async function detectLandmarks(input, config3, outputSize2) {
if (poseScore < (config3.body.minConfidence || 0)) if (poseScore < (config3.body.minConfidence || 0))
return null; return null;
const keypoints = rescaleKeypoints(keypointsRelative, outputSize2); const keypoints = rescaleKeypoints(keypointsRelative, outputSize2);
const boxes = calculateBoxes(keypoints, [outputSize2[0], outputSize2[1]]); const kpts = keypoints.map((k) => k.position);
const boxes = calc(kpts, [outputSize2[0], outputSize2[1]]);
const annotations2 = {}; const annotations2 = {};
for (const [name, indexes] of Object.entries(connected)) { for (const [name, indexes] of Object.entries(connected)) {
const pt = []; const pt = [];
@ -5414,22 +5413,9 @@ async function detectLandmarks(input, config3, outputSize2) {
} }
annotations2[name] = pt; annotations2[name] = pt;
} }
const body4 = { id: 0, score: Math.trunc(100 * poseScore) / 100, box: boxes.keypointsBox, boxRaw: boxes.keypointsBoxRaw, keypoints, annotations: annotations2 }; const body4 = { id: 0, score: Math.trunc(100 * poseScore) / 100, box: boxes.box, boxRaw: boxes.boxRaw, keypoints, annotations: annotations2 };
return body4; return body4;
} }
async function detectBoxes(input, config3, outputSize2) {
var _a;
const t = {};
t.res = (_a = models.detector) == null ? void 0 : _a.execute(input, ["Identity"]);
t.logitsRaw = tf12.slice(t.res, [0, 0, 0], [1, -1, 1]);
t.boxesRaw = tf12.slice(t.res, [0, 0, 1], [1, -1, -1]);
t.logits = tf12.squeeze(t.logitsRaw);
t.boxes = tf12.squeeze(t.boxesRaw);
const boxes = await decode(t.boxes, t.logits, config3, outputSize2);
rescaleBoxes(boxes, outputSize2);
Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3]));
return boxes;
}
async function predict5(input, config3) { async function predict5(input, config3) {
const outputSize2 = [input.shape[2] || 0, input.shape[1] || 0]; const outputSize2 = [input.shape[2] || 0, input.shape[1] || 0];
const skipTime = (config3.body.skipTime || 0) > now() - lastTime5; const skipTime = (config3.body.skipTime || 0) > now() - lastTime5;
@ -5438,26 +5424,13 @@ async function predict5(input, config3) {
skipped5++; skipped5++;
} else { } else {
const t = {}; const t = {};
if (config3.body["detector"] && config3.body["detector"]["enabled"]) { t.landmarks = await prepareImage(input, 256);
t.detector = await prepareImage(input, 224); cache = await detectLandmarks(t.landmarks, config3, outputSize2);
const boxes = await detectBoxes(t.detector, config3, outputSize2);
if (boxes && boxes.length === 1) {
t.landmarks = await prepareImage(input, 256, boxes[0].box);
cache = await detectLandmarks(t.landmarks, config3, outputSize2);
}
if (cache)
cache.score = boxes[0].score;
} else {
t.landmarks = await prepareImage(input, 256, lastBox);
cache = await detectLandmarks(t.landmarks, config3, outputSize2);
}
Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3])); Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3]));
lastTime5 = now(); lastTime5 = now();
skipped5 = 0; skipped5 = 0;
} }
if (cache) return cache ? [cache] : [];
return [cache];
return [];
} }
// src/object/centernet.ts // src/object/centernet.ts
@ -5598,13 +5571,13 @@ async function process3(res, outputShape, config3) {
detections[0][id][2] / inputSize4 - x, detections[0][id][2] / inputSize4 - x,
detections[0][id][3] / inputSize4 - y detections[0][id][3] / inputSize4 - y
]; ];
const box4 = [ const box5 = [
Math.trunc(boxRaw[0] * outputShape[0]), Math.trunc(boxRaw[0] * outputShape[0]),
Math.trunc(boxRaw[1] * outputShape[1]), Math.trunc(boxRaw[1] * outputShape[1]),
Math.trunc(boxRaw[2] * outputShape[0]), Math.trunc(boxRaw[2] * outputShape[0]),
Math.trunc(boxRaw[3] * outputShape[1]) Math.trunc(boxRaw[3] * outputShape[1])
]; ];
results.push({ id: i++, score, class: classVal, label, box: box4, boxRaw }); results.push({ id: i++, score, class: classVal, label, box: box5, boxRaw });
} }
Object.keys(t).forEach((tensor3) => tf13.dispose(t[tensor3])); Object.keys(t).forEach((tensor3) => tf13.dispose(t[tensor3]));
return results; return results;
@ -5725,10 +5698,10 @@ async function predict7(image29, config3) {
tf14.dispose(tensor3); tf14.dispose(tensor3);
if (resT) { if (resT) {
cache2.keypoints.length = 0; cache2.keypoints.length = 0;
const squeeze11 = resT.squeeze(); const squeeze10 = resT.squeeze();
tf14.dispose(resT); tf14.dispose(resT);
const stack5 = squeeze11.unstack(2); const stack5 = squeeze10.unstack(2);
tf14.dispose(squeeze11); tf14.dispose(squeeze10);
for (let id = 0; id < stack5.length; id++) { for (let id = 0; id < stack5.length; id++) {
const [x2, y2, partScore] = await max2d(stack5[id], config3.body.minConfidence); const [x2, y2, partScore] = await max2d(stack5[id], config3.body.minConfidence);
if (partScore > (((_a = config3.body) == null ? void 0 : _a.minConfidence) || 0)) { if (partScore > (((_a = config3.body) == null ? void 0 : _a.minConfidence) || 0)) {
@ -5946,20 +5919,20 @@ var getLeftToRightEyeDepthDifference = (rawCoords) => {
return leftEyeZ - rightEyeZ; return leftEyeZ - rightEyeZ;
}; };
var getEyeBox = (rawCoords, face5, eyeInnerCornerIndex, eyeOuterCornerIndex, meshSize, flip = false) => { var getEyeBox = (rawCoords, face5, eyeInnerCornerIndex, eyeOuterCornerIndex, meshSize, flip = false) => {
const box4 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge)); const box5 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge));
const boxSize = getBoxSize(box4); const boxSize = getBoxSize(box5);
let crop2 = tf17.image.cropAndResize(face5, [[ let crop2 = tf17.image.cropAndResize(face5, [[
box4.startPoint[1] / meshSize, box5.startPoint[1] / meshSize,
box4.startPoint[0] / meshSize, box5.startPoint[0] / meshSize,
box4.endPoint[1] / meshSize, box5.endPoint[1] / meshSize,
box4.endPoint[0] / meshSize box5.endPoint[0] / meshSize
]], [0], [inputSize5, inputSize5]); ]], [0], [inputSize5, inputSize5]);
if (flip && env.kernels.includes("flipleftright")) { if (flip && env.kernels.includes("flipleftright")) {
const flipped = tf17.image.flipLeftRight(crop2); const flipped = tf17.image.flipLeftRight(crop2);
tf17.dispose(crop2); tf17.dispose(crop2);
crop2 = flipped; crop2 = flipped;
} }
return { box: box4, boxSize, crop: crop2 }; return { box: box5, boxSize, crop: crop2 };
}; };
var getEyeCoords = (eyeData, eyeBox, eyeBoxSize, flip = false) => { var getEyeCoords = (eyeData, eyeBox, eyeBoxSize, flip = false) => {
const eyeRawCoords = []; const eyeRawCoords = [];
@ -6053,7 +6026,7 @@ async function predict10(input, config3) {
const newCache = []; const newCache = [];
let id = 0; let id = 0;
for (let i = 0; i < boxCache.length; i++) { for (let i = 0; i < boxCache.length; i++) {
let box4 = boxCache[i]; let box5 = boxCache[i];
let angle = 0; let angle = 0;
let rotationMatrix; let rotationMatrix;
const face5 = { const face5 = {
@ -6067,20 +6040,20 @@ async function predict10(input, config3) {
faceScore: 0, faceScore: 0,
annotations: {} annotations: {}
}; };
[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) ? inputSize6 : size()); [angle, rotationMatrix, face5.tensor] = correctFaceRotation((_d = config3.face.detector) == null ? void 0 : _d.rotation, box5, input, ((_e = config3.face.mesh) == null ? void 0 : _e.enabled) ? inputSize6 : size());
if ((_f = config3 == null ? void 0 : config3.filter) == null ? void 0 : _f.equalization) { if ((_f = config3 == null ? void 0 : config3.filter) == null ? void 0 : _f.equalization) {
const equilized = await histogramEqualization(face5.tensor); const equilized = await histogramEqualization(face5.tensor);
tf18.dispose(face5.tensor); tf18.dispose(face5.tensor);
face5.tensor = equilized; face5.tensor = equilized;
} }
face5.boxScore = Math.round(100 * box4.confidence) / 100; face5.boxScore = Math.round(100 * box5.confidence) / 100;
if (!((_g = config3.face.mesh) == null ? void 0 : _g.enabled)) { if (!((_g = config3.face.mesh) == null ? void 0 : _g.enabled)) {
face5.box = getClampedBox(box4, input); face5.box = getClampedBox(box5, input);
face5.boxRaw = getRawBox(box4, input); face5.boxRaw = getRawBox(box5, input);
face5.score = face5.boxScore; face5.score = face5.boxScore;
face5.mesh = box4.landmarks.map((pt) => [ face5.mesh = box5.landmarks.map((pt) => [
(box4.startPoint[0] + box4.endPoint[0]) / 2 + (box4.endPoint[0] + box4.startPoint[0]) * pt[0] / size(), (box5.startPoint[0] + box5.endPoint[0]) / 2 + (box5.endPoint[0] + box5.startPoint[0]) * pt[0] / size(),
(box4.startPoint[1] + box4.endPoint[1]) / 2 + (box4.endPoint[1] + box4.startPoint[1]) * pt[1] / size() (box5.startPoint[1] + box5.endPoint[1]) / 2 + (box5.endPoint[1] + box5.startPoint[1]) * pt[1] / size()
]); ]);
face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]); face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]);
for (const key of Object.keys(blazeFaceLandmarks)) for (const key of Object.keys(blazeFaceLandmarks))
@ -6096,24 +6069,24 @@ async function predict10(input, config3) {
let rawCoords = await coordsReshaped.array(); let rawCoords = await coordsReshaped.array();
tf18.dispose([contourCoords, coordsReshaped, confidence, contours]); tf18.dispose([contourCoords, coordsReshaped, confidence, contours]);
if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) { if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
box4.confidence = face5.faceScore; box5.confidence = face5.faceScore;
} else { } else {
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled) if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize6); rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize6);
face5.mesh = transformRawCoords(rawCoords, box4, angle, rotationMatrix, inputSize6); face5.mesh = transformRawCoords(rawCoords, box5, angle, rotationMatrix, inputSize6);
face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]); face5.meshRaw = face5.mesh.map((pt) => [pt[0] / (input.shape[2] || 0), pt[1] / (input.shape[1] || 0), (pt[2] || 0) / inputSize6]);
for (const key of Object.keys(meshAnnotations)) for (const key of Object.keys(meshAnnotations))
face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]); face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]);
const boxCalculated = calculateLandmarksBoundingBox(face5.mesh); const boxCalculated = calculateLandmarksBoundingBox(face5.mesh);
const boxEnlarged = enlargeBox(boxCalculated, ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6); const boxEnlarged = enlargeBox(boxCalculated, ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6);
const boxSquared = squarifyBox(boxEnlarged); const boxSquared = squarifyBox(boxEnlarged);
box4 = { ...boxSquared, confidence: box4.confidence }; box5 = { ...boxSquared, confidence: box5.confidence };
face5.box = getClampedBox(box4, input); face5.box = getClampedBox(box5, input);
face5.boxRaw = getRawBox(box4, input); face5.boxRaw = getRawBox(box5, input);
face5.score = face5.faceScore; face5.score = face5.faceScore;
newCache.push(box4); newCache.push(box5);
tf18.dispose(face5.tensor); tf18.dispose(face5.tensor);
[angle, rotationMatrix, face5.tensor] = correctFaceRotation((_k = config3.face.detector) == null ? void 0 : _k.rotation, box4, input, inputSize6); [angle, rotationMatrix, face5.tensor] = correctFaceRotation((_k = config3.face.detector) == null ? void 0 : _k.rotation, box5, input, inputSize6);
} }
} }
faces.push(face5); faces.push(face5);
@ -6226,54 +6199,54 @@ var tf21 = __toModule(require_tfjs_esm());
// src/hand/handposeutil.ts // src/hand/handposeutil.ts
var tf20 = __toModule(require_tfjs_esm()); var tf20 = __toModule(require_tfjs_esm());
function getBoxSize2(box4) { function getBoxSize2(box5) {
return [ return [
Math.abs(box4.endPoint[0] - box4.startPoint[0]), Math.abs(box5.endPoint[0] - box5.startPoint[0]),
Math.abs(box4.endPoint[1] - box4.startPoint[1]) Math.abs(box5.endPoint[1] - box5.startPoint[1])
]; ];
} }
function getBoxCenter2(box4) { function getBoxCenter2(box5) {
return [ return [
box4.startPoint[0] + (box4.endPoint[0] - box4.startPoint[0]) / 2, box5.startPoint[0] + (box5.endPoint[0] - box5.startPoint[0]) / 2,
box4.startPoint[1] + (box4.endPoint[1] - box4.startPoint[1]) / 2 box5.startPoint[1] + (box5.endPoint[1] - box5.startPoint[1]) / 2
]; ];
} }
function cutBoxFromImageAndResize2(box4, image29, cropSize) { function cutBoxFromImageAndResize2(box5, image29, cropSize) {
const h = image29.shape[1]; const h = image29.shape[1];
const w = image29.shape[2]; const w = image29.shape[2];
const boxes = [[ const boxes = [[
box4.startPoint[1] / h, box5.startPoint[1] / h,
box4.startPoint[0] / w, box5.startPoint[0] / w,
box4.endPoint[1] / h, box5.endPoint[1] / h,
box4.endPoint[0] / w box5.endPoint[0] / w
]]; ]];
return tf20.image.cropAndResize(image29, boxes, [0], cropSize); return tf20.image.cropAndResize(image29, boxes, [0], cropSize);
} }
function scaleBoxCoordinates2(box4, factor) { function scaleBoxCoordinates2(box5, factor) {
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]]; const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]]; const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
const palmLandmarks = box4.palmLandmarks.map((coord) => { const palmLandmarks = box5.palmLandmarks.map((coord) => {
const scaledCoord = [coord[0] * factor[0], coord[1] * factor[1]]; const scaledCoord = [coord[0] * factor[0], coord[1] * factor[1]];
return scaledCoord; return scaledCoord;
}); });
return { startPoint, endPoint, palmLandmarks, confidence: box4.confidence }; return { startPoint, endPoint, palmLandmarks, confidence: box5.confidence };
} }
function enlargeBox2(box4, factor = 1.5) { function enlargeBox2(box5, factor = 1.5) {
const center = getBoxCenter2(box4); const center = getBoxCenter2(box5);
const size2 = getBoxSize2(box4); const size2 = getBoxSize2(box5);
const newHalfSize = [factor * size2[0] / 2, factor * size2[1] / 2]; const newHalfSize = [factor * size2[0] / 2, factor * size2[1] / 2];
const startPoint = [center[0] - newHalfSize[0], center[1] - newHalfSize[1]]; const startPoint = [center[0] - newHalfSize[0], center[1] - newHalfSize[1]];
const endPoint = [center[0] + newHalfSize[0], center[1] + newHalfSize[1]]; const endPoint = [center[0] + newHalfSize[0], center[1] + newHalfSize[1]];
return { startPoint, endPoint, palmLandmarks: box4.palmLandmarks }; return { startPoint, endPoint, palmLandmarks: box5.palmLandmarks };
} }
function squarifyBox2(box4) { function squarifyBox2(box5) {
const centers = getBoxCenter2(box4); const centers = getBoxCenter2(box5);
const size2 = getBoxSize2(box4); const size2 = getBoxSize2(box5);
const maxEdge = Math.max(...size2); const maxEdge = Math.max(...size2);
const halfSize = maxEdge / 2; const halfSize = maxEdge / 2;
const startPoint = [centers[0] - halfSize, centers[1] - halfSize]; const startPoint = [centers[0] - halfSize, centers[1] - halfSize];
const endPoint = [centers[0] + halfSize, centers[1] + halfSize]; const endPoint = [centers[0] + halfSize, centers[1] + halfSize];
return { startPoint, endPoint, palmLandmarks: box4.palmLandmarks }; return { startPoint, endPoint, palmLandmarks: box5.palmLandmarks };
} }
function normalizeRadians2(angle) { function normalizeRadians2(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));
@ -9347,9 +9320,9 @@ var HandDetector = class {
p.slice = tf21.slice(t.predictions, [index2, 5], [1, 14]); p.slice = tf21.slice(t.predictions, [index2, 5], [1, 14]);
p.norm = this.normalizeLandmarks(p.slice, index2); p.norm = this.normalizeLandmarks(p.slice, index2);
p.palmLandmarks = tf21.reshape(p.norm, [-1, 2]); p.palmLandmarks = tf21.reshape(p.norm, [-1, 2]);
const box4 = await p.box.data(); const box5 = await p.box.data();
const startPoint = box4.slice(0, 2); const startPoint = box5.slice(0, 2);
const endPoint = box4.slice(2, 4); const endPoint = box5.slice(2, 4);
const palmLandmarks = await p.palmLandmarks.array(); const palmLandmarks = await p.palmLandmarks.array();
const hand3 = { startPoint, endPoint, palmLandmarks, confidence: scores[index2] }; const hand3 = { startPoint, endPoint, palmLandmarks, confidence: scores[index2] };
const scaled = scaleBoxCoordinates2(hand3, [input.shape[2] / this.inputSize, input.shape[1] / this.inputSize]); const scaled = scaleBoxCoordinates2(hand3, [input.shape[2] / this.inputSize, input.shape[1] / this.inputSize]);
@ -9936,24 +9909,24 @@ async function predict12(input, config3) {
} }
} }
const keypoints = predictions[i].landmarks; const keypoints = predictions[i].landmarks;
let box4 = [Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, 0, 0]; let box5 = [Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, 0, 0];
let boxRaw = [0, 0, 0, 0]; let boxRaw = [0, 0, 0, 0];
if (keypoints && keypoints.length > 0) { if (keypoints && keypoints.length > 0) {
for (const pt of keypoints) { for (const pt of keypoints) {
if (pt[0] < box4[0]) if (pt[0] < box5[0])
box4[0] = pt[0]; box5[0] = pt[0];
if (pt[1] < box4[1]) if (pt[1] < box5[1])
box4[1] = pt[1]; box5[1] = pt[1];
if (pt[0] > box4[2]) if (pt[0] > box5[2])
box4[2] = pt[0]; box5[2] = pt[0];
if (pt[1] > box4[3]) if (pt[1] > box5[3])
box4[3] = pt[1]; box5[3] = pt[1];
} }
box4[2] -= box4[0]; box5[2] -= box5[0];
box4[3] -= box4[1]; box5[3] -= box5[1];
boxRaw = [box4[0] / (input.shape[2] || 0), box4[1] / (input.shape[1] || 0), box4[2] / (input.shape[2] || 0), box4[3] / (input.shape[1] || 0)]; boxRaw = [box5[0] / (input.shape[2] || 0), box5[1] / (input.shape[1] || 0), box5[2] / (input.shape[2] || 0), box5[3] / (input.shape[1] || 0)];
} else { } else {
box4 = predictions[i].box ? [ box5 = predictions[i].box ? [
Math.trunc(Math.max(0, predictions[i].box.topLeft[0])), Math.trunc(Math.max(0, predictions[i].box.topLeft[0])),
Math.trunc(Math.max(0, predictions[i].box.topLeft[1])), Math.trunc(Math.max(0, predictions[i].box.topLeft[1])),
Math.trunc(Math.min(input.shape[2] || 0, predictions[i].box.bottomRight[0]) - Math.max(0, predictions[i].box.topLeft[0])), Math.trunc(Math.min(input.shape[2] || 0, predictions[i].box.bottomRight[0]) - Math.max(0, predictions[i].box.topLeft[0])),
@ -9973,7 +9946,7 @@ async function predict12(input, config3) {
boxScore: Math.round(100 * predictions[i].boxConfidence) / 100, boxScore: Math.round(100 * predictions[i].boxConfidence) / 100,
fingerScore: Math.round(100 * predictions[i].fingerConfidence) / 100, fingerScore: Math.round(100 * predictions[i].fingerConfidence) / 100,
label: "hand", label: "hand",
box: box4, box: box5,
boxRaw, boxRaw,
keypoints, keypoints,
annotations: annotations2, annotations: annotations2,
@ -10014,40 +9987,6 @@ async function load13(config3) {
return [handDetectorModel, handPoseModel]; return [handDetectorModel, handPoseModel];
} }
// src/util/box.ts
function calc(keypoints, outputSize2 = [1, 1]) {
const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
const box4 = [min2[0], min2[1], max4[0] - min2[0], max4[1] - min2[1]];
const boxRaw = [box4[0] / outputSize2[0], box4[1] / outputSize2[1], box4[2] / outputSize2[0], box4[3] / outputSize2[1]];
return { box: box4, boxRaw };
}
function square(keypoints, outputSize2 = [1, 1]) {
const coords8 = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])];
const min2 = [Math.min(...coords8[0]), Math.min(...coords8[1])];
const max4 = [Math.max(...coords8[0]), Math.max(...coords8[1])];
const center = [(min2[0] + max4[0]) / 2, (min2[1] + max4[1]) / 2];
const dist = Math.max(center[0] - min2[0], center[1] - min2[1], -center[0] + max4[0], -center[1] + max4[1]);
const box4 = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];
const boxRaw = [box4[0] / outputSize2[0], box4[1] / outputSize2[1], box4[2] / outputSize2[0], box4[3] / outputSize2[1]];
return { box: box4, boxRaw };
}
function scale(box4, scaleFact) {
const dist = [box4[2] * scaleFact, box4[3] * scaleFact];
const newBox = [
box4[0] - (dist[0] - box4[2]) / 2,
box4[1] - (dist[1] - box4[3]) / 2,
dist[0],
dist[1]
];
return newBox;
}
function crop(box4) {
const yxBox = [Math.max(0, box4[1]), Math.max(0, box4[0]), Math.min(1, box4[3] + box4[1]), Math.min(1, box4[2] + box4[0])];
return yxBox;
}
// src/hand/handtrack.ts // src/hand/handtrack.ts
var tf24 = __toModule(require_tfjs_esm()); var tf24 = __toModule(require_tfjs_esm());
var models2 = [null, null]; var models2 = [null, null];
@ -10066,11 +10005,11 @@ var cache3 = {
hands: [] hands: []
}; };
var fingerMap = { var fingerMap = {
thumb: [1, 2, 3, 4], thumb: [0, 1, 2, 3, 4],
index: [5, 6, 7, 8], index: [0, 5, 6, 7, 8],
middle: [9, 10, 11, 12], middle: [0, 9, 10, 11, 12],
ring: [13, 14, 15, 16], ring: [0, 13, 14, 15, 16],
pinky: [17, 18, 19, 20], pinky: [0, 17, 18, 19, 20],
palm: [0] palm: [0]
}; };
async function loadDetect2(config3) { async function loadDetect2(config3) {
@ -10621,7 +10560,7 @@ async function process4(res, inputSize9, outputShape, config3) {
]; ];
let boxRaw = [x, y, w, h]; let boxRaw = [x, y, w, h];
boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1))); boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1)));
const box4 = [ const box5 = [
boxRaw[0] * outputShape[0], boxRaw[0] * outputShape[0],
boxRaw[1] * outputShape[1], boxRaw[1] * outputShape[1],
boxRaw[2] * outputShape[0], boxRaw[2] * outputShape[0],
@ -10632,7 +10571,7 @@ async function process4(res, inputSize9, outputShape, config3) {
score: Math.round(100 * score) / 100, score: Math.round(100 * score) / 100,
class: j + 1, class: j + 1,
label: labels[j].label, label: labels[j].label,
box: box4.map((a) => Math.trunc(a)), box: box5.map((a) => Math.trunc(a)),
boxRaw boxRaw
}; };
results.push(result); results.push(result);
@ -10975,7 +10914,7 @@ function getInstanceScore(existingPoses, keypoints) {
}, 0); }, 0);
return notOverlappedKeypointScores / keypoints.length; return notOverlappedKeypointScores / keypoints.length;
} }
function decode2(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) { function decode(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) {
const poses = []; const poses = [];
const queue = buildPartWithScoreQueue(minConfidence2, scores); const queue = buildPartWithScoreQueue(minConfidence2, scores);
while (poses.length < maxDetected && !queue.empty()) { while (poses.length < maxDetected && !queue.empty()) {
@ -10986,9 +10925,9 @@ function decode2(offsets, scores, displacementsFwd, displacementsBwd, maxDetecte
let keypoints = decodePose(root, scores, offsets, displacementsFwd, displacementsBwd); let keypoints = decodePose(root, scores, offsets, displacementsFwd, displacementsBwd);
keypoints = keypoints.filter((a) => a.score > minConfidence2); keypoints = keypoints.filter((a) => a.score > minConfidence2);
const score = getInstanceScore(poses, keypoints); const score = getInstanceScore(poses, keypoints);
const box4 = getBoundingBox(keypoints); const box5 = getBoundingBox(keypoints);
if (score > minConfidence2) if (score > minConfidence2)
poses.push({ keypoints, box: box4, score: Math.round(100 * score) / 100 }); poses.push({ keypoints, box: box5, score: Math.round(100 * score) / 100 });
} }
return poses; return poses;
} }
@ -11006,7 +10945,7 @@ async function predict17(input, config3) {
const buffers = await Promise.all(res.map((tensor3) => tensor3.buffer())); const buffers = await Promise.all(res.map((tensor3) => tensor3.buffer()));
for (const t of res) for (const t of res)
tf29.dispose(t); tf29.dispose(t);
const decoded = await decode2(buffers[0], buffers[1], buffers[2], buffers[3], config3.body.maxDetected, config3.body.minConfidence); const decoded = await decode(buffers[0], buffers[1], buffers[2], buffers[3], config3.body.maxDetected, config3.body.minConfidence);
if (!model16.inputs[0].shape) if (!model16.inputs[0].shape)
return []; return [];
const scaled = scalePoses(decoded, [input.shape[1], input.shape[2]], [model16.inputs[0].shape[2], model16.inputs[0].shape[1]]); const scaled = scalePoses(decoded, [input.shape[1], input.shape[2]], [model16.inputs[0].shape[2], model16.inputs[0].shape[1]]);
@ -12065,7 +12004,7 @@ var calculateFaceAngle = (face5, imageSize) => {
thetaY = 0; thetaY = 0;
if (isNaN(thetaZ)) if (isNaN(thetaZ))
thetaZ = 0; thetaZ = 0;
return { pitch: 2 * -thetaX, yaw: 2 * -thetaY, roll: 2 * -thetaZ }; return { pitch: -thetaX, yaw: -thetaY, roll: -thetaZ };
}; };
const meshToEulerAngle = (mesh2) => { const meshToEulerAngle = (mesh2) => {
const radians = (a1, a2, b1, b2) => Math.atan2(b2 - a2, b1 - a1); const radians = (a1, a2, b1, b2) => Math.atan2(b2 - a2, b1 - a1);
@ -12411,7 +12350,7 @@ function calc2(newResult, config3) {
bufferedResult.body = JSON.parse(JSON.stringify(newResult.body)); bufferedResult.body = JSON.parse(JSON.stringify(newResult.body));
} else { } else {
for (let i = 0; i < newResult.body.length; i++) { for (let i = 0; i < newResult.body.length; i++) {
const box4 = newResult.body[i].box.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor); const box5 = newResult.body[i].box.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor);
const boxRaw = newResult.body[i].boxRaw.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + newBoxCoord) / bufferedFactor); const boxRaw = newResult.body[i].boxRaw.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + newBoxCoord) / bufferedFactor);
const keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({ const keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({
score: newKpt.score, score: newKpt.score,
@ -12445,14 +12384,14 @@ function calc2(newResult, config3) {
} }
annotations2[name] = pt; annotations2[name] = pt;
} }
bufferedResult.body[i] = { ...newResult.body[i], box: box4, boxRaw, keypoints, annotations: annotations2 }; bufferedResult.body[i] = { ...newResult.body[i], box: box5, boxRaw, keypoints, annotations: annotations2 };
} }
} }
if (!bufferedResult.hand || newResult.hand.length !== bufferedResult.hand.length) { if (!bufferedResult.hand || newResult.hand.length !== bufferedResult.hand.length) {
bufferedResult.hand = JSON.parse(JSON.stringify(newResult.hand)); bufferedResult.hand = JSON.parse(JSON.stringify(newResult.hand));
} else { } else {
for (let i = 0; i < newResult.hand.length; i++) { for (let i = 0; i < newResult.hand.length; i++) {
const box4 = newResult.hand[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].box[j] + b) / bufferedFactor); const box5 = newResult.hand[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].box[j] + b) / bufferedFactor);
const boxRaw = newResult.hand[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].boxRaw[j] + b) / bufferedFactor); const boxRaw = newResult.hand[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.hand[i].boxRaw[j] + b) / bufferedFactor);
if (bufferedResult.hand[i].keypoints.length !== newResult.hand[i].keypoints.length) if (bufferedResult.hand[i].keypoints.length !== newResult.hand[i].keypoints.length)
bufferedResult.hand[i].keypoints = newResult.hand[i].keypoints; bufferedResult.hand[i].keypoints = newResult.hand[i].keypoints;
@ -12466,14 +12405,14 @@ function calc2(newResult, config3) {
annotations2[key] = newResult.hand[i].annotations[key] && newResult.hand[i].annotations[key][0] ? newResult.hand[i].annotations[key].map((val, j) => val.map((coord, k) => ((bufferedFactor - 1) * bufferedResult.hand[i].annotations[key][j][k] + coord) / bufferedFactor)) : null; annotations2[key] = newResult.hand[i].annotations[key] && newResult.hand[i].annotations[key][0] ? newResult.hand[i].annotations[key].map((val, j) => val.map((coord, k) => ((bufferedFactor - 1) * bufferedResult.hand[i].annotations[key][j][k] + coord) / bufferedFactor)) : null;
} }
} }
bufferedResult.hand[i] = { ...newResult.hand[i], box: box4, boxRaw, keypoints, annotations: annotations2 }; bufferedResult.hand[i] = { ...newResult.hand[i], box: box5, boxRaw, keypoints, annotations: annotations2 };
} }
} }
if (!bufferedResult.face || newResult.face.length !== bufferedResult.face.length) { if (!bufferedResult.face || newResult.face.length !== bufferedResult.face.length) {
bufferedResult.face = JSON.parse(JSON.stringify(newResult.face)); bufferedResult.face = JSON.parse(JSON.stringify(newResult.face));
} else { } else {
for (let i = 0; i < newResult.face.length; i++) { for (let i = 0; i < newResult.face.length; i++) {
const box4 = newResult.face[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].box[j] + b) / bufferedFactor); const box5 = newResult.face[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].box[j] + b) / bufferedFactor);
const boxRaw = newResult.face[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].boxRaw[j] + b) / bufferedFactor); const boxRaw = newResult.face[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.face[i].boxRaw[j] + b) / bufferedFactor);
if (newResult.face[i].rotation) { if (newResult.face[i].rotation) {
const rotation = { matrix: [0, 0, 0, 0, 0, 0, 0, 0, 0], angle: { roll: 0, yaw: 0, pitch: 0 }, gaze: { bearing: 0, strength: 0 } }; const rotation = { matrix: [0, 0, 0, 0, 0, 0, 0, 0, 0], angle: { roll: 0, yaw: 0, pitch: 0 }, gaze: { bearing: 0, strength: 0 } };
@ -12487,18 +12426,18 @@ function calc2(newResult, config3) {
bearing: ((bufferedFactor - 1) * (((_u = (_t = bufferedResult.face[i].rotation) == null ? void 0 : _t.gaze) == null ? void 0 : _u.bearing) || 0) + (((_w = (_v = newResult.face[i].rotation) == null ? void 0 : _v.gaze) == null ? void 0 : _w.bearing) || 0)) / bufferedFactor, bearing: ((bufferedFactor - 1) * (((_u = (_t = bufferedResult.face[i].rotation) == null ? void 0 : _t.gaze) == null ? void 0 : _u.bearing) || 0) + (((_w = (_v = newResult.face[i].rotation) == null ? void 0 : _v.gaze) == null ? void 0 : _w.bearing) || 0)) / bufferedFactor,
strength: ((bufferedFactor - 1) * (((_y = (_x = bufferedResult.face[i].rotation) == null ? void 0 : _x.gaze) == null ? void 0 : _y.strength) || 0) + (((_A = (_z = newResult.face[i].rotation) == null ? void 0 : _z.gaze) == null ? void 0 : _A.strength) || 0)) / bufferedFactor strength: ((bufferedFactor - 1) * (((_y = (_x = bufferedResult.face[i].rotation) == null ? void 0 : _x.gaze) == null ? void 0 : _y.strength) || 0) + (((_A = (_z = newResult.face[i].rotation) == null ? void 0 : _z.gaze) == null ? void 0 : _A.strength) || 0)) / bufferedFactor
}; };
bufferedResult.face[i] = { ...newResult.face[i], rotation, box: box4, boxRaw }; bufferedResult.face[i] = { ...newResult.face[i], rotation, box: box5, boxRaw };
} }
bufferedResult.face[i] = { ...newResult.face[i], box: box4, boxRaw }; bufferedResult.face[i] = { ...newResult.face[i], box: box5, boxRaw };
} }
} }
if (!bufferedResult.object || newResult.object.length !== bufferedResult.object.length) { if (!bufferedResult.object || newResult.object.length !== bufferedResult.object.length) {
bufferedResult.object = JSON.parse(JSON.stringify(newResult.object)); bufferedResult.object = JSON.parse(JSON.stringify(newResult.object));
} else { } else {
for (let i = 0; i < newResult.object.length; i++) { for (let i = 0; i < newResult.object.length; i++) {
const box4 = newResult.object[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].box[j] + b) / bufferedFactor); const box5 = newResult.object[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].box[j] + b) / bufferedFactor);
const boxRaw = newResult.object[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].boxRaw[j] + b) / bufferedFactor); const boxRaw = newResult.object[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.object[i].boxRaw[j] + b) / bufferedFactor);
bufferedResult.object[i] = { ...newResult.object[i], box: box4, boxRaw }; bufferedResult.object[i] = { ...newResult.object[i], box: box5, boxRaw };
} }
} }
if (newResult.persons) { if (newResult.persons) {
@ -12507,7 +12446,7 @@ function calc2(newResult, config3) {
bufferedResult.persons = JSON.parse(JSON.stringify(newPersons)); bufferedResult.persons = JSON.parse(JSON.stringify(newPersons));
} else { } else {
for (let i = 0; i < newPersons.length; i++) { for (let i = 0; i < newPersons.length; i++) {
bufferedResult.persons[i].box = newPersons[i].box.map((box4, j) => ((bufferedFactor - 1) * bufferedResult.persons[i].box[j] + box4) / bufferedFactor); bufferedResult.persons[i].box = newPersons[i].box.map((box5, j) => ((bufferedFactor - 1) * bufferedResult.persons[i].box[j] + box5) / bufferedFactor);
} }
} }
} }
@ -12598,10 +12537,10 @@ function join2(faces, bodies, hands, gestures, shape) {
} }
const x = []; const x = [];
const y = []; const y = [];
const extractXY = (box4) => { const extractXY = (box5) => {
if (box4 && box4.length === 4) { if (box5 && box5.length === 4) {
x.push(box4[0], box4[0] + box4[2]); x.push(box5[0], box5[0] + box5[2]);
y.push(box4[1], box4[1] + box4[3]); y.push(box5[1], box5[1] + box5[3]);
} }
}; };
extractXY((_k = person2.face) == null ? void 0 : _k.box); extractXY((_k = person2.face) == null ? void 0 : _k.box);

117
dist/tfjs.esm.js vendored
View File

@ -4,7 +4,7 @@
author: <https://github.com/vladmandic>' author: <https://github.com/vladmandic>'
*/ */
// node_modules/.pnpm/github.com+vladmandic+tfjs@23eb80be7626f37f74b23351f804509a335f2a55/node_modules/@vladmandic/tfjs/dist/tfjs.esm.js // node_modules/.pnpm/github.com+vladmandic+tfjs@2127fce0dddf3d77d045441f26e892d4792418f4/node_modules/@vladmandic/tfjs/dist/tfjs.esm.js
var __create = Object.create; var __create = Object.create;
var __defProp = Object.defineProperty; var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@ -48697,19 +48697,20 @@ var PackProgram = class {
this.packedInputs = false; this.packedInputs = false;
this.packedOutput = true; this.packedOutput = true;
this.outputShape = outputShape; this.outputShape = outputShape;
const rank = outputShape.length; this.rank = outputShape.length;
if (rank === 0) { this.enableShapeUniforms = useShapeUniforms(this.outputShape.length);
if (this.rank === 0) {
this.userCode = ` this.userCode = `
void main() { void main() {
setOutput(vec4(getA(), 0., 0., 0.)); setOutput(vec4(getA(), 0., 0., 0.));
} }
`; `;
} else { } else {
const channels = getChannels("rc", rank); const channels = getChannels("rc", this.rank);
const dtype = getCoordsDataType(rank); const dtype = getCoordsDataType(this.rank);
const outOfBoundsCondition = getOutOfBoundsCondition(rank, outputShape, channels); const outOfBoundsCondition = this.getOutOfBoundsCondition(channels);
const setup46 = getSetup(rank, outputShape[outputShape.length - 1], outputShape[outputShape.length - 2], channels); const setup46 = this.getSetup(channels);
const output = getOutput(outputShape, channels); const output = this.getOutput(channels);
this.userCode = ` this.userCode = `
void main() { void main() {
${dtype} rc = getOutputCoords(); ${dtype} rc = getOutputCoords();
@ -48725,61 +48726,62 @@ var PackProgram = class {
`; `;
} }
} }
}; getSourceCoordsArr(dims) {
function getSourceCoordsArr(rank, dims) { const coords3 = [];
const coords3 = []; for (let row = 0; row <= 1; row++) {
for (let row = 0; row <= 1; row++) { for (let col = 0; col <= 1; col++) {
for (let col = 0; col <= 1; col++) { let coord = `${row === 0 ? "r" : "rp1"}, ${col === 0 ? "c" : "cp1"}`;
let coord = `${row === 0 ? "r" : "rp1"}, ${col === 0 ? "c" : "cp1"}`; for (let d = 2; d < this.rank; d++) {
for (let d = 2; d < rank; d++) { coord = `${dims[dims.length - 1 - d]},` + coord;
coord = `${dims[dims.length - 1 - d]},` + coord; }
coords3.push(coord);
} }
coords3.push(coord);
} }
return coords3;
} }
return coords3; getOutOfBoundsCondition(dims) {
} if (this.rank === 1) {
function getOutOfBoundsCondition(rank, shape, dims) { return `rc > ${this.enableShapeUniforms ? "outShape" : this.outputShape[0]}`;
if (rank === 1) {
return `rc > ${shape[0]}`;
}
let cond = "";
for (let i = rank - 2; i < rank; i++) {
cond += `${dims[i]} >= ${shape[i]}`;
if (i < rank - 1) {
cond += "||";
} }
let cond = "";
for (let i = this.rank - 2; i < this.rank; i++) {
cond += `${dims[i]} >= ${this.enableShapeUniforms ? `outShape[${i}]` : this.outputShape[i]}`;
if (i < this.rank - 1) {
cond += "||";
}
}
return cond;
} }
return cond; getSetup(dims) {
} if (this.rank === 1) {
function getSetup(rank, cols, rows, dims) { return "";
if (rank === 1) { }
return ""; const innerDims = dims.slice(-2);
} const col = this.enableShapeUniforms ? `outShape[${this.rank} - 1]` : this.outputShape[this.rank - 1];
const innerDims = dims.slice(-2); const row = this.enableShapeUniforms ? `outShape[${this.rank} - 2]` : this.outputShape[this.rank - 2];
return ` return `
int r = ${innerDims[0]}; int r = ${innerDims[0]};
int c = ${innerDims[1]}; int c = ${innerDims[1]};
int rp1 = r + 1; int rp1 = r + 1;
int cp1 = c + 1; int cp1 = c + 1;
bool cEdge = cp1 >= ${cols}; bool cEdge = cp1 >= ${col};
bool rEdge = rp1 >= ${rows}; bool rEdge = rp1 >= ${row};
`; `;
}
function getOutput(shape, dims) {
const rank = shape.length;
const sourceCoords = getSourceCoordsArr(rank, dims);
if (rank === 1) {
return `getA(rc),
rc + 1 >= ${shape[0]} ? 0. : getA(rc + 1),
0, 0`;
} }
return `getA(${sourceCoords[0]}), getOutput(dims) {
cEdge ? 0. : getA(${sourceCoords[1]}), const sourceCoords = this.getSourceCoordsArr(dims);
rEdge ? 0. : getA(${sourceCoords[2]}), if (this.rank === 1) {
rEdge || cEdge ? 0. : getA(${sourceCoords[3]})`; return `getA(rc),
} rc + 1 >= ${this.enableShapeUniforms ? "outShape" : this.outputShape[0]} ? 0. : getA(rc + 1),
0, 0`;
}
return `getA(${sourceCoords[0]}),
cEdge ? 0. : getA(${sourceCoords[1]}),
rEdge ? 0. : getA(${sourceCoords[2]}),
rEdge || cEdge ? 0. : getA(${sourceCoords[3]})`;
}
};
var ReshapePackedProgram = class { var ReshapePackedProgram = class {
constructor(outputShape, inputShape) { constructor(outputShape, inputShape) {
this.variableNames = ["A"]; this.variableNames = ["A"];
@ -49122,6 +49124,7 @@ var UnpackProgram = class {
this.packedInputs = true; this.packedInputs = true;
this.packedOutput = false; this.packedOutput = false;
this.outputShape = outputShape; this.outputShape = outputShape;
this.enableShapeUniforms = useShapeUniforms(this.outputShape.length);
const rank = outputShape.length; const rank = outputShape.length;
const channels = getChannels("rc", rank); const channels = getChannels("rc", rank);
const dtype = getCoordsDataType(rank); const dtype = getCoordsDataType(rank);
@ -69967,7 +69970,7 @@ registerBackend("wasm", async () => {
const { wasm } = await init(); const { wasm } = await init();
return new BackendWasm(wasm); return new BackendWasm(wasm);
}, WASM_PRIORITY); }, WASM_PRIORITY);
var externalVersion = "3.11.0-20211123"; var externalVersion = "3.11.0-20211124";
var version8 = { var version8 = {
tfjs: externalVersion, tfjs: externalVersion,
"tfjs-core": externalVersion, "tfjs-core": externalVersion,

View File

@ -65,7 +65,7 @@
"@tensorflow/tfjs-layers": "^3.11.0", "@tensorflow/tfjs-layers": "^3.11.0",
"@tensorflow/tfjs-node": "^3.11.0", "@tensorflow/tfjs-node": "^3.11.0",
"@tensorflow/tfjs-node-gpu": "^3.11.0", "@tensorflow/tfjs-node-gpu": "^3.11.0",
"@types/node": "^16.11.9", "@types/node": "^16.11.10",
"@types/offscreencanvas": "^2019.6.4", "@types/offscreencanvas": "^2019.6.4",
"@typescript-eslint/eslint-plugin": "^5.4.0", "@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0", "@typescript-eslint/parser": "^5.4.0",

View File

@ -10,8 +10,7 @@ import type { GraphModel, Tensor } from '../tfjs/types';
import type { Config } from '../config'; import type { Config } from '../config';
import * as coords from './blazeposecoords'; import * as coords from './blazeposecoords';
import * as detect from './blazeposedetector'; import * as detect from './blazeposedetector';
import * as box from '../util/box';
interface DetectedBox { box: Box, boxRaw: Box, score: number }
const env = { initial: true }; const env = { initial: true };
// const models: [GraphModel | null, GraphModel | null] = [null, null]; // const models: [GraphModel | null, GraphModel | null] = [null, null];
@ -24,7 +23,7 @@ const outputNodes: { detector: string[], landmarks: string[] } = {
}; };
let cache: BodyResult | null = null; let cache: BodyResult | null = null;
let lastBox: Box | undefined; let cropBox: Box | undefined;
let padding: [number, number][] = [[0, 0], [0, 0], [0, 0], [0, 0]]; let padding: [number, number][] = [[0, 0], [0, 0], [0, 0], [0, 0]];
let lastTime = 0; let lastTime = 0;
@ -63,50 +62,43 @@ export async function load(config: Config): Promise<[GraphModel | null, GraphMod
return [models.detector, models.landmarks]; return [models.detector, models.landmarks];
} }
function calculateBoxes(keypoints: Array<BodyKeypoint>, outputSize: [number, number]): { keypointsBox: Box, keypointsBoxRaw: Box } { async function prepareImage(input: Tensor, size: number): Promise<Tensor> {
const x = keypoints.map((a) => a.position[0]);
const y = keypoints.map((a) => a.position[1]);
const keypointsBox: Box = [Math.min(...x), Math.min(...y), Math.max(...x) - Math.min(...x), Math.max(...y) - Math.min(...y)];
const keypointsBoxRaw: Box = [keypointsBox[0] / outputSize[0], keypointsBox[1] / outputSize[1], keypointsBox[2] / outputSize[0], keypointsBox[3] / outputSize[1]];
return { keypointsBox, keypointsBoxRaw };
}
async function prepareImage(input: Tensor, size: number, box?: Box): Promise<Tensor> {
const t: Record<string, Tensor> = {}; const t: Record<string, Tensor> = {};
if (!input.shape || !input.shape[1] || !input.shape[2]) return input; if (!input.shape || !input.shape[1] || !input.shape[2]) return input;
let final: Tensor; let final: Tensor;
if (cropBox) {
t.cropped = tf.image.cropAndResize(input, [cropBox], [0], [input.shape[1], input.shape[2]]); // if we have cached box use it to crop input
}
if (input.shape[1] !== input.shape[2]) { // only pad if width different than height if (input.shape[1] !== input.shape[2]) { // only pad if width different than height
const height: [number, number] = box const height: [number, number] = [
? [Math.trunc(input.shape[1] * box[1]), Math.trunc(input.shape[1] * (box[1] + box[3]))] input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0,
: [input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0, input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0]; input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0,
const width: [number, number] = box ];
? [Math.trunc(input.shape[2] * box[0]), Math.trunc(input.shape[2] * (box[0] + box[2]))] const width: [number, number] = [
: [input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0, input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0]; input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0,
input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0,
];
padding = [ padding = [
[0, 0], // dont touch batch [0, 0], // dont touch batch
height, // height before&after height, // height before&after
width, // width before&after width, // width before&after
[0, 0], // dont touch rbg [0, 0], // dont touch rbg
]; ];
if (box) { t.pad = tf.pad(t.cropped || input, padding); // use cropped box if it exists
t.resize = tf.image.cropAndResize(input, [box], [0], [size, size]); t.resize = tf.image.resizeBilinear(t.pad, [size, size]);
} else {
t.pad = tf.pad(input, padding);
t.resize = tf.image.resizeBilinear(t.pad, [size, size]);
}
final = tf.div(t.resize, constants.tf255); final = tf.div(t.resize, constants.tf255);
} else if (input.shape[1] !== size) { // if input needs resizing } else if (input.shape[1] !== size) { // if input needs resizing
t.resize = tf.image.resizeBilinear(input, [size, size]); t.resize = tf.image.resizeBilinear(t.cropped || input, [size, size]);
final = tf.div(t.resize, constants.tf255); final = tf.div(t.resize, constants.tf255);
} else { // if input is already in a correct resolution just normalize it } else { // if input is already in a correct resolution just normalize it
final = tf.div(input, constants.tf255); final = tf.div(t.cropped || input, constants.tf255);
} }
Object.keys(t).forEach((tensor) => tf.dispose(t[tensor])); Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));
return final; return final;
} }
function rescaleKeypoints(keypoints: Array<BodyKeypoint>, outputSize: [number, number]): Array<BodyKeypoint> { function rescaleKeypoints(keypoints: Array<BodyKeypoint>, outputSize: [number, number]): Array<BodyKeypoint> {
for (const kpt of keypoints) { for (const kpt of keypoints) { // first rescale due to padding
kpt.position = [ kpt.position = [
Math.trunc(kpt.position[0] * (outputSize[0] + padding[2][0] + padding[2][1]) / outputSize[0] - padding[2][0]), Math.trunc(kpt.position[0] * (outputSize[0] + padding[2][0] + padding[2][1]) / outputSize[0] - padding[2][0]),
Math.trunc(kpt.position[1] * (outputSize[1] + padding[1][0] + padding[1][1]) / outputSize[1] - padding[1][0]), Math.trunc(kpt.position[1] * (outputSize[1] + padding[1][0] + padding[1][1]) / outputSize[1] - padding[1][0]),
@ -114,20 +106,21 @@ function rescaleKeypoints(keypoints: Array<BodyKeypoint>, outputSize: [number, n
]; ];
kpt.positionRaw = [kpt.position[0] / outputSize[0], kpt.position[1] / outputSize[1], kpt.position[2] as number]; kpt.positionRaw = [kpt.position[0] / outputSize[0], kpt.position[1] / outputSize[1], kpt.position[2] as number];
} }
return keypoints; if (cropBox) { // second rescale due to cropping
} for (const kpt of keypoints) {
kpt.positionRaw = [
function rescaleBoxes(boxes: Array<DetectedBox>, outputSize: [number, number]): Array<DetectedBox> { kpt.positionRaw[0] + cropBox[1], // correct offset due to crop
for (const box of boxes) { kpt.positionRaw[1] + cropBox[0], // correct offset due to crop
box.box = [ kpt.positionRaw[2] as number,
Math.trunc(box.box[0] * (outputSize[0] + padding[2][0] + padding[2][1]) / outputSize[0]), ];
Math.trunc(box.box[1] * (outputSize[1] + padding[1][0] + padding[1][1]) / outputSize[1]), kpt.position = [
Math.trunc(box.box[2] * (outputSize[0] + padding[2][0] + padding[2][1]) / outputSize[0]), Math.trunc(kpt.positionRaw[0] * outputSize[0]),
Math.trunc(box.box[3] * (outputSize[1] + padding[1][0] + padding[1][1]) / outputSize[1]), Math.trunc(kpt.positionRaw[1] * outputSize[1]),
]; kpt.positionRaw[2] as number,
box.boxRaw = [box.box[0] / outputSize[0], box.box[1] / outputSize[1], box.box[2] / outputSize[0], box.box[3] / outputSize[1]]; ];
}
} }
return boxes; return keypoints;
} }
async function detectLandmarks(input: Tensor, config: Config, outputSize: [number, number]): Promise<BodyResult | null> { async function detectLandmarks(input: Tensor, config: Config, outputSize: [number, number]): Promise<BodyResult | null> {
@ -155,22 +148,38 @@ async function detectLandmarks(input: Tensor, config: Config, outputSize: [numbe
} }
if (poseScore < (config.body.minConfidence || 0)) return null; if (poseScore < (config.body.minConfidence || 0)) return null;
const keypoints: Array<BodyKeypoint> = rescaleKeypoints(keypointsRelative, outputSize); // keypoints were relative to input image which is padded const keypoints: Array<BodyKeypoint> = rescaleKeypoints(keypointsRelative, outputSize); // keypoints were relative to input image which is padded
const boxes = calculateBoxes(keypoints, [outputSize[0], outputSize[1]]); // now find boxes based on rescaled keypoints const kpts = keypoints.map((k) => k.position);
const boxes = box.calc(kpts, [outputSize[0], outputSize[1]]); // now find boxes based on rescaled keypoints
const annotations: Record<string, Point[][]> = {}; const annotations: Record<string, Point[][]> = {};
for (const [name, indexes] of Object.entries(coords.connected)) { for (const [name, indexes] of Object.entries(coords.connected)) {
const pt: Array<Point[]> = []; const pt: Array<Point[]> = [];
for (let i = 0; i < indexes.length - 1; i++) { for (let i = 0; i < indexes.length - 1; i++) {
const pt0 = keypoints.find((kpt) => kpt.part === indexes[i]); const pt0 = keypoints.find((kpt) => kpt.part === indexes[i]);
const pt1 = keypoints.find((kpt) => kpt.part === indexes[i + 1]); const pt1 = keypoints.find((kpt) => kpt.part === indexes[i + 1]);
// if (pt0 && pt1 && pt0.score > (config.body.minConfidence || 0) && pt1.score > (config.body.minConfidence || 0)) pt.push([pt0.position, pt1.position]);
if (pt0 && pt1) pt.push([pt0.position, pt1.position]); if (pt0 && pt1) pt.push([pt0.position, pt1.position]);
} }
annotations[name] = pt; annotations[name] = pt;
} }
const body = { id: 0, score: Math.trunc(100 * poseScore) / 100, box: boxes.keypointsBox, boxRaw: boxes.keypointsBoxRaw, keypoints, annotations }; const body = { id: 0, score: Math.trunc(100 * poseScore) / 100, box: boxes.box, boxRaw: boxes.boxRaw, keypoints, annotations };
return body; return body;
} }
/*
interface DetectedBox { box: Box, boxRaw: Box, score: number }
function rescaleBoxes(boxes: Array<DetectedBox>, outputSize: [number, number]): Array<DetectedBox> {
for (const b of boxes) {
b.box = [
Math.trunc(b.box[0] * (outputSize[0] + padding[2][0] + padding[2][1]) / outputSize[0]),
Math.trunc(b.box[1] * (outputSize[1] + padding[1][0] + padding[1][1]) / outputSize[1]),
Math.trunc(b.box[2] * (outputSize[0] + padding[2][0] + padding[2][1]) / outputSize[0]),
Math.trunc(b.box[3] * (outputSize[1] + padding[1][0] + padding[1][1]) / outputSize[1]),
];
b.boxRaw = [b.box[0] / outputSize[0], b.box[1] / outputSize[1], b.box[2] / outputSize[0], b.box[3] / outputSize[1]];
}
return boxes;
}
async function detectBoxes(input: Tensor, config: Config, outputSize: [number, number]) { async function detectBoxes(input: Tensor, config: Config, outputSize: [number, number]) {
const t: Record<string, Tensor> = {}; const t: Record<string, Tensor> = {};
t.res = models.detector?.execute(input, ['Identity']) as Tensor; // t.res = models.detector?.execute(input, ['Identity']) as Tensor; //
@ -183,6 +192,7 @@ async function detectBoxes(input: Tensor, config: Config, outputSize: [number, n
Object.keys(t).forEach((tensor) => tf.dispose(t[tensor])); Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));
return boxes; return boxes;
} }
*/
export async function predict(input: Tensor, config: Config): Promise<BodyResult[]> { export async function predict(input: Tensor, config: Config): Promise<BodyResult[]> {
const outputSize: [number, number] = [input.shape[2] || 0, input.shape[1] || 0]; const outputSize: [number, number] = [input.shape[2] || 0, input.shape[1] || 0];
@ -192,33 +202,31 @@ export async function predict(input: Tensor, config: Config): Promise<BodyResult
skipped++; skipped++;
} else { } else {
const t: Record<string, Tensor> = {}; const t: Record<string, Tensor> = {};
/*
if (config.body['detector'] && config.body['detector']['enabled']) { if (config.body['detector'] && config.body['detector']['enabled']) {
t.detector = await prepareImage(input, 224); t.detector = await prepareImage(input, 224);
const boxes = await detectBoxes(t.detector, config, outputSize); const boxes = await detectBoxes(t.detector, config, outputSize);
if (boxes && boxes.length === 1) {
t.landmarks = await prepareImage(input, 256, boxes[0].box); // padded and resized according to detector
cache = await detectLandmarks(t.landmarks, config, outputSize);
}
if (cache) cache.score = boxes[0].score;
} else {
t.landmarks = await prepareImage(input, 256, lastBox); // padded and resized
cache = await detectLandmarks(t.landmarks, config, outputSize);
/*
lastBox = undefined;
if (cache?.box) {
const cx = cache.boxRaw[0] + (cache.boxRaw[2] / 2);
const cy = cache.boxRaw[1] + (cache.boxRaw[3] / 2);
let size = cache.boxRaw[2] > cache.boxRaw[3] ? cache.boxRaw[2] : cache.boxRaw[3];
size = (size * 1.2) / 2; // enlarge and half it
lastBox = [cx - size, cy - size, 2 * size, 2 * size];
}
*/
} }
*/
t.landmarks = await prepareImage(input, 256); // padded and resized
cache = await detectLandmarks(t.landmarks, config, outputSize);
/*
cropBox = [0, 0, 1, 1]; // reset crop coordinates
if (cache?.boxRaw && config.skipAllowed) {
const cx = (2.0 * cache.boxRaw[0] + cache.boxRaw[2]) / 2;
const cy = (2.0 * cache.boxRaw[1] + cache.boxRaw[3]) / 2;
let size = cache.boxRaw[2] > cache.boxRaw[3] ? cache.boxRaw[2] : cache.boxRaw[3];
size = (size * 1.0) / 2; // enlarge and half it
if (cx > 0.1 && cx < 0.9 && cy > 0.1 && cy < 0.9 && size > 0.1) { // only update if box is sane
const y = 0; // cy - size;
const x = cx - size;
cropBox = [y, x, y + 1, x + 1]; // [y0,x0,y1,x1] used for cropping but width/height are not yet implemented so we only reposition image to center of body
}
}
*/
Object.keys(t).forEach((tensor) => tf.dispose(t[tensor])); Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));
// if (cache && boxes.length > 0) cache.box = boxes[0].box;
lastTime = now(); lastTime = now();
skipped = 0; skipped = 0;
} }
if (cache) return [cache]; return cache ? [cache] : [];
return [];
} }

View File

@ -78,7 +78,7 @@ export const calculateFaceAngle = (face, imageSize): {
if (isNaN(thetaX)) thetaX = 0; if (isNaN(thetaX)) thetaX = 0;
if (isNaN(thetaY)) thetaY = 0; if (isNaN(thetaY)) thetaY = 0;
if (isNaN(thetaZ)) thetaZ = 0; if (isNaN(thetaZ)) thetaZ = 0;
return { pitch: 2 * -thetaX, yaw: 2 * -thetaY, roll: 2 * -thetaZ }; return { pitch: -thetaX, yaw: -thetaY, roll: -thetaZ };
}; };
// simple Euler angle calculation based existing 3D mesh // simple Euler angle calculation based existing 3D mesh
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars

View File

@ -51,11 +51,11 @@ const cache: {
}; };
const fingerMap = { const fingerMap = {
thumb: [1, 2, 3, 4], thumb: [0, 1, 2, 3, 4],
index: [5, 6, 7, 8], index: [0, 5, 6, 7, 8],
middle: [9, 10, 11, 12], middle: [0, 9, 10, 11, 12],
ring: [13, 14, 15, 16], ring: [0, 13, 14, 15, 16],
pinky: [17, 18, 19, 20], pinky: [0, 17, 18, 19, 20],
palm: [0], palm: [0],
}; };

View File

@ -1,25 +1,25 @@
2021-11-23 10:21:50 INFO:  Application: {"name":"@vladmandic/human","version":"2.5.4"} 2021-11-24 16:12:45 INFO:  Application: {"name":"@vladmandic/human","version":"2.5.4"}
2021-11-23 10:21:50 INFO:  Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true} 2021-11-24 16:12:45 INFO:  Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
2021-11-23 10:21:50 INFO:  Toolchain: {"build":"0.6.4","esbuild":"0.13.15","typescript":"4.5.2","typedoc":"0.22.9","eslint":"8.3.0"} 2021-11-24 16:12:45 INFO:  Toolchain: {"build":"0.6.4","esbuild":"0.13.15","typescript":"4.5.2","typedoc":"0.22.9","eslint":"8.3.0"}
2021-11-23 10:21:50 INFO:  Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]} 2021-11-24 16:12:45 INFO:  Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
2021-11-23 10:21:50 STATE: Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]} 2021-11-24 16:12:45 STATE: Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]}
2021-11-23 10:21:50 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-24 16:12:45 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-23 10:21:50 STATE: Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":63,"inputBytes":556638,"outputBytes":468195} 2021-11-24 16:12:45 STATE: Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":63,"inputBytes":556369,"outputBytes":464672}
2021-11-23 10:21:50 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-24 16:12:45 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-23 10:21:50 STATE: Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":63,"inputBytes":556646,"outputBytes":468199} 2021-11-24 16:12:45 STATE: Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":63,"inputBytes":556377,"outputBytes":464676}
2021-11-23 10:21:50 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-24 16:12:45 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-23 10:21:50 STATE: Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":63,"inputBytes":556713,"outputBytes":468271} 2021-11-24 16:12:45 STATE: Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":63,"inputBytes":556444,"outputBytes":464748}
2021-11-23 10:21:50 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-24 16:12:45 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-23 10:21:50 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-24 16:12:45 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-23 10:21:50 STATE: Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":63,"inputBytes":556275,"outputBytes":470281} 2021-11-24 16:12:45 STATE: Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":63,"inputBytes":556006,"outputBytes":466434}
2021-11-23 10:21:51 STATE: 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":2500868} 2021-11-24 16:12:46 STATE: 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":2501333}
2021-11-23 10:21:51 STATE: Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":63,"inputBytes":3056231,"outputBytes":1627483} 2021-11-24 16:12:46 STATE: Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":63,"inputBytes":3056427,"outputBytes":1626393}
2021-11-23 10:21:51 STATE: Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":63,"inputBytes":3056231,"outputBytes":2977445} 2021-11-24 16:12:47 STATE: Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":63,"inputBytes":3056427,"outputBytes":2974514}
2021-11-23 10:22:12 STATE: Typings: {"input":"src/human.ts","output":"types/lib","files":110} 2021-11-24 16:13:08 STATE: Typings: {"input":"src/human.ts","output":"types/lib","files":110}
2021-11-23 10:22:12 WARN:  You are running with an unsupported TypeScript version! TypeDoc supports 4.0, 4.1, 4.2, 4.3, 4.4 2021-11-24 16:13:08 WARN:  You are running with an unsupported TypeScript version! TypeDoc supports 4.0, 4.1, 4.2, 4.3, 4.4
2021-11-23 10:22:20 STATE: TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":52,"generated":true} 2021-11-24 16:13:16 STATE: TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":52,"generated":true}
2021-11-23 10:22:20 STATE: Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":5866,"outputBytes":4127} 2021-11-24 16:13:16 STATE: Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":5864,"outputBytes":4127}
2021-11-23 10:22:20 STATE: Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15174,"outputBytes":11794} 2021-11-24 16:13:16 STATE: Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15174,"outputBytes":11794}
2021-11-23 10:23:03 STATE: Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":94,"errors":0,"warnings":0} 2021-11-24 16:13:55 STATE: Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":94,"errors":0,"warnings":0}
2021-11-23 10:23:04 STATE: ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"} 2021-11-24 16:13:55 STATE: ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
2021-11-23 10:23:04 INFO:  Done... 2021-11-24 16:13:55 INFO:  Done...

File diff suppressed because it is too large Load Diff