mirror of https://github.com/vladmandic/human
update blazepose and extend hand annotations
parent
db6fe46741
commit
8050f5ed99
|
@ -11,14 +11,13 @@
|
|||
|
||||
### **HEAD -> main** 2021/11/23 mandic00@live.com
|
||||
|
||||
- fix face box scaling on detection
|
||||
- cleanup
|
||||
|
||||
### **2.5.4** 2021/11/22 mandic00@live.com
|
||||
|
||||
- prototype blazepose detector
|
||||
|
||||
### **origin/main** 2021/11/21 mandic00@live.com
|
||||
|
||||
- minor fixes
|
||||
- add body 3d interpolation
|
||||
- edit blazepose keypoints
|
||||
- new build process
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -10,7 +10,7 @@
|
|||
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
|
||||
// backend: 'webgpu' as 'webgpu,
|
||||
// backend: 'webgpu' as const,
|
||||
// async: true,
|
||||
modelBasePath: '../../models',
|
||||
filter: { enabled: true, equalization: false },
|
||||
|
|
|
@ -963,8 +963,8 @@ function GLImageFilter() {
|
|||
|
||||
// src/image/enhance.ts
|
||||
async function histogramEqualization(inputImage) {
|
||||
const squeeze11 = inputImage.shape.length === 4 ? tfjs_esm_exports.squeeze(inputImage) : inputImage;
|
||||
const channels = tfjs_esm_exports.split(squeeze11, 3, 2);
|
||||
const squeeze10 = inputImage.shape.length === 4 ? tfjs_esm_exports.squeeze(inputImage) : inputImage;
|
||||
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 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()));
|
||||
|
@ -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 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 reshape8 = tfjs_esm_exports.reshape(rgb2, [1, squeeze11.shape[0], squeeze11.shape[1], 3]);
|
||||
tfjs_esm_exports.dispose([...channels, ...min2, ...max4, ...sub10, ...range, ...fact, ...enh, rgb2, squeeze11]);
|
||||
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, squeeze10]);
|
||||
return reshape8;
|
||||
}
|
||||
|
||||
|
@ -1390,8 +1390,8 @@ async function predict(image29, config3, idx, count2) {
|
|||
if (!(model == null ? void 0 : model.inputs[0].shape))
|
||||
return;
|
||||
const t = {};
|
||||
const box4 = [[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]]);
|
||||
const box5 = [[0, 0.1, 0.9, 0.9]];
|
||||
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: [] };
|
||||
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"]);
|
||||
|
@ -4875,44 +4875,44 @@ var UV33 = VTX33.map((x) => UV468[x]);
|
|||
var UV7 = VTX7.map((x) => UV468[x]);
|
||||
|
||||
// src/face/facemeshutil.ts
|
||||
var getBoxSize = (box4) => [Math.abs(box4.endPoint[0] - box4.startPoint[0]), Math.abs(box4.endPoint[1] - box4.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 getClampedBox = (box4, input) => box4 ? [
|
||||
Math.trunc(Math.max(0, box4.startPoint[0])),
|
||||
Math.trunc(Math.max(0, box4.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[1] || 0, box4.endPoint[1]) - Math.max(0, box4.startPoint[1]))
|
||||
var getBoxSize = (box5) => [Math.abs(box5.endPoint[0] - box5.startPoint[0]), Math.abs(box5.endPoint[1] - box5.startPoint[1])];
|
||||
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 = (box5, input) => box5 ? [
|
||||
Math.trunc(Math.max(0, box5.startPoint[0])),
|
||||
Math.trunc(Math.max(0, box5.startPoint[1])),
|
||||
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, box5.endPoint[1]) - Math.max(0, box5.startPoint[1]))
|
||||
] : [0, 0, 0, 0];
|
||||
var getRawBox = (box4, input) => box4 ? [
|
||||
box4.startPoint[0] / (input.shape[2] || 0),
|
||||
box4.startPoint[1] / (input.shape[1] || 0),
|
||||
(box4.endPoint[0] - box4.startPoint[0]) / (input.shape[2] || 0),
|
||||
(box4.endPoint[1] - box4.startPoint[1]) / (input.shape[1] || 0)
|
||||
var getRawBox = (box5, input) => box5 ? [
|
||||
box5.startPoint[0] / (input.shape[2] || 0),
|
||||
box5.startPoint[1] / (input.shape[1] || 0),
|
||||
(box5.endPoint[0] - box5.startPoint[0]) / (input.shape[2] || 0),
|
||||
(box5.endPoint[1] - box5.startPoint[1]) / (input.shape[1] || 0)
|
||||
] : [0, 0, 0, 0];
|
||||
var scaleBoxCoordinates = (box4, factor) => {
|
||||
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]];
|
||||
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]];
|
||||
return { startPoint, endPoint, landmarks: box4.landmarks, confidence: box4.confidence };
|
||||
var scaleBoxCoordinates = (box5, factor) => {
|
||||
const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
|
||||
const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
|
||||
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 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);
|
||||
tfjs_esm_exports.dispose(crop2);
|
||||
return norm;
|
||||
};
|
||||
var enlargeBox = (box4, factor) => {
|
||||
const center = getBoxCenter(box4);
|
||||
const size2 = getBoxSize(box4);
|
||||
var enlargeBox = (box5, factor) => {
|
||||
const center = getBoxCenter(box5);
|
||||
const size2 = getBoxSize(box5);
|
||||
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) => {
|
||||
const centers = getBoxCenter(box4);
|
||||
const size2 = getBoxSize(box4);
|
||||
var squarifyBox = (box5) => {
|
||||
const centers = getBoxCenter(box5);
|
||||
const size2 = getBoxSize(box5);
|
||||
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) => {
|
||||
const xs = landmarks.map((d) => d[0]);
|
||||
|
@ -4980,8 +4980,8 @@ function generateAnchors(inputSize9) {
|
|||
}
|
||||
return anchors4;
|
||||
}
|
||||
function transformRawCoords(coordsRaw, box4, angle, rotationMatrix, inputSize9) {
|
||||
const boxSize = getBoxSize(box4);
|
||||
function transformRawCoords(coordsRaw, box5, angle, rotationMatrix, inputSize9) {
|
||||
const boxSize = getBoxSize(box5);
|
||||
const coordsScaled = coordsRaw.map((coord) => [
|
||||
boxSize[0] / inputSize9 * (coord[0] - 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 coordsRotated = largeAngle ? coordsScaled.map((coord) => [...rotatePoint(coord, coordsRotationMatrix), coord[2]]) : coordsScaled;
|
||||
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) => [
|
||||
Math.round(coord[0] + dot(boxCenter, inverseRotationMatrix[0])),
|
||||
Math.round(coord[1] + dot(boxCenter, inverseRotationMatrix[1])),
|
||||
Math.round(coord[2] || 0)
|
||||
]);
|
||||
}
|
||||
function correctFaceRotation(rotate, box4, input, inputSize9) {
|
||||
const symmetryLine = box4.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine;
|
||||
function correctFaceRotation(rotate, box5, input, inputSize9) {
|
||||
const symmetryLine = box5.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine;
|
||||
let angle = 0;
|
||||
let rotationMatrix = fixedRotationMatrix;
|
||||
let face5;
|
||||
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;
|
||||
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 rotated = tfjs_esm_exports.image.rotateWithOffset(input, angle, 0, centerRaw);
|
||||
rotationMatrix = buildRotationMatrix(-angle, center);
|
||||
face5 = cutBoxFromImageAndResize(box4, rotated, [inputSize9, inputSize9]);
|
||||
face5 = cutBoxFromImageAndResize(box5, rotated, [inputSize9, inputSize9]);
|
||||
tfjs_esm_exports.dispose(rotated);
|
||||
} else {
|
||||
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]);
|
||||
face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
|
||||
}
|
||||
} else {
|
||||
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]);
|
||||
face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
|
||||
}
|
||||
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)) };
|
||||
}
|
||||
var cropFactor = [5, 5];
|
||||
function decodeBoxes(boxesTensor, anchor) {
|
||||
return tfjs_esm_exports.tidy(() => {
|
||||
const split5 = tfjs_esm_exports.split(boxesTensor, 12, 1);
|
||||
let xCenter = tfjs_esm_exports.squeeze(split5[0]);
|
||||
let yCenter = tfjs_esm_exports.squeeze(split5[1]);
|
||||
let width = tfjs_esm_exports.squeeze(split5[2]);
|
||||
let height = tfjs_esm_exports.squeeze(split5[3]);
|
||||
xCenter = tfjs_esm_exports.add(tfjs_esm_exports.div(xCenter, inputSize2), anchor.x);
|
||||
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;
|
||||
});
|
||||
|
||||
// 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 box5 = [min2[0], min2[1], max4[0] - min2[0], max4[1] - min2[1]];
|
||||
const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
|
||||
return { box: box5, boxRaw };
|
||||
}
|
||||
async function decode(boxesTensor, logitsTensor, config3, outputSize2) {
|
||||
const t = {};
|
||||
t.boxes = decodeBoxes(boxesTensor, anchorTensor);
|
||||
t.scores = tfjs_esm_exports.sigmoid(logitsTensor);
|
||||
t.argmax = tfjs_esm_exports.argMax(t.scores);
|
||||
const i = (await t.argmax.data())[0];
|
||||
const scores = await t.scores.data();
|
||||
const detected = [];
|
||||
const minScore = config3.body["detector"] && config3.body["detector"]["minConfidence"] ? config3.body["detector"]["minConfidence"] : 0;
|
||||
if (scores[i] >= minScore) {
|
||||
const boxes = await t.boxes.array();
|
||||
const boxRaw = boxes[i];
|
||||
const box4 = [boxRaw[0] * outputSize2[0], boxRaw[1] * outputSize2[1], boxRaw[2] * outputSize2[0], boxRaw[3] * outputSize2[1]];
|
||||
detected.push({ box: box4, boxRaw, score: scores[i] });
|
||||
}
|
||||
Object.keys(t).forEach((tensor3) => tfjs_esm_exports.dispose(t[tensor3]));
|
||||
return detected;
|
||||
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 box5 = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];
|
||||
const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
|
||||
return { box: box5, boxRaw };
|
||||
}
|
||||
function scale(box5, scaleFact) {
|
||||
const dist = [box5[2] * scaleFact, box5[3] * scaleFact];
|
||||
const newBox = [
|
||||
box5[0] - (dist[0] - box5[2]) / 2,
|
||||
box5[1] - (dist[1] - box5[3]) / 2,
|
||||
dist[0],
|
||||
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
|
||||
|
@ -5245,7 +5243,7 @@ var outputNodes = {
|
|||
detector: []
|
||||
};
|
||||
var cache = null;
|
||||
var lastBox;
|
||||
var cropBox;
|
||||
var padding = [[0, 0], [0, 0], [0, 0], [0, 0]];
|
||||
var lastTime5 = 0;
|
||||
var sigmoid3 = (x) => 1 - 1 / (1 + Math.exp(x));
|
||||
|
@ -5282,39 +5280,37 @@ async function loadPose(config3) {
|
|||
log("cached model:", models.landmarks["modelUrl"]);
|
||||
return models.landmarks;
|
||||
}
|
||||
function calculateBoxes(keypoints, outputSize2) {
|
||||
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) {
|
||||
async function prepareImage(input, size2) {
|
||||
const t = {};
|
||||
if (!input.shape || !input.shape[1] || !input.shape[2])
|
||||
return input;
|
||||
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]) {
|
||||
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 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];
|
||||
const height = [
|
||||
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 = [
|
||||
[0, 0],
|
||||
height,
|
||||
width,
|
||||
[0, 0]
|
||||
];
|
||||
if (box4) {
|
||||
t.resize = tfjs_esm_exports.image.cropAndResize(input, [box4], [0], [size2, size2]);
|
||||
} else {
|
||||
t.pad = tfjs_esm_exports.pad(input, padding);
|
||||
t.resize = tfjs_esm_exports.image.resizeBilinear(t.pad, [size2, size2]);
|
||||
}
|
||||
t.pad = tfjs_esm_exports.pad(t.cropped || input, padding);
|
||||
t.resize = tfjs_esm_exports.image.resizeBilinear(t.pad, [size2, size2]);
|
||||
final = tfjs_esm_exports.div(t.resize, constants.tf255);
|
||||
} 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);
|
||||
} 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]));
|
||||
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]];
|
||||
}
|
||||
return keypoints;
|
||||
}
|
||||
function rescaleBoxes(boxes, outputSize2) {
|
||||
for (const box4 of boxes) {
|
||||
box4.box = [
|
||||
Math.trunc(box4.box[0] * (outputSize2[0] + padding[2][0] + padding[2][1]) / outputSize2[0]),
|
||||
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]),
|
||||
Math.trunc(box4.box[3] * (outputSize2[1] + padding[1][0] + padding[1][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]];
|
||||
if (cropBox) {
|
||||
for (const kpt4 of keypoints) {
|
||||
kpt4.positionRaw = [
|
||||
kpt4.positionRaw[0] + cropBox[1],
|
||||
kpt4.positionRaw[1] + cropBox[0],
|
||||
kpt4.positionRaw[2]
|
||||
];
|
||||
kpt4.position = [
|
||||
Math.trunc(kpt4.positionRaw[0] * outputSize2[0]),
|
||||
Math.trunc(kpt4.positionRaw[1] * outputSize2[1]),
|
||||
kpt4.positionRaw[2]
|
||||
];
|
||||
}
|
||||
}
|
||||
return boxes;
|
||||
return keypoints;
|
||||
}
|
||||
async function detectLandmarks(input, config3, outputSize2) {
|
||||
var _a;
|
||||
|
@ -5362,7 +5360,8 @@ async function detectLandmarks(input, config3, outputSize2) {
|
|||
if (poseScore < (config3.body.minConfidence || 0))
|
||||
return null;
|
||||
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 = {};
|
||||
for (const [name, indexes] of Object.entries(connected)) {
|
||||
const pt = [];
|
||||
|
@ -5374,22 +5373,9 @@ async function detectLandmarks(input, config3, outputSize2) {
|
|||
}
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
const outputSize2 = [input.shape[2] || 0, input.shape[1] || 0];
|
||||
const skipTime = (config3.body.skipTime || 0) > now() - lastTime5;
|
||||
|
@ -5398,26 +5384,13 @@ async function predict5(input, config3) {
|
|||
skipped5++;
|
||||
} else {
|
||||
const t = {};
|
||||
if (config3.body["detector"] && config3.body["detector"]["enabled"]) {
|
||||
t.detector = await prepareImage(input, 224);
|
||||
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);
|
||||
}
|
||||
t.landmarks = await prepareImage(input, 256);
|
||||
cache = await detectLandmarks(t.landmarks, config3, outputSize2);
|
||||
Object.keys(t).forEach((tensor3) => tfjs_esm_exports.dispose(t[tensor3]));
|
||||
lastTime5 = now();
|
||||
skipped5 = 0;
|
||||
}
|
||||
if (cache)
|
||||
return [cache];
|
||||
return [];
|
||||
return cache ? [cache] : [];
|
||||
}
|
||||
|
||||
// src/object/labels.ts
|
||||
|
@ -5555,13 +5528,13 @@ async function process3(res, outputShape, config3) {
|
|||
detections[0][id][2] / inputSize4 - x,
|
||||
detections[0][id][3] / inputSize4 - y
|
||||
];
|
||||
const box4 = [
|
||||
const box5 = [
|
||||
Math.trunc(boxRaw[0] * outputShape[0]),
|
||||
Math.trunc(boxRaw[1] * outputShape[1]),
|
||||
Math.trunc(boxRaw[2] * outputShape[0]),
|
||||
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]));
|
||||
return results;
|
||||
|
@ -5679,10 +5652,10 @@ async function predict7(image29, config3) {
|
|||
tfjs_esm_exports.dispose(tensor3);
|
||||
if (resT) {
|
||||
cache2.keypoints.length = 0;
|
||||
const squeeze11 = resT.squeeze();
|
||||
const squeeze10 = resT.squeeze();
|
||||
tfjs_esm_exports.dispose(resT);
|
||||
const stack5 = squeeze11.unstack(2);
|
||||
tfjs_esm_exports.dispose(squeeze11);
|
||||
const stack5 = squeeze10.unstack(2);
|
||||
tfjs_esm_exports.dispose(squeeze10);
|
||||
for (let id = 0; id < stack5.length; id++) {
|
||||
const [x2, y2, partScore] = await max2d(stack5[id], config3.body.minConfidence);
|
||||
if (partScore > (((_a = config3.body) == null ? void 0 : _a.minConfidence) || 0)) {
|
||||
|
@ -5894,20 +5867,20 @@ var getLeftToRightEyeDepthDifference = (rawCoords) => {
|
|||
return leftEyeZ - rightEyeZ;
|
||||
};
|
||||
var getEyeBox = (rawCoords, face5, eyeInnerCornerIndex, eyeOuterCornerIndex, meshSize, flip = false) => {
|
||||
const box4 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge));
|
||||
const boxSize = getBoxSize(box4);
|
||||
const box5 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge));
|
||||
const boxSize = getBoxSize(box5);
|
||||
let crop2 = tfjs_esm_exports.image.cropAndResize(face5, [[
|
||||
box4.startPoint[1] / meshSize,
|
||||
box4.startPoint[0] / meshSize,
|
||||
box4.endPoint[1] / meshSize,
|
||||
box4.endPoint[0] / meshSize
|
||||
box5.startPoint[1] / meshSize,
|
||||
box5.startPoint[0] / meshSize,
|
||||
box5.endPoint[1] / meshSize,
|
||||
box5.endPoint[0] / meshSize
|
||||
]], [0], [inputSize5, inputSize5]);
|
||||
if (flip && env.kernels.includes("flipleftright")) {
|
||||
const flipped = tfjs_esm_exports.image.flipLeftRight(crop2);
|
||||
tfjs_esm_exports.dispose(crop2);
|
||||
crop2 = flipped;
|
||||
}
|
||||
return { box: box4, boxSize, crop: crop2 };
|
||||
return { box: box5, boxSize, crop: crop2 };
|
||||
};
|
||||
var getEyeCoords = (eyeData, eyeBox, eyeBoxSize, flip = false) => {
|
||||
const eyeRawCoords = [];
|
||||
|
@ -6001,7 +5974,7 @@ async function predict10(input, config3) {
|
|||
const newCache = [];
|
||||
let id = 0;
|
||||
for (let i = 0; i < boxCache.length; i++) {
|
||||
let box4 = boxCache[i];
|
||||
let box5 = boxCache[i];
|
||||
let angle = 0;
|
||||
let rotationMatrix;
|
||||
const face5 = {
|
||||
|
@ -6015,20 +5988,20 @@ async function predict10(input, config3) {
|
|||
faceScore: 0,
|
||||
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) {
|
||||
const equilized = await histogramEqualization(face5.tensor);
|
||||
tfjs_esm_exports.dispose(face5.tensor);
|
||||
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)) {
|
||||
face5.box = getClampedBox(box4, input);
|
||||
face5.boxRaw = getRawBox(box4, input);
|
||||
face5.box = getClampedBox(box5, input);
|
||||
face5.boxRaw = getRawBox(box5, input);
|
||||
face5.score = face5.boxScore;
|
||||
face5.mesh = box4.landmarks.map((pt) => [
|
||||
(box4.startPoint[0] + box4.endPoint[0]) / 2 + (box4.endPoint[0] + box4.startPoint[0]) * pt[0] / size(),
|
||||
(box4.startPoint[1] + box4.endPoint[1]) / 2 + (box4.endPoint[1] + box4.startPoint[1]) * pt[1] / size()
|
||||
face5.mesh = box5.landmarks.map((pt) => [
|
||||
(box5.startPoint[0] + box5.endPoint[0]) / 2 + (box5.endPoint[0] + box5.startPoint[0]) * pt[0] / 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]);
|
||||
for (const key of Object.keys(blazeFaceLandmarks))
|
||||
|
@ -6044,24 +6017,24 @@ async function predict10(input, config3) {
|
|||
let rawCoords = await coordsReshaped.array();
|
||||
tfjs_esm_exports.dispose([contourCoords, coordsReshaped, confidence, contours]);
|
||||
if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
|
||||
box4.confidence = face5.faceScore;
|
||||
box5.confidence = face5.faceScore;
|
||||
} else {
|
||||
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
|
||||
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]);
|
||||
for (const key of Object.keys(meshAnnotations))
|
||||
face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]);
|
||||
const boxCalculated = calculateLandmarksBoundingBox(face5.mesh);
|
||||
const boxEnlarged = enlargeBox(boxCalculated, ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6);
|
||||
const boxSquared = squarifyBox(boxEnlarged);
|
||||
box4 = { ...boxSquared, confidence: box4.confidence };
|
||||
face5.box = getClampedBox(box4, input);
|
||||
face5.boxRaw = getRawBox(box4, input);
|
||||
box5 = { ...boxSquared, confidence: box5.confidence };
|
||||
face5.box = getClampedBox(box5, input);
|
||||
face5.boxRaw = getRawBox(box5, input);
|
||||
face5.score = face5.faceScore;
|
||||
newCache.push(box4);
|
||||
newCache.push(box5);
|
||||
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);
|
||||
|
@ -6166,54 +6139,54 @@ async function predict11(image29, config3, idx, count2) {
|
|||
}
|
||||
|
||||
// src/hand/handposeutil.ts
|
||||
function getBoxSize2(box4) {
|
||||
function getBoxSize2(box5) {
|
||||
return [
|
||||
Math.abs(box4.endPoint[0] - box4.startPoint[0]),
|
||||
Math.abs(box4.endPoint[1] - box4.startPoint[1])
|
||||
Math.abs(box5.endPoint[0] - box5.startPoint[0]),
|
||||
Math.abs(box5.endPoint[1] - box5.startPoint[1])
|
||||
];
|
||||
}
|
||||
function getBoxCenter2(box4) {
|
||||
function getBoxCenter2(box5) {
|
||||
return [
|
||||
box4.startPoint[0] + (box4.endPoint[0] - box4.startPoint[0]) / 2,
|
||||
box4.startPoint[1] + (box4.endPoint[1] - box4.startPoint[1]) / 2
|
||||
box5.startPoint[0] + (box5.endPoint[0] - box5.startPoint[0]) / 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 w = image29.shape[2];
|
||||
const boxes = [[
|
||||
box4.startPoint[1] / h,
|
||||
box4.startPoint[0] / w,
|
||||
box4.endPoint[1] / h,
|
||||
box4.endPoint[0] / w
|
||||
box5.startPoint[1] / h,
|
||||
box5.startPoint[0] / w,
|
||||
box5.endPoint[1] / h,
|
||||
box5.endPoint[0] / w
|
||||
]];
|
||||
return tfjs_esm_exports.image.cropAndResize(image29, boxes, [0], cropSize);
|
||||
}
|
||||
function scaleBoxCoordinates2(box4, factor) {
|
||||
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]];
|
||||
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]];
|
||||
const palmLandmarks = box4.palmLandmarks.map((coord) => {
|
||||
function scaleBoxCoordinates2(box5, factor) {
|
||||
const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
|
||||
const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
|
||||
const palmLandmarks = box5.palmLandmarks.map((coord) => {
|
||||
const scaledCoord = [coord[0] * factor[0], coord[1] * factor[1]];
|
||||
return scaledCoord;
|
||||
});
|
||||
return { startPoint, endPoint, palmLandmarks, confidence: box4.confidence };
|
||||
return { startPoint, endPoint, palmLandmarks, confidence: box5.confidence };
|
||||
}
|
||||
function enlargeBox2(box4, factor = 1.5) {
|
||||
const center = getBoxCenter2(box4);
|
||||
const size2 = getBoxSize2(box4);
|
||||
function enlargeBox2(box5, factor = 1.5) {
|
||||
const center = getBoxCenter2(box5);
|
||||
const size2 = getBoxSize2(box5);
|
||||
const newHalfSize = [factor * size2[0] / 2, factor * size2[1] / 2];
|
||||
const startPoint = [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) {
|
||||
const centers = getBoxCenter2(box4);
|
||||
const size2 = getBoxSize2(box4);
|
||||
function squarifyBox2(box5) {
|
||||
const centers = getBoxCenter2(box5);
|
||||
const size2 = getBoxSize2(box5);
|
||||
const maxEdge = Math.max(...size2);
|
||||
const halfSize = maxEdge / 2;
|
||||
const startPoint = [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) {
|
||||
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.norm = this.normalizeLandmarks(p.slice, index2);
|
||||
p.palmLandmarks = tfjs_esm_exports.reshape(p.norm, [-1, 2]);
|
||||
const box4 = await p.box.data();
|
||||
const startPoint = box4.slice(0, 2);
|
||||
const endPoint = box4.slice(2, 4);
|
||||
const box5 = await p.box.data();
|
||||
const startPoint = box5.slice(0, 2);
|
||||
const endPoint = box5.slice(2, 4);
|
||||
const palmLandmarks = await p.palmLandmarks.array();
|
||||
const hand3 = { startPoint, endPoint, palmLandmarks, confidence: scores[index2] };
|
||||
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;
|
||||
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];
|
||||
if (keypoints && keypoints.length > 0) {
|
||||
for (const pt of keypoints) {
|
||||
if (pt[0] < box4[0])
|
||||
box4[0] = pt[0];
|
||||
if (pt[1] < box4[1])
|
||||
box4[1] = pt[1];
|
||||
if (pt[0] > box4[2])
|
||||
box4[2] = pt[0];
|
||||
if (pt[1] > box4[3])
|
||||
box4[3] = pt[1];
|
||||
if (pt[0] < box5[0])
|
||||
box5[0] = pt[0];
|
||||
if (pt[1] < box5[1])
|
||||
box5[1] = pt[1];
|
||||
if (pt[0] > box5[2])
|
||||
box5[2] = pt[0];
|
||||
if (pt[1] > box5[3])
|
||||
box5[3] = pt[1];
|
||||
}
|
||||
box4[2] -= box4[0];
|
||||
box4[3] -= box4[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)];
|
||||
box5[2] -= box5[0];
|
||||
box5[3] -= box5[1];
|
||||
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 {
|
||||
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[1])),
|
||||
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,
|
||||
fingerScore: Math.round(100 * predictions[i].fingerConfidence) / 100,
|
||||
label: "hand",
|
||||
box: box4,
|
||||
box: box5,
|
||||
boxRaw,
|
||||
keypoints,
|
||||
annotations: annotations2,
|
||||
|
@ -9953,40 +9926,6 @@ async function load13(config3) {
|
|||
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
|
||||
var models2 = [null, null];
|
||||
var modelOutputNodes = ["StatefulPartitionedCall/Postprocessor/Slice", "StatefulPartitionedCall/Postprocessor/ExpandDims_1"];
|
||||
|
@ -10004,11 +9943,11 @@ var cache3 = {
|
|||
hands: []
|
||||
};
|
||||
var fingerMap = {
|
||||
thumb: [1, 2, 3, 4],
|
||||
index: [5, 6, 7, 8],
|
||||
middle: [9, 10, 11, 12],
|
||||
ring: [13, 14, 15, 16],
|
||||
pinky: [17, 18, 19, 20],
|
||||
thumb: [0, 1, 2, 3, 4],
|
||||
index: [0, 5, 6, 7, 8],
|
||||
middle: [0, 9, 10, 11, 12],
|
||||
ring: [0, 13, 14, 15, 16],
|
||||
pinky: [0, 17, 18, 19, 20],
|
||||
palm: [0]
|
||||
};
|
||||
async function loadDetect2(config3) {
|
||||
|
@ -10553,7 +10492,7 @@ async function process4(res, inputSize9, outputShape, config3) {
|
|||
];
|
||||
let boxRaw = [x, y, w, h];
|
||||
boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1)));
|
||||
const box4 = [
|
||||
const box5 = [
|
||||
boxRaw[0] * outputShape[0],
|
||||
boxRaw[1] * outputShape[1],
|
||||
boxRaw[2] * outputShape[0],
|
||||
|
@ -10564,7 +10503,7 @@ async function process4(res, inputSize9, outputShape, config3) {
|
|||
score: Math.round(100 * score) / 100,
|
||||
class: j + 1,
|
||||
label: labels[j].label,
|
||||
box: box4.map((a) => Math.trunc(a)),
|
||||
box: box5.map((a) => Math.trunc(a)),
|
||||
boxRaw
|
||||
};
|
||||
results.push(result);
|
||||
|
@ -10904,7 +10843,7 @@ function getInstanceScore(existingPoses, keypoints) {
|
|||
}, 0);
|
||||
return notOverlappedKeypointScores / keypoints.length;
|
||||
}
|
||||
function decode2(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) {
|
||||
function decode(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) {
|
||||
const poses = [];
|
||||
const queue = buildPartWithScoreQueue(minConfidence2, scores);
|
||||
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);
|
||||
keypoints = keypoints.filter((a) => a.score > minConfidence2);
|
||||
const score = getInstanceScore(poses, keypoints);
|
||||
const box4 = getBoundingBox(keypoints);
|
||||
const box5 = getBoundingBox(keypoints);
|
||||
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;
|
||||
}
|
||||
|
@ -10935,7 +10874,7 @@ async function predict17(input, config3) {
|
|||
const buffers = await Promise.all(res.map((tensor3) => tensor3.buffer()));
|
||||
for (const t of res)
|
||||
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)
|
||||
return [];
|
||||
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;
|
||||
if (isNaN(thetaZ))
|
||||
thetaZ = 0;
|
||||
return { pitch: 2 * -thetaX, yaw: 2 * -thetaY, roll: 2 * -thetaZ };
|
||||
return { pitch: -thetaX, yaw: -thetaY, roll: -thetaZ };
|
||||
};
|
||||
const meshToEulerAngle = (mesh2) => {
|
||||
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));
|
||||
} else {
|
||||
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 keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({
|
||||
score: newKpt.score,
|
||||
|
@ -12368,14 +12307,14 @@ function calc2(newResult, config3) {
|
|||
}
|
||||
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) {
|
||||
bufferedResult.hand = JSON.parse(JSON.stringify(newResult.hand));
|
||||
} else {
|
||||
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);
|
||||
if (bufferedResult.hand[i].keypoints.length !== newResult.hand[i].keypoints.length)
|
||||
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;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
bufferedResult.face = JSON.parse(JSON.stringify(newResult.face));
|
||||
} else {
|
||||
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);
|
||||
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 } };
|
||||
|
@ -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,
|
||||
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) {
|
||||
bufferedResult.object = JSON.parse(JSON.stringify(newResult.object));
|
||||
} else {
|
||||
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);
|
||||
bufferedResult.object[i] = { ...newResult.object[i], box: box4, boxRaw };
|
||||
bufferedResult.object[i] = { ...newResult.object[i], box: box5, boxRaw };
|
||||
}
|
||||
}
|
||||
if (newResult.persons) {
|
||||
|
@ -12430,7 +12369,7 @@ function calc2(newResult, config3) {
|
|||
bufferedResult.persons = JSON.parse(JSON.stringify(newPersons));
|
||||
} else {
|
||||
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 y = [];
|
||||
const extractXY = (box4) => {
|
||||
if (box4 && box4.length === 4) {
|
||||
x.push(box4[0], box4[0] + box4[2]);
|
||||
y.push(box4[1], box4[1] + box4[3]);
|
||||
const extractXY = (box5) => {
|
||||
if (box5 && box5.length === 4) {
|
||||
x.push(box5[0], box5[0] + box5[2]);
|
||||
y.push(box5[1], box5[1] + box5[3]);
|
||||
}
|
||||
};
|
||||
extractXY((_k = person2.face) == null ? void 0 : _k.box);
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -49402,19 +49402,20 @@ var PackProgram = class {
|
|||
this.packedInputs = false;
|
||||
this.packedOutput = true;
|
||||
this.outputShape = outputShape;
|
||||
const rank = outputShape.length;
|
||||
if (rank === 0) {
|
||||
this.rank = outputShape.length;
|
||||
this.enableShapeUniforms = useShapeUniforms(this.outputShape.length);
|
||||
if (this.rank === 0) {
|
||||
this.userCode = `
|
||||
void main() {
|
||||
setOutput(vec4(getA(), 0., 0., 0.));
|
||||
}
|
||||
`;
|
||||
} else {
|
||||
const channels = getChannels("rc", rank);
|
||||
const dtype = getCoordsDataType(rank);
|
||||
const outOfBoundsCondition = getOutOfBoundsCondition(rank, outputShape, channels);
|
||||
const setup46 = getSetup(rank, outputShape[outputShape.length - 1], outputShape[outputShape.length - 2], channels);
|
||||
const output = getOutput(outputShape, channels);
|
||||
const channels = getChannels("rc", this.rank);
|
||||
const dtype = getCoordsDataType(this.rank);
|
||||
const outOfBoundsCondition = this.getOutOfBoundsCondition(channels);
|
||||
const setup46 = this.getSetup(channels);
|
||||
const output = this.getOutput(channels);
|
||||
this.userCode = `
|
||||
void main() {
|
||||
${dtype} rc = getOutputCoords();
|
||||
|
@ -49430,61 +49431,62 @@ var PackProgram = class {
|
|||
`;
|
||||
}
|
||||
}
|
||||
};
|
||||
function getSourceCoordsArr(rank, dims) {
|
||||
const coords32 = [];
|
||||
for (let row = 0; row <= 1; row++) {
|
||||
for (let col = 0; col <= 1; col++) {
|
||||
let coord = `${row === 0 ? "r" : "rp1"}, ${col === 0 ? "c" : "cp1"}`;
|
||||
for (let d = 2; d < rank; d++) {
|
||||
coord = `${dims[dims.length - 1 - d]},` + coord;
|
||||
getSourceCoordsArr(dims) {
|
||||
const coords32 = [];
|
||||
for (let row = 0; row <= 1; row++) {
|
||||
for (let col = 0; col <= 1; col++) {
|
||||
let coord = `${row === 0 ? "r" : "rp1"}, ${col === 0 ? "c" : "cp1"}`;
|
||||
for (let d = 2; d < this.rank; d++) {
|
||||
coord = `${dims[dims.length - 1 - d]},` + coord;
|
||||
}
|
||||
coords32.push(coord);
|
||||
}
|
||||
coords32.push(coord);
|
||||
}
|
||||
return coords32;
|
||||
}
|
||||
return coords32;
|
||||
}
|
||||
function getOutOfBoundsCondition(rank, shape, dims) {
|
||||
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 += "||";
|
||||
getOutOfBoundsCondition(dims) {
|
||||
if (this.rank === 1) {
|
||||
return `rc > ${this.enableShapeUniforms ? "outShape" : this.outputShape[0]}`;
|
||||
}
|
||||
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;
|
||||
}
|
||||
function getSetup(rank, cols, rows, dims) {
|
||||
if (rank === 1) {
|
||||
return "";
|
||||
}
|
||||
const innerDims = dims.slice(-2);
|
||||
return `
|
||||
int r = ${innerDims[0]};
|
||||
int c = ${innerDims[1]};
|
||||
int rp1 = r + 1;
|
||||
int cp1 = c + 1;
|
||||
getSetup(dims) {
|
||||
if (this.rank === 1) {
|
||||
return "";
|
||||
}
|
||||
const innerDims = dims.slice(-2);
|
||||
const col = this.enableShapeUniforms ? `outShape[${this.rank} - 1]` : this.outputShape[this.rank - 1];
|
||||
const row = this.enableShapeUniforms ? `outShape[${this.rank} - 2]` : this.outputShape[this.rank - 2];
|
||||
return `
|
||||
int r = ${innerDims[0]};
|
||||
int c = ${innerDims[1]};
|
||||
int rp1 = r + 1;
|
||||
int cp1 = c + 1;
|
||||
|
||||
bool cEdge = cp1 >= ${cols};
|
||||
bool rEdge = rp1 >= ${rows};
|
||||
`;
|
||||
}
|
||||
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`;
|
||||
bool cEdge = cp1 >= ${col};
|
||||
bool rEdge = rp1 >= ${row};
|
||||
`;
|
||||
}
|
||||
return `getA(${sourceCoords[0]}),
|
||||
cEdge ? 0. : getA(${sourceCoords[1]}),
|
||||
rEdge ? 0. : getA(${sourceCoords[2]}),
|
||||
rEdge || cEdge ? 0. : getA(${sourceCoords[3]})`;
|
||||
}
|
||||
getOutput(dims) {
|
||||
const sourceCoords = this.getSourceCoordsArr(dims);
|
||||
if (this.rank === 1) {
|
||||
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 {
|
||||
constructor(outputShape, inputShape) {
|
||||
this.variableNames = ["A"];
|
||||
|
@ -49827,6 +49829,7 @@ var UnpackProgram = class {
|
|||
this.packedInputs = true;
|
||||
this.packedOutput = false;
|
||||
this.outputShape = outputShape;
|
||||
this.enableShapeUniforms = useShapeUniforms(this.outputShape.length);
|
||||
const rank = outputShape.length;
|
||||
const channels = getChannels("rc", rank);
|
||||
const dtype = getCoordsDataType(rank);
|
||||
|
@ -70672,7 +70675,7 @@ registerBackend("wasm", async () => {
|
|||
const { wasm } = await init();
|
||||
return new BackendWasm(wasm);
|
||||
}, WASM_PRIORITY);
|
||||
var externalVersion = "3.11.0-20211123";
|
||||
var externalVersion = "3.11.0-20211124";
|
||||
var version8 = {
|
||||
tfjs: externalVersion,
|
||||
"tfjs-core": externalVersion,
|
||||
|
@ -71818,8 +71821,8 @@ async function predict(image7, config3, idx, count3) {
|
|||
if (!(model2 == null ? void 0 : model2.inputs[0].shape))
|
||||
return;
|
||||
const t = {};
|
||||
const box4 = [[0, 0.1, 0.9, 0.9]];
|
||||
t.resize = image.cropAndResize(image7, box4, [0], [model2.inputs[0].shape[2], model2.inputs[0].shape[1]]);
|
||||
const box5 = [[0, 0.1, 0.9, 0.9]];
|
||||
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: [] };
|
||||
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"]);
|
||||
|
@ -75303,44 +75306,44 @@ var UV33 = VTX33.map((x) => UV468[x]);
|
|||
var UV7 = VTX7.map((x) => UV468[x]);
|
||||
|
||||
// src/face/facemeshutil.ts
|
||||
var getBoxSize = (box4) => [Math.abs(box4.endPoint[0] - box4.startPoint[0]), Math.abs(box4.endPoint[1] - box4.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 getClampedBox = (box4, input2) => box4 ? [
|
||||
Math.trunc(Math.max(0, box4.startPoint[0])),
|
||||
Math.trunc(Math.max(0, box4.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[1] || 0, box4.endPoint[1]) - Math.max(0, box4.startPoint[1]))
|
||||
var getBoxSize = (box5) => [Math.abs(box5.endPoint[0] - box5.startPoint[0]), Math.abs(box5.endPoint[1] - box5.startPoint[1])];
|
||||
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 = (box5, input2) => box5 ? [
|
||||
Math.trunc(Math.max(0, box5.startPoint[0])),
|
||||
Math.trunc(Math.max(0, box5.startPoint[1])),
|
||||
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, box5.endPoint[1]) - Math.max(0, box5.startPoint[1]))
|
||||
] : [0, 0, 0, 0];
|
||||
var getRawBox = (box4, input2) => box4 ? [
|
||||
box4.startPoint[0] / (input2.shape[2] || 0),
|
||||
box4.startPoint[1] / (input2.shape[1] || 0),
|
||||
(box4.endPoint[0] - box4.startPoint[0]) / (input2.shape[2] || 0),
|
||||
(box4.endPoint[1] - box4.startPoint[1]) / (input2.shape[1] || 0)
|
||||
var getRawBox = (box5, input2) => box5 ? [
|
||||
box5.startPoint[0] / (input2.shape[2] || 0),
|
||||
box5.startPoint[1] / (input2.shape[1] || 0),
|
||||
(box5.endPoint[0] - box5.startPoint[0]) / (input2.shape[2] || 0),
|
||||
(box5.endPoint[1] - box5.startPoint[1]) / (input2.shape[1] || 0)
|
||||
] : [0, 0, 0, 0];
|
||||
var scaleBoxCoordinates = (box4, factor) => {
|
||||
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]];
|
||||
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]];
|
||||
return { startPoint, endPoint, landmarks: box4.landmarks, confidence: box4.confidence };
|
||||
var scaleBoxCoordinates = (box5, factor) => {
|
||||
const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
|
||||
const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
|
||||
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 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);
|
||||
dispose(crop2);
|
||||
return norm2;
|
||||
};
|
||||
var enlargeBox = (box4, factor) => {
|
||||
const center = getBoxCenter(box4);
|
||||
const size2 = getBoxSize(box4);
|
||||
var enlargeBox = (box5, factor) => {
|
||||
const center = getBoxCenter(box5);
|
||||
const size2 = getBoxSize(box5);
|
||||
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) => {
|
||||
const centers = getBoxCenter(box4);
|
||||
const size2 = getBoxSize(box4);
|
||||
var squarifyBox = (box5) => {
|
||||
const centers = getBoxCenter(box5);
|
||||
const size2 = getBoxSize(box5);
|
||||
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) => {
|
||||
const xs = landmarks.map((d) => d[0]);
|
||||
|
@ -75408,8 +75411,8 @@ function generateAnchors(inputSize9) {
|
|||
}
|
||||
return anchors4;
|
||||
}
|
||||
function transformRawCoords(coordsRaw, box4, angle, rotationMatrix, inputSize9) {
|
||||
const boxSize = getBoxSize(box4);
|
||||
function transformRawCoords(coordsRaw, box5, angle, rotationMatrix, inputSize9) {
|
||||
const boxSize = getBoxSize(box5);
|
||||
const coordsScaled = coordsRaw.map((coord) => [
|
||||
boxSize[0] / inputSize9 * (coord[0] - 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 coordsRotated = largeAngle ? coordsScaled.map((coord) => [...rotatePoint(coord, coordsRotationMatrix), coord[2]]) : coordsScaled;
|
||||
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) => [
|
||||
Math.round(coord[0] + dot4(boxCenter, inverseRotationMatrix[0])),
|
||||
Math.round(coord[1] + dot4(boxCenter, inverseRotationMatrix[1])),
|
||||
Math.round(coord[2] || 0)
|
||||
]);
|
||||
}
|
||||
function correctFaceRotation(rotate, box4, input2, inputSize9) {
|
||||
const symmetryLine = box4.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine;
|
||||
function correctFaceRotation(rotate, box5, input2, inputSize9) {
|
||||
const symmetryLine = box5.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine;
|
||||
let angle = 0;
|
||||
let rotationMatrix = fixedRotationMatrix;
|
||||
let face5;
|
||||
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;
|
||||
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 rotated = image.rotateWithOffset(input2, angle, 0, centerRaw);
|
||||
rotationMatrix = buildRotationMatrix(-angle, center);
|
||||
face5 = cutBoxFromImageAndResize(box4, rotated, [inputSize9, inputSize9]);
|
||||
face5 = cutBoxFromImageAndResize(box5, rotated, [inputSize9, inputSize9]);
|
||||
dispose(rotated);
|
||||
} else {
|
||||
face5 = cutBoxFromImageAndResize(box4, input2, [inputSize9, inputSize9]);
|
||||
face5 = cutBoxFromImageAndResize(box5, input2, [inputSize9, inputSize9]);
|
||||
}
|
||||
} else {
|
||||
face5 = cutBoxFromImageAndResize(box4, input2, [inputSize9, inputSize9]);
|
||||
face5 = cutBoxFromImageAndResize(box5, input2, [inputSize9, inputSize9]);
|
||||
}
|
||||
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)) };
|
||||
}
|
||||
var cropFactor = [5, 5];
|
||||
function decodeBoxes(boxesTensor, anchor) {
|
||||
return tidy(() => {
|
||||
const split4 = split(boxesTensor, 12, 1);
|
||||
let xCenter = squeeze(split4[0]);
|
||||
let yCenter = squeeze(split4[1]);
|
||||
let width = squeeze(split4[2]);
|
||||
let height = squeeze(split4[3]);
|
||||
xCenter = add2(div(xCenter, inputSize2), anchor.x);
|
||||
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;
|
||||
});
|
||||
|
||||
// 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 box5 = [min7[0], min7[1], max7[0] - min7[0], max7[1] - min7[1]];
|
||||
const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
|
||||
return { box: box5, boxRaw };
|
||||
}
|
||||
async function decode(boxesTensor, logitsTensor, config3, outputSize2) {
|
||||
const t = {};
|
||||
t.boxes = decodeBoxes(boxesTensor, anchorTensor);
|
||||
t.scores = sigmoid(logitsTensor);
|
||||
t.argmax = argMax(t.scores);
|
||||
const i = (await t.argmax.data())[0];
|
||||
const scores = await t.scores.data();
|
||||
const detected = [];
|
||||
const minScore = config3.body["detector"] && config3.body["detector"]["minConfidence"] ? config3.body["detector"]["minConfidence"] : 0;
|
||||
if (scores[i] >= minScore) {
|
||||
const boxes = await t.boxes.array();
|
||||
const boxRaw = boxes[i];
|
||||
const box4 = [boxRaw[0] * outputSize2[0], boxRaw[1] * outputSize2[1], boxRaw[2] * outputSize2[0], boxRaw[3] * outputSize2[1]];
|
||||
detected.push({ box: box4, boxRaw, score: scores[i] });
|
||||
}
|
||||
Object.keys(t).forEach((tensor2) => dispose(t[tensor2]));
|
||||
return detected;
|
||||
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 box5 = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];
|
||||
const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
|
||||
return { box: box5, boxRaw };
|
||||
}
|
||||
function scale2(box5, scaleFact) {
|
||||
const dist = [box5[2] * scaleFact, box5[3] * scaleFact];
|
||||
const newBox = [
|
||||
box5[0] - (dist[0] - box5[2]) / 2,
|
||||
box5[1] - (dist[1] - box5[3]) / 2,
|
||||
dist[0],
|
||||
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
|
||||
|
@ -75673,7 +75674,7 @@ var outputNodes = {
|
|||
detector: []
|
||||
};
|
||||
var cache = null;
|
||||
var lastBox;
|
||||
var cropBox;
|
||||
var padding = [[0, 0], [0, 0], [0, 0], [0, 0]];
|
||||
var lastTime5 = 0;
|
||||
var sigmoid6 = (x) => 1 - 1 / (1 + Math.exp(x));
|
||||
|
@ -75710,39 +75711,37 @@ async function loadPose(config3) {
|
|||
log("cached model:", models.landmarks["modelUrl"]);
|
||||
return models.landmarks;
|
||||
}
|
||||
function calculateBoxes(keypoints, outputSize2) {
|
||||
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) {
|
||||
async function prepareImage(input2, size2) {
|
||||
const t = {};
|
||||
if (!input2.shape || !input2.shape[1] || !input2.shape[2])
|
||||
return input2;
|
||||
let final;
|
||||
if (cropBox) {
|
||||
t.cropped = image.cropAndResize(input2, [cropBox], [0], [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 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];
|
||||
const height = [
|
||||
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 = [
|
||||
[0, 0],
|
||||
height,
|
||||
width,
|
||||
[0, 0]
|
||||
];
|
||||
if (box4) {
|
||||
t.resize = image.cropAndResize(input2, [box4], [0], [size2, size2]);
|
||||
} else {
|
||||
t.pad = pad(input2, padding);
|
||||
t.resize = image.resizeBilinear(t.pad, [size2, size2]);
|
||||
}
|
||||
t.pad = pad(t.cropped || input2, padding);
|
||||
t.resize = image.resizeBilinear(t.pad, [size2, size2]);
|
||||
final = div(t.resize, constants.tf255);
|
||||
} 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);
|
||||
} else {
|
||||
final = div(input2, constants.tf255);
|
||||
final = div(t.cropped || input2, constants.tf255);
|
||||
}
|
||||
Object.keys(t).forEach((tensor2) => dispose(t[tensor2]));
|
||||
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]];
|
||||
}
|
||||
return keypoints;
|
||||
}
|
||||
function rescaleBoxes(boxes, outputSize2) {
|
||||
for (const box4 of boxes) {
|
||||
box4.box = [
|
||||
Math.trunc(box4.box[0] * (outputSize2[0] + padding[2][0] + padding[2][1]) / outputSize2[0]),
|
||||
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]),
|
||||
Math.trunc(box4.box[3] * (outputSize2[1] + padding[1][0] + padding[1][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]];
|
||||
if (cropBox) {
|
||||
for (const kpt4 of keypoints) {
|
||||
kpt4.positionRaw = [
|
||||
kpt4.positionRaw[0] + cropBox[1],
|
||||
kpt4.positionRaw[1] + cropBox[0],
|
||||
kpt4.positionRaw[2]
|
||||
];
|
||||
kpt4.position = [
|
||||
Math.trunc(kpt4.positionRaw[0] * outputSize2[0]),
|
||||
Math.trunc(kpt4.positionRaw[1] * outputSize2[1]),
|
||||
kpt4.positionRaw[2]
|
||||
];
|
||||
}
|
||||
}
|
||||
return boxes;
|
||||
return keypoints;
|
||||
}
|
||||
async function detectLandmarks(input2, config3, outputSize2) {
|
||||
var _a;
|
||||
|
@ -75790,7 +75791,8 @@ async function detectLandmarks(input2, config3, outputSize2) {
|
|||
if (poseScore < (config3.body.minConfidence || 0))
|
||||
return null;
|
||||
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 = {};
|
||||
for (const [name, indexes] of Object.entries(connected)) {
|
||||
const pt = [];
|
||||
|
@ -75802,22 +75804,9 @@ async function detectLandmarks(input2, config3, outputSize2) {
|
|||
}
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
const outputSize2 = [input2.shape[2] || 0, input2.shape[1] || 0];
|
||||
const skipTime = (config3.body.skipTime || 0) > now() - lastTime5;
|
||||
|
@ -75826,26 +75815,13 @@ async function predict5(input2, config3) {
|
|||
skipped5++;
|
||||
} else {
|
||||
const t = {};
|
||||
if (config3.body["detector"] && config3.body["detector"]["enabled"]) {
|
||||
t.detector = await prepareImage(input2, 224);
|
||||
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);
|
||||
}
|
||||
t.landmarks = await prepareImage(input2, 256);
|
||||
cache = await detectLandmarks(t.landmarks, config3, outputSize2);
|
||||
Object.keys(t).forEach((tensor2) => dispose(t[tensor2]));
|
||||
lastTime5 = now();
|
||||
skipped5 = 0;
|
||||
}
|
||||
if (cache)
|
||||
return [cache];
|
||||
return [];
|
||||
return cache ? [cache] : [];
|
||||
}
|
||||
|
||||
// src/object/labels.ts
|
||||
|
@ -75983,13 +75959,13 @@ async function process3(res, outputShape, config3) {
|
|||
detections[0][id][2] / inputSize4 - x,
|
||||
detections[0][id][3] / inputSize4 - y
|
||||
];
|
||||
const box4 = [
|
||||
const box5 = [
|
||||
Math.trunc(boxRaw[0] * outputShape[0]),
|
||||
Math.trunc(boxRaw[1] * outputShape[1]),
|
||||
Math.trunc(boxRaw[2] * outputShape[0]),
|
||||
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]));
|
||||
return results;
|
||||
|
@ -76322,20 +76298,20 @@ var getLeftToRightEyeDepthDifference = (rawCoords) => {
|
|||
return leftEyeZ - rightEyeZ;
|
||||
};
|
||||
var getEyeBox = (rawCoords, face5, eyeInnerCornerIndex, eyeOuterCornerIndex, meshSize, flip = false) => {
|
||||
const box4 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge));
|
||||
const boxSize = getBoxSize(box4);
|
||||
const box5 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge));
|
||||
const boxSize = getBoxSize(box5);
|
||||
let crop2 = image.cropAndResize(face5, [[
|
||||
box4.startPoint[1] / meshSize,
|
||||
box4.startPoint[0] / meshSize,
|
||||
box4.endPoint[1] / meshSize,
|
||||
box4.endPoint[0] / meshSize
|
||||
box5.startPoint[1] / meshSize,
|
||||
box5.startPoint[0] / meshSize,
|
||||
box5.endPoint[1] / meshSize,
|
||||
box5.endPoint[0] / meshSize
|
||||
]], [0], [inputSize5, inputSize5]);
|
||||
if (flip && env2.kernels.includes("flipleftright")) {
|
||||
const flipped = image.flipLeftRight(crop2);
|
||||
dispose(crop2);
|
||||
crop2 = flipped;
|
||||
}
|
||||
return { box: box4, boxSize, crop: crop2 };
|
||||
return { box: box5, boxSize, crop: crop2 };
|
||||
};
|
||||
var getEyeCoords = (eyeData, eyeBox, eyeBoxSize, flip = false) => {
|
||||
const eyeRawCoords = [];
|
||||
|
@ -76429,7 +76405,7 @@ async function predict10(input2, config3) {
|
|||
const newCache = [];
|
||||
let id = 0;
|
||||
for (let i = 0; i < boxCache.length; i++) {
|
||||
let box4 = boxCache[i];
|
||||
let box5 = boxCache[i];
|
||||
let angle = 0;
|
||||
let rotationMatrix;
|
||||
const face5 = {
|
||||
|
@ -76443,20 +76419,20 @@ async function predict10(input2, config3) {
|
|||
faceScore: 0,
|
||||
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) {
|
||||
const equilized = await histogramEqualization(face5.tensor);
|
||||
dispose(face5.tensor);
|
||||
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)) {
|
||||
face5.box = getClampedBox(box4, input2);
|
||||
face5.boxRaw = getRawBox(box4, input2);
|
||||
face5.box = getClampedBox(box5, input2);
|
||||
face5.boxRaw = getRawBox(box5, input2);
|
||||
face5.score = face5.boxScore;
|
||||
face5.mesh = box4.landmarks.map((pt) => [
|
||||
(box4.startPoint[0] + box4.endPoint[0]) / 2 + (box4.endPoint[0] + box4.startPoint[0]) * pt[0] / size(),
|
||||
(box4.startPoint[1] + box4.endPoint[1]) / 2 + (box4.endPoint[1] + box4.startPoint[1]) * pt[1] / size()
|
||||
face5.mesh = box5.landmarks.map((pt) => [
|
||||
(box5.startPoint[0] + box5.endPoint[0]) / 2 + (box5.endPoint[0] + box5.startPoint[0]) * pt[0] / 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]);
|
||||
for (const key of Object.keys(blazeFaceLandmarks))
|
||||
|
@ -76472,24 +76448,24 @@ async function predict10(input2, config3) {
|
|||
let rawCoords = await coordsReshaped.array();
|
||||
dispose([contourCoords, coordsReshaped, confidence, contours]);
|
||||
if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
|
||||
box4.confidence = face5.faceScore;
|
||||
box5.confidence = face5.faceScore;
|
||||
} else {
|
||||
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
|
||||
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]);
|
||||
for (const key of Object.keys(meshAnnotations))
|
||||
face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]);
|
||||
const boxCalculated = calculateLandmarksBoundingBox(face5.mesh);
|
||||
const boxEnlarged = enlargeBox(boxCalculated, ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6);
|
||||
const boxSquared = squarifyBox(boxEnlarged);
|
||||
box4 = { ...boxSquared, confidence: box4.confidence };
|
||||
face5.box = getClampedBox(box4, input2);
|
||||
face5.boxRaw = getRawBox(box4, input2);
|
||||
box5 = { ...boxSquared, confidence: box5.confidence };
|
||||
face5.box = getClampedBox(box5, input2);
|
||||
face5.boxRaw = getRawBox(box5, input2);
|
||||
face5.score = face5.faceScore;
|
||||
newCache.push(box4);
|
||||
newCache.push(box5);
|
||||
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);
|
||||
|
@ -76594,54 +76570,54 @@ async function predict11(image7, config3, idx, count3) {
|
|||
}
|
||||
|
||||
// src/hand/handposeutil.ts
|
||||
function getBoxSize2(box4) {
|
||||
function getBoxSize2(box5) {
|
||||
return [
|
||||
Math.abs(box4.endPoint[0] - box4.startPoint[0]),
|
||||
Math.abs(box4.endPoint[1] - box4.startPoint[1])
|
||||
Math.abs(box5.endPoint[0] - box5.startPoint[0]),
|
||||
Math.abs(box5.endPoint[1] - box5.startPoint[1])
|
||||
];
|
||||
}
|
||||
function getBoxCenter2(box4) {
|
||||
function getBoxCenter2(box5) {
|
||||
return [
|
||||
box4.startPoint[0] + (box4.endPoint[0] - box4.startPoint[0]) / 2,
|
||||
box4.startPoint[1] + (box4.endPoint[1] - box4.startPoint[1]) / 2
|
||||
box5.startPoint[0] + (box5.endPoint[0] - box5.startPoint[0]) / 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 w = image7.shape[2];
|
||||
const boxes = [[
|
||||
box4.startPoint[1] / h,
|
||||
box4.startPoint[0] / w,
|
||||
box4.endPoint[1] / h,
|
||||
box4.endPoint[0] / w
|
||||
box5.startPoint[1] / h,
|
||||
box5.startPoint[0] / w,
|
||||
box5.endPoint[1] / h,
|
||||
box5.endPoint[0] / w
|
||||
]];
|
||||
return image.cropAndResize(image7, boxes, [0], cropSize);
|
||||
}
|
||||
function scaleBoxCoordinates2(box4, factor) {
|
||||
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]];
|
||||
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]];
|
||||
const palmLandmarks = box4.palmLandmarks.map((coord) => {
|
||||
function scaleBoxCoordinates2(box5, factor) {
|
||||
const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
|
||||
const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
|
||||
const palmLandmarks = box5.palmLandmarks.map((coord) => {
|
||||
const scaledCoord = [coord[0] * factor[0], coord[1] * factor[1]];
|
||||
return scaledCoord;
|
||||
});
|
||||
return { startPoint, endPoint, palmLandmarks, confidence: box4.confidence };
|
||||
return { startPoint, endPoint, palmLandmarks, confidence: box5.confidence };
|
||||
}
|
||||
function enlargeBox2(box4, factor = 1.5) {
|
||||
const center = getBoxCenter2(box4);
|
||||
const size2 = getBoxSize2(box4);
|
||||
function enlargeBox2(box5, factor = 1.5) {
|
||||
const center = getBoxCenter2(box5);
|
||||
const size2 = getBoxSize2(box5);
|
||||
const newHalfSize = [factor * size2[0] / 2, factor * size2[1] / 2];
|
||||
const startPoint = [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) {
|
||||
const centers = getBoxCenter2(box4);
|
||||
const size2 = getBoxSize2(box4);
|
||||
function squarifyBox2(box5) {
|
||||
const centers = getBoxCenter2(box5);
|
||||
const size2 = getBoxSize2(box5);
|
||||
const maxEdge = Math.max(...size2);
|
||||
const halfSize = maxEdge / 2;
|
||||
const startPoint = [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) {
|
||||
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.norm = this.normalizeLandmarks(p2.slice, index2);
|
||||
p2.palmLandmarks = reshape(p2.norm, [-1, 2]);
|
||||
const box4 = await p2.box.data();
|
||||
const startPoint = box4.slice(0, 2);
|
||||
const endPoint = box4.slice(2, 4);
|
||||
const box5 = await p2.box.data();
|
||||
const startPoint = box5.slice(0, 2);
|
||||
const endPoint = box5.slice(2, 4);
|
||||
const palmLandmarks = await p2.palmLandmarks.array();
|
||||
const hand3 = { startPoint, endPoint, palmLandmarks, confidence: scores[index2] };
|
||||
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;
|
||||
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];
|
||||
if (keypoints && keypoints.length > 0) {
|
||||
for (const pt of keypoints) {
|
||||
if (pt[0] < box4[0])
|
||||
box4[0] = pt[0];
|
||||
if (pt[1] < box4[1])
|
||||
box4[1] = pt[1];
|
||||
if (pt[0] > box4[2])
|
||||
box4[2] = pt[0];
|
||||
if (pt[1] > box4[3])
|
||||
box4[3] = pt[1];
|
||||
if (pt[0] < box5[0])
|
||||
box5[0] = pt[0];
|
||||
if (pt[1] < box5[1])
|
||||
box5[1] = pt[1];
|
||||
if (pt[0] > box5[2])
|
||||
box5[2] = pt[0];
|
||||
if (pt[1] > box5[3])
|
||||
box5[3] = pt[1];
|
||||
}
|
||||
box4[2] -= box4[0];
|
||||
box4[3] -= box4[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)];
|
||||
box5[2] -= box5[0];
|
||||
box5[3] -= box5[1];
|
||||
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 {
|
||||
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[1])),
|
||||
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,
|
||||
fingerScore: Math.round(100 * predictions[i].fingerConfidence) / 100,
|
||||
label: "hand",
|
||||
box: box4,
|
||||
box: box5,
|
||||
boxRaw,
|
||||
keypoints,
|
||||
annotations: annotations2,
|
||||
|
@ -80381,40 +80357,6 @@ async function load13(config3) {
|
|||
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
|
||||
var models2 = [null, null];
|
||||
var modelOutputNodes = ["StatefulPartitionedCall/Postprocessor/Slice", "StatefulPartitionedCall/Postprocessor/ExpandDims_1"];
|
||||
|
@ -80432,11 +80374,11 @@ var cache3 = {
|
|||
hands: []
|
||||
};
|
||||
var fingerMap = {
|
||||
thumb: [1, 2, 3, 4],
|
||||
index: [5, 6, 7, 8],
|
||||
middle: [9, 10, 11, 12],
|
||||
ring: [13, 14, 15, 16],
|
||||
pinky: [17, 18, 19, 20],
|
||||
thumb: [0, 1, 2, 3, 4],
|
||||
index: [0, 5, 6, 7, 8],
|
||||
middle: [0, 9, 10, 11, 12],
|
||||
ring: [0, 13, 14, 15, 16],
|
||||
pinky: [0, 17, 18, 19, 20],
|
||||
palm: [0]
|
||||
};
|
||||
async function loadDetect2(config3) {
|
||||
|
@ -80981,7 +80923,7 @@ async function process4(res, inputSize9, outputShape, config3) {
|
|||
];
|
||||
let boxRaw = [x, y, w, h];
|
||||
boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1)));
|
||||
const box4 = [
|
||||
const box5 = [
|
||||
boxRaw[0] * outputShape[0],
|
||||
boxRaw[1] * outputShape[1],
|
||||
boxRaw[2] * outputShape[0],
|
||||
|
@ -80992,7 +80934,7 @@ async function process4(res, inputSize9, outputShape, config3) {
|
|||
score: Math.round(100 * score) / 100,
|
||||
class: j + 1,
|
||||
label: labels[j].label,
|
||||
box: box4.map((a) => Math.trunc(a)),
|
||||
box: box5.map((a) => Math.trunc(a)),
|
||||
boxRaw
|
||||
};
|
||||
results.push(result);
|
||||
|
@ -81332,7 +81274,7 @@ function getInstanceScore(existingPoses, keypoints) {
|
|||
}, 0);
|
||||
return notOverlappedKeypointScores / keypoints.length;
|
||||
}
|
||||
function decode2(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) {
|
||||
function decode(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) {
|
||||
const poses = [];
|
||||
const queue = buildPartWithScoreQueue(minConfidence2, scores);
|
||||
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);
|
||||
keypoints = keypoints.filter((a) => a.score > minConfidence2);
|
||||
const score = getInstanceScore(poses, keypoints);
|
||||
const box4 = getBoundingBox(keypoints);
|
||||
const box5 = getBoundingBox(keypoints);
|
||||
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;
|
||||
}
|
||||
|
@ -81363,7 +81305,7 @@ async function predict17(input2, config3) {
|
|||
const buffers = await Promise.all(res.map((tensor2) => tensor2.buffer()));
|
||||
for (const t of res)
|
||||
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)
|
||||
return [];
|
||||
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;
|
||||
if (isNaN(thetaZ))
|
||||
thetaZ = 0;
|
||||
return { pitch: 2 * -thetaX, yaw: 2 * -thetaY, roll: 2 * -thetaZ };
|
||||
return { pitch: -thetaX, yaw: -thetaY, roll: -thetaZ };
|
||||
};
|
||||
const meshToEulerAngle = (mesh2) => {
|
||||
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));
|
||||
} else {
|
||||
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 keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({
|
||||
score: newKpt.score,
|
||||
|
@ -82796,14 +82738,14 @@ function calc2(newResult, config3) {
|
|||
}
|
||||
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) {
|
||||
bufferedResult.hand = JSON.parse(JSON.stringify(newResult.hand));
|
||||
} else {
|
||||
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);
|
||||
if (bufferedResult.hand[i].keypoints.length !== newResult.hand[i].keypoints.length)
|
||||
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;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
bufferedResult.face = JSON.parse(JSON.stringify(newResult.face));
|
||||
} else {
|
||||
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);
|
||||
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 } };
|
||||
|
@ -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,
|
||||
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) {
|
||||
bufferedResult.object = JSON.parse(JSON.stringify(newResult.object));
|
||||
} else {
|
||||
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);
|
||||
bufferedResult.object[i] = { ...newResult.object[i], box: box4, boxRaw };
|
||||
bufferedResult.object[i] = { ...newResult.object[i], box: box5, boxRaw };
|
||||
}
|
||||
}
|
||||
if (newResult.persons) {
|
||||
|
@ -82858,7 +82800,7 @@ function calc2(newResult, config3) {
|
|||
bufferedResult.persons = JSON.parse(JSON.stringify(newPersons));
|
||||
} else {
|
||||
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 y = [];
|
||||
const extractXY = (box4) => {
|
||||
if (box4 && box4.length === 4) {
|
||||
x.push(box4[0], box4[0] + box4[2]);
|
||||
y.push(box4[1], box4[1] + box4[3]);
|
||||
const extractXY = (box5) => {
|
||||
if (box5 && box5.length === 4) {
|
||||
x.push(box5[0], box5[0] + box5[2]);
|
||||
y.push(box5[1], box5[1] + box5[3]);
|
||||
}
|
||||
};
|
||||
extractXY((_k = person2.face) == null ? void 0 : _k.box);
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -980,8 +980,8 @@ function GLImageFilter() {
|
|||
// src/image/enhance.ts
|
||||
var tf = __toModule(require_tfjs_esm());
|
||||
async function histogramEqualization(inputImage) {
|
||||
const squeeze11 = inputImage.shape.length === 4 ? tf.squeeze(inputImage) : inputImage;
|
||||
const channels = tf.split(squeeze11, 3, 2);
|
||||
const squeeze10 = inputImage.shape.length === 4 ? tf.squeeze(inputImage) : inputImage;
|
||||
const channels = tf.split(squeeze10, 3, 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 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 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 reshape8 = tf.reshape(rgb2, [1, squeeze11.shape[0], squeeze11.shape[1], 3]);
|
||||
tf.dispose([...channels, ...min2, ...max4, ...sub10, ...range, ...fact, ...enh, rgb2, squeeze11]);
|
||||
const reshape8 = tf.reshape(rgb2, [1, squeeze10.shape[0], squeeze10.shape[1], 3]);
|
||||
tf.dispose([...channels, ...min2, ...max4, ...sub10, ...range, ...fact, ...enh, rgb2, squeeze10]);
|
||||
return reshape8;
|
||||
}
|
||||
|
||||
|
@ -1414,8 +1414,8 @@ async function predict(image29, config3, idx, count2) {
|
|||
if (!(model == null ? void 0 : model.inputs[0].shape))
|
||||
return;
|
||||
const t = {};
|
||||
const box4 = [[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]]);
|
||||
const box5 = [[0, 0.1, 0.9, 0.9]];
|
||||
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: [] };
|
||||
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"]);
|
||||
|
@ -4911,44 +4911,44 @@ var UV33 = VTX33.map((x) => UV468[x]);
|
|||
var UV7 = VTX7.map((x) => UV468[x]);
|
||||
|
||||
// src/face/facemeshutil.ts
|
||||
var getBoxSize = (box4) => [Math.abs(box4.endPoint[0] - box4.startPoint[0]), Math.abs(box4.endPoint[1] - box4.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 getClampedBox = (box4, input) => box4 ? [
|
||||
Math.trunc(Math.max(0, box4.startPoint[0])),
|
||||
Math.trunc(Math.max(0, box4.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[1] || 0, box4.endPoint[1]) - Math.max(0, box4.startPoint[1]))
|
||||
var getBoxSize = (box5) => [Math.abs(box5.endPoint[0] - box5.startPoint[0]), Math.abs(box5.endPoint[1] - box5.startPoint[1])];
|
||||
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 = (box5, input) => box5 ? [
|
||||
Math.trunc(Math.max(0, box5.startPoint[0])),
|
||||
Math.trunc(Math.max(0, box5.startPoint[1])),
|
||||
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, box5.endPoint[1]) - Math.max(0, box5.startPoint[1]))
|
||||
] : [0, 0, 0, 0];
|
||||
var getRawBox = (box4, input) => box4 ? [
|
||||
box4.startPoint[0] / (input.shape[2] || 0),
|
||||
box4.startPoint[1] / (input.shape[1] || 0),
|
||||
(box4.endPoint[0] - box4.startPoint[0]) / (input.shape[2] || 0),
|
||||
(box4.endPoint[1] - box4.startPoint[1]) / (input.shape[1] || 0)
|
||||
var getRawBox = (box5, input) => box5 ? [
|
||||
box5.startPoint[0] / (input.shape[2] || 0),
|
||||
box5.startPoint[1] / (input.shape[1] || 0),
|
||||
(box5.endPoint[0] - box5.startPoint[0]) / (input.shape[2] || 0),
|
||||
(box5.endPoint[1] - box5.startPoint[1]) / (input.shape[1] || 0)
|
||||
] : [0, 0, 0, 0];
|
||||
var scaleBoxCoordinates = (box4, factor) => {
|
||||
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]];
|
||||
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]];
|
||||
return { startPoint, endPoint, landmarks: box4.landmarks, confidence: box4.confidence };
|
||||
var scaleBoxCoordinates = (box5, factor) => {
|
||||
const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
|
||||
const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
|
||||
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 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);
|
||||
tf9.dispose(crop2);
|
||||
return norm;
|
||||
};
|
||||
var enlargeBox = (box4, factor) => {
|
||||
const center = getBoxCenter(box4);
|
||||
const size2 = getBoxSize(box4);
|
||||
var enlargeBox = (box5, factor) => {
|
||||
const center = getBoxCenter(box5);
|
||||
const size2 = getBoxSize(box5);
|
||||
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) => {
|
||||
const centers = getBoxCenter(box4);
|
||||
const size2 = getBoxSize(box4);
|
||||
var squarifyBox = (box5) => {
|
||||
const centers = getBoxCenter(box5);
|
||||
const size2 = getBoxSize(box5);
|
||||
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) => {
|
||||
const xs = landmarks.map((d) => d[0]);
|
||||
|
@ -5016,8 +5016,8 @@ function generateAnchors(inputSize9) {
|
|||
}
|
||||
return anchors4;
|
||||
}
|
||||
function transformRawCoords(coordsRaw, box4, angle, rotationMatrix, inputSize9) {
|
||||
const boxSize = getBoxSize(box4);
|
||||
function transformRawCoords(coordsRaw, box5, angle, rotationMatrix, inputSize9) {
|
||||
const boxSize = getBoxSize(box5);
|
||||
const coordsScaled = coordsRaw.map((coord) => [
|
||||
boxSize[0] / inputSize9 * (coord[0] - 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 coordsRotated = largeAngle ? coordsScaled.map((coord) => [...rotatePoint(coord, coordsRotationMatrix), coord[2]]) : coordsScaled;
|
||||
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) => [
|
||||
Math.round(coord[0] + dot(boxCenter, inverseRotationMatrix[0])),
|
||||
Math.round(coord[1] + dot(boxCenter, inverseRotationMatrix[1])),
|
||||
Math.round(coord[2] || 0)
|
||||
]);
|
||||
}
|
||||
function correctFaceRotation(rotate, box4, input, inputSize9) {
|
||||
const symmetryLine = box4.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine;
|
||||
function correctFaceRotation(rotate, box5, input, inputSize9) {
|
||||
const symmetryLine = box5.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine;
|
||||
let angle = 0;
|
||||
let rotationMatrix = fixedRotationMatrix;
|
||||
let face5;
|
||||
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;
|
||||
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 rotated = tf9.image.rotateWithOffset(input, angle, 0, centerRaw);
|
||||
rotationMatrix = buildRotationMatrix(-angle, center);
|
||||
face5 = cutBoxFromImageAndResize(box4, rotated, [inputSize9, inputSize9]);
|
||||
face5 = cutBoxFromImageAndResize(box5, rotated, [inputSize9, inputSize9]);
|
||||
tf9.dispose(rotated);
|
||||
} else {
|
||||
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]);
|
||||
face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
|
||||
}
|
||||
} else {
|
||||
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]);
|
||||
face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
|
||||
}
|
||||
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)) };
|
||||
}
|
||||
var cropFactor = [5, 5];
|
||||
function decodeBoxes(boxesTensor, anchor) {
|
||||
return tf11.tidy(() => {
|
||||
const split5 = tf11.split(boxesTensor, 12, 1);
|
||||
let xCenter = tf11.squeeze(split5[0]);
|
||||
let yCenter = tf11.squeeze(split5[1]);
|
||||
let width = tf11.squeeze(split5[2]);
|
||||
let height = tf11.squeeze(split5[3]);
|
||||
xCenter = tf11.add(tf11.div(xCenter, inputSize2), anchor.x);
|
||||
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;
|
||||
});
|
||||
|
||||
// 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 box5 = [min2[0], min2[1], max4[0] - min2[0], max4[1] - min2[1]];
|
||||
const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
|
||||
return { box: box5, boxRaw };
|
||||
}
|
||||
async function decode(boxesTensor, logitsTensor, config3, outputSize2) {
|
||||
const t = {};
|
||||
t.boxes = decodeBoxes(boxesTensor, anchorTensor);
|
||||
t.scores = tf11.sigmoid(logitsTensor);
|
||||
t.argmax = tf11.argMax(t.scores);
|
||||
const i = (await t.argmax.data())[0];
|
||||
const scores = await t.scores.data();
|
||||
const detected = [];
|
||||
const minScore = config3.body["detector"] && config3.body["detector"]["minConfidence"] ? config3.body["detector"]["minConfidence"] : 0;
|
||||
if (scores[i] >= minScore) {
|
||||
const boxes = await t.boxes.array();
|
||||
const boxRaw = boxes[i];
|
||||
const box4 = [boxRaw[0] * outputSize2[0], boxRaw[1] * outputSize2[1], boxRaw[2] * outputSize2[0], boxRaw[3] * outputSize2[1]];
|
||||
detected.push({ box: box4, boxRaw, score: scores[i] });
|
||||
}
|
||||
Object.keys(t).forEach((tensor3) => tf11.dispose(t[tensor3]));
|
||||
return detected;
|
||||
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 box5 = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];
|
||||
const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
|
||||
return { box: box5, boxRaw };
|
||||
}
|
||||
function scale(box5, scaleFact) {
|
||||
const dist = [box5[2] * scaleFact, box5[3] * scaleFact];
|
||||
const newBox = [
|
||||
box5[0] - (dist[0] - box5[2]) / 2,
|
||||
box5[1] - (dist[1] - box5[3]) / 2,
|
||||
dist[0],
|
||||
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
|
||||
|
@ -5285,7 +5283,7 @@ var outputNodes = {
|
|||
detector: []
|
||||
};
|
||||
var cache = null;
|
||||
var lastBox;
|
||||
var cropBox;
|
||||
var padding = [[0, 0], [0, 0], [0, 0], [0, 0]];
|
||||
var lastTime5 = 0;
|
||||
var sigmoid3 = (x) => 1 - 1 / (1 + Math.exp(x));
|
||||
|
@ -5322,39 +5320,37 @@ async function loadPose(config3) {
|
|||
log("cached model:", models.landmarks["modelUrl"]);
|
||||
return models.landmarks;
|
||||
}
|
||||
function calculateBoxes(keypoints, outputSize2) {
|
||||
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) {
|
||||
async function prepareImage(input, size2) {
|
||||
const t = {};
|
||||
if (!input.shape || !input.shape[1] || !input.shape[2])
|
||||
return input;
|
||||
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]) {
|
||||
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 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];
|
||||
const height = [
|
||||
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 = [
|
||||
[0, 0],
|
||||
height,
|
||||
width,
|
||||
[0, 0]
|
||||
];
|
||||
if (box4) {
|
||||
t.resize = tf12.image.cropAndResize(input, [box4], [0], [size2, size2]);
|
||||
} else {
|
||||
t.pad = tf12.pad(input, padding);
|
||||
t.resize = tf12.image.resizeBilinear(t.pad, [size2, size2]);
|
||||
}
|
||||
t.pad = tf12.pad(t.cropped || input, padding);
|
||||
t.resize = tf12.image.resizeBilinear(t.pad, [size2, size2]);
|
||||
final = tf12.div(t.resize, constants.tf255);
|
||||
} 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);
|
||||
} else {
|
||||
final = tf12.div(input, constants.tf255);
|
||||
final = tf12.div(t.cropped || input, constants.tf255);
|
||||
}
|
||||
Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3]));
|
||||
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]];
|
||||
}
|
||||
return keypoints;
|
||||
}
|
||||
function rescaleBoxes(boxes, outputSize2) {
|
||||
for (const box4 of boxes) {
|
||||
box4.box = [
|
||||
Math.trunc(box4.box[0] * (outputSize2[0] + padding[2][0] + padding[2][1]) / outputSize2[0]),
|
||||
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]),
|
||||
Math.trunc(box4.box[3] * (outputSize2[1] + padding[1][0] + padding[1][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]];
|
||||
if (cropBox) {
|
||||
for (const kpt4 of keypoints) {
|
||||
kpt4.positionRaw = [
|
||||
kpt4.positionRaw[0] + cropBox[1],
|
||||
kpt4.positionRaw[1] + cropBox[0],
|
||||
kpt4.positionRaw[2]
|
||||
];
|
||||
kpt4.position = [
|
||||
Math.trunc(kpt4.positionRaw[0] * outputSize2[0]),
|
||||
Math.trunc(kpt4.positionRaw[1] * outputSize2[1]),
|
||||
kpt4.positionRaw[2]
|
||||
];
|
||||
}
|
||||
}
|
||||
return boxes;
|
||||
return keypoints;
|
||||
}
|
||||
async function detectLandmarks(input, config3, outputSize2) {
|
||||
var _a;
|
||||
|
@ -5402,7 +5400,8 @@ async function detectLandmarks(input, config3, outputSize2) {
|
|||
if (poseScore < (config3.body.minConfidence || 0))
|
||||
return null;
|
||||
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 = {};
|
||||
for (const [name, indexes] of Object.entries(connected)) {
|
||||
const pt = [];
|
||||
|
@ -5414,22 +5413,9 @@ async function detectLandmarks(input, config3, outputSize2) {
|
|||
}
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
const outputSize2 = [input.shape[2] || 0, input.shape[1] || 0];
|
||||
const skipTime = (config3.body.skipTime || 0) > now() - lastTime5;
|
||||
|
@ -5438,26 +5424,13 @@ async function predict5(input, config3) {
|
|||
skipped5++;
|
||||
} else {
|
||||
const t = {};
|
||||
if (config3.body["detector"] && config3.body["detector"]["enabled"]) {
|
||||
t.detector = await prepareImage(input, 224);
|
||||
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);
|
||||
}
|
||||
t.landmarks = await prepareImage(input, 256);
|
||||
cache = await detectLandmarks(t.landmarks, config3, outputSize2);
|
||||
Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3]));
|
||||
lastTime5 = now();
|
||||
skipped5 = 0;
|
||||
}
|
||||
if (cache)
|
||||
return [cache];
|
||||
return [];
|
||||
return cache ? [cache] : [];
|
||||
}
|
||||
|
||||
// src/object/centernet.ts
|
||||
|
@ -5598,13 +5571,13 @@ async function process3(res, outputShape, config3) {
|
|||
detections[0][id][2] / inputSize4 - x,
|
||||
detections[0][id][3] / inputSize4 - y
|
||||
];
|
||||
const box4 = [
|
||||
const box5 = [
|
||||
Math.trunc(boxRaw[0] * outputShape[0]),
|
||||
Math.trunc(boxRaw[1] * outputShape[1]),
|
||||
Math.trunc(boxRaw[2] * outputShape[0]),
|
||||
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]));
|
||||
return results;
|
||||
|
@ -5725,10 +5698,10 @@ async function predict7(image29, config3) {
|
|||
tf14.dispose(tensor3);
|
||||
if (resT) {
|
||||
cache2.keypoints.length = 0;
|
||||
const squeeze11 = resT.squeeze();
|
||||
const squeeze10 = resT.squeeze();
|
||||
tf14.dispose(resT);
|
||||
const stack5 = squeeze11.unstack(2);
|
||||
tf14.dispose(squeeze11);
|
||||
const stack5 = squeeze10.unstack(2);
|
||||
tf14.dispose(squeeze10);
|
||||
for (let id = 0; id < stack5.length; id++) {
|
||||
const [x2, y2, partScore] = await max2d(stack5[id], config3.body.minConfidence);
|
||||
if (partScore > (((_a = config3.body) == null ? void 0 : _a.minConfidence) || 0)) {
|
||||
|
@ -5946,20 +5919,20 @@ var getLeftToRightEyeDepthDifference = (rawCoords) => {
|
|||
return leftEyeZ - rightEyeZ;
|
||||
};
|
||||
var getEyeBox = (rawCoords, face5, eyeInnerCornerIndex, eyeOuterCornerIndex, meshSize, flip = false) => {
|
||||
const box4 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge));
|
||||
const boxSize = getBoxSize(box4);
|
||||
const box5 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge));
|
||||
const boxSize = getBoxSize(box5);
|
||||
let crop2 = tf17.image.cropAndResize(face5, [[
|
||||
box4.startPoint[1] / meshSize,
|
||||
box4.startPoint[0] / meshSize,
|
||||
box4.endPoint[1] / meshSize,
|
||||
box4.endPoint[0] / meshSize
|
||||
box5.startPoint[1] / meshSize,
|
||||
box5.startPoint[0] / meshSize,
|
||||
box5.endPoint[1] / meshSize,
|
||||
box5.endPoint[0] / meshSize
|
||||
]], [0], [inputSize5, inputSize5]);
|
||||
if (flip && env.kernels.includes("flipleftright")) {
|
||||
const flipped = tf17.image.flipLeftRight(crop2);
|
||||
tf17.dispose(crop2);
|
||||
crop2 = flipped;
|
||||
}
|
||||
return { box: box4, boxSize, crop: crop2 };
|
||||
return { box: box5, boxSize, crop: crop2 };
|
||||
};
|
||||
var getEyeCoords = (eyeData, eyeBox, eyeBoxSize, flip = false) => {
|
||||
const eyeRawCoords = [];
|
||||
|
@ -6053,7 +6026,7 @@ async function predict10(input, config3) {
|
|||
const newCache = [];
|
||||
let id = 0;
|
||||
for (let i = 0; i < boxCache.length; i++) {
|
||||
let box4 = boxCache[i];
|
||||
let box5 = boxCache[i];
|
||||
let angle = 0;
|
||||
let rotationMatrix;
|
||||
const face5 = {
|
||||
|
@ -6067,20 +6040,20 @@ async function predict10(input, config3) {
|
|||
faceScore: 0,
|
||||
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) {
|
||||
const equilized = await histogramEqualization(face5.tensor);
|
||||
tf18.dispose(face5.tensor);
|
||||
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)) {
|
||||
face5.box = getClampedBox(box4, input);
|
||||
face5.boxRaw = getRawBox(box4, input);
|
||||
face5.box = getClampedBox(box5, input);
|
||||
face5.boxRaw = getRawBox(box5, input);
|
||||
face5.score = face5.boxScore;
|
||||
face5.mesh = box4.landmarks.map((pt) => [
|
||||
(box4.startPoint[0] + box4.endPoint[0]) / 2 + (box4.endPoint[0] + box4.startPoint[0]) * pt[0] / size(),
|
||||
(box4.startPoint[1] + box4.endPoint[1]) / 2 + (box4.endPoint[1] + box4.startPoint[1]) * pt[1] / size()
|
||||
face5.mesh = box5.landmarks.map((pt) => [
|
||||
(box5.startPoint[0] + box5.endPoint[0]) / 2 + (box5.endPoint[0] + box5.startPoint[0]) * pt[0] / 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]);
|
||||
for (const key of Object.keys(blazeFaceLandmarks))
|
||||
|
@ -6096,24 +6069,24 @@ async function predict10(input, config3) {
|
|||
let rawCoords = await coordsReshaped.array();
|
||||
tf18.dispose([contourCoords, coordsReshaped, confidence, contours]);
|
||||
if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
|
||||
box4.confidence = face5.faceScore;
|
||||
box5.confidence = face5.faceScore;
|
||||
} else {
|
||||
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
|
||||
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]);
|
||||
for (const key of Object.keys(meshAnnotations))
|
||||
face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]);
|
||||
const boxCalculated = calculateLandmarksBoundingBox(face5.mesh);
|
||||
const boxEnlarged = enlargeBox(boxCalculated, ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6);
|
||||
const boxSquared = squarifyBox(boxEnlarged);
|
||||
box4 = { ...boxSquared, confidence: box4.confidence };
|
||||
face5.box = getClampedBox(box4, input);
|
||||
face5.boxRaw = getRawBox(box4, input);
|
||||
box5 = { ...boxSquared, confidence: box5.confidence };
|
||||
face5.box = getClampedBox(box5, input);
|
||||
face5.boxRaw = getRawBox(box5, input);
|
||||
face5.score = face5.faceScore;
|
||||
newCache.push(box4);
|
||||
newCache.push(box5);
|
||||
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);
|
||||
|
@ -6226,54 +6199,54 @@ var tf21 = __toModule(require_tfjs_esm());
|
|||
|
||||
// src/hand/handposeutil.ts
|
||||
var tf20 = __toModule(require_tfjs_esm());
|
||||
function getBoxSize2(box4) {
|
||||
function getBoxSize2(box5) {
|
||||
return [
|
||||
Math.abs(box4.endPoint[0] - box4.startPoint[0]),
|
||||
Math.abs(box4.endPoint[1] - box4.startPoint[1])
|
||||
Math.abs(box5.endPoint[0] - box5.startPoint[0]),
|
||||
Math.abs(box5.endPoint[1] - box5.startPoint[1])
|
||||
];
|
||||
}
|
||||
function getBoxCenter2(box4) {
|
||||
function getBoxCenter2(box5) {
|
||||
return [
|
||||
box4.startPoint[0] + (box4.endPoint[0] - box4.startPoint[0]) / 2,
|
||||
box4.startPoint[1] + (box4.endPoint[1] - box4.startPoint[1]) / 2
|
||||
box5.startPoint[0] + (box5.endPoint[0] - box5.startPoint[0]) / 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 w = image29.shape[2];
|
||||
const boxes = [[
|
||||
box4.startPoint[1] / h,
|
||||
box4.startPoint[0] / w,
|
||||
box4.endPoint[1] / h,
|
||||
box4.endPoint[0] / w
|
||||
box5.startPoint[1] / h,
|
||||
box5.startPoint[0] / w,
|
||||
box5.endPoint[1] / h,
|
||||
box5.endPoint[0] / w
|
||||
]];
|
||||
return tf20.image.cropAndResize(image29, boxes, [0], cropSize);
|
||||
}
|
||||
function scaleBoxCoordinates2(box4, factor) {
|
||||
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]];
|
||||
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]];
|
||||
const palmLandmarks = box4.palmLandmarks.map((coord) => {
|
||||
function scaleBoxCoordinates2(box5, factor) {
|
||||
const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
|
||||
const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
|
||||
const palmLandmarks = box5.palmLandmarks.map((coord) => {
|
||||
const scaledCoord = [coord[0] * factor[0], coord[1] * factor[1]];
|
||||
return scaledCoord;
|
||||
});
|
||||
return { startPoint, endPoint, palmLandmarks, confidence: box4.confidence };
|
||||
return { startPoint, endPoint, palmLandmarks, confidence: box5.confidence };
|
||||
}
|
||||
function enlargeBox2(box4, factor = 1.5) {
|
||||
const center = getBoxCenter2(box4);
|
||||
const size2 = getBoxSize2(box4);
|
||||
function enlargeBox2(box5, factor = 1.5) {
|
||||
const center = getBoxCenter2(box5);
|
||||
const size2 = getBoxSize2(box5);
|
||||
const newHalfSize = [factor * size2[0] / 2, factor * size2[1] / 2];
|
||||
const startPoint = [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) {
|
||||
const centers = getBoxCenter2(box4);
|
||||
const size2 = getBoxSize2(box4);
|
||||
function squarifyBox2(box5) {
|
||||
const centers = getBoxCenter2(box5);
|
||||
const size2 = getBoxSize2(box5);
|
||||
const maxEdge = Math.max(...size2);
|
||||
const halfSize = maxEdge / 2;
|
||||
const startPoint = [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) {
|
||||
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.norm = this.normalizeLandmarks(p.slice, index2);
|
||||
p.palmLandmarks = tf21.reshape(p.norm, [-1, 2]);
|
||||
const box4 = await p.box.data();
|
||||
const startPoint = box4.slice(0, 2);
|
||||
const endPoint = box4.slice(2, 4);
|
||||
const box5 = await p.box.data();
|
||||
const startPoint = box5.slice(0, 2);
|
||||
const endPoint = box5.slice(2, 4);
|
||||
const palmLandmarks = await p.palmLandmarks.array();
|
||||
const hand3 = { startPoint, endPoint, palmLandmarks, confidence: scores[index2] };
|
||||
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;
|
||||
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];
|
||||
if (keypoints && keypoints.length > 0) {
|
||||
for (const pt of keypoints) {
|
||||
if (pt[0] < box4[0])
|
||||
box4[0] = pt[0];
|
||||
if (pt[1] < box4[1])
|
||||
box4[1] = pt[1];
|
||||
if (pt[0] > box4[2])
|
||||
box4[2] = pt[0];
|
||||
if (pt[1] > box4[3])
|
||||
box4[3] = pt[1];
|
||||
if (pt[0] < box5[0])
|
||||
box5[0] = pt[0];
|
||||
if (pt[1] < box5[1])
|
||||
box5[1] = pt[1];
|
||||
if (pt[0] > box5[2])
|
||||
box5[2] = pt[0];
|
||||
if (pt[1] > box5[3])
|
||||
box5[3] = pt[1];
|
||||
}
|
||||
box4[2] -= box4[0];
|
||||
box4[3] -= box4[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)];
|
||||
box5[2] -= box5[0];
|
||||
box5[3] -= box5[1];
|
||||
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 {
|
||||
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[1])),
|
||||
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,
|
||||
fingerScore: Math.round(100 * predictions[i].fingerConfidence) / 100,
|
||||
label: "hand",
|
||||
box: box4,
|
||||
box: box5,
|
||||
boxRaw,
|
||||
keypoints,
|
||||
annotations: annotations2,
|
||||
|
@ -10014,40 +9987,6 @@ async function load13(config3) {
|
|||
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
|
||||
var tf24 = __toModule(require_tfjs_esm());
|
||||
var models2 = [null, null];
|
||||
|
@ -10066,11 +10005,11 @@ var cache3 = {
|
|||
hands: []
|
||||
};
|
||||
var fingerMap = {
|
||||
thumb: [1, 2, 3, 4],
|
||||
index: [5, 6, 7, 8],
|
||||
middle: [9, 10, 11, 12],
|
||||
ring: [13, 14, 15, 16],
|
||||
pinky: [17, 18, 19, 20],
|
||||
thumb: [0, 1, 2, 3, 4],
|
||||
index: [0, 5, 6, 7, 8],
|
||||
middle: [0, 9, 10, 11, 12],
|
||||
ring: [0, 13, 14, 15, 16],
|
||||
pinky: [0, 17, 18, 19, 20],
|
||||
palm: [0]
|
||||
};
|
||||
async function loadDetect2(config3) {
|
||||
|
@ -10621,7 +10560,7 @@ async function process4(res, inputSize9, outputShape, config3) {
|
|||
];
|
||||
let boxRaw = [x, y, w, h];
|
||||
boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1)));
|
||||
const box4 = [
|
||||
const box5 = [
|
||||
boxRaw[0] * outputShape[0],
|
||||
boxRaw[1] * outputShape[1],
|
||||
boxRaw[2] * outputShape[0],
|
||||
|
@ -10632,7 +10571,7 @@ async function process4(res, inputSize9, outputShape, config3) {
|
|||
score: Math.round(100 * score) / 100,
|
||||
class: j + 1,
|
||||
label: labels[j].label,
|
||||
box: box4.map((a) => Math.trunc(a)),
|
||||
box: box5.map((a) => Math.trunc(a)),
|
||||
boxRaw
|
||||
};
|
||||
results.push(result);
|
||||
|
@ -10975,7 +10914,7 @@ function getInstanceScore(existingPoses, keypoints) {
|
|||
}, 0);
|
||||
return notOverlappedKeypointScores / keypoints.length;
|
||||
}
|
||||
function decode2(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) {
|
||||
function decode(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) {
|
||||
const poses = [];
|
||||
const queue = buildPartWithScoreQueue(minConfidence2, scores);
|
||||
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);
|
||||
keypoints = keypoints.filter((a) => a.score > minConfidence2);
|
||||
const score = getInstanceScore(poses, keypoints);
|
||||
const box4 = getBoundingBox(keypoints);
|
||||
const box5 = getBoundingBox(keypoints);
|
||||
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;
|
||||
}
|
||||
|
@ -11006,7 +10945,7 @@ async function predict17(input, config3) {
|
|||
const buffers = await Promise.all(res.map((tensor3) => tensor3.buffer()));
|
||||
for (const t of res)
|
||||
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)
|
||||
return [];
|
||||
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;
|
||||
if (isNaN(thetaZ))
|
||||
thetaZ = 0;
|
||||
return { pitch: 2 * -thetaX, yaw: 2 * -thetaY, roll: 2 * -thetaZ };
|
||||
return { pitch: -thetaX, yaw: -thetaY, roll: -thetaZ };
|
||||
};
|
||||
const meshToEulerAngle = (mesh2) => {
|
||||
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));
|
||||
} else {
|
||||
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 keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({
|
||||
score: newKpt.score,
|
||||
|
@ -12445,14 +12384,14 @@ function calc2(newResult, config3) {
|
|||
}
|
||||
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) {
|
||||
bufferedResult.hand = JSON.parse(JSON.stringify(newResult.hand));
|
||||
} else {
|
||||
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);
|
||||
if (bufferedResult.hand[i].keypoints.length !== newResult.hand[i].keypoints.length)
|
||||
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;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
bufferedResult.face = JSON.parse(JSON.stringify(newResult.face));
|
||||
} else {
|
||||
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);
|
||||
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 } };
|
||||
|
@ -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,
|
||||
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) {
|
||||
bufferedResult.object = JSON.parse(JSON.stringify(newResult.object));
|
||||
} else {
|
||||
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);
|
||||
bufferedResult.object[i] = { ...newResult.object[i], box: box4, boxRaw };
|
||||
bufferedResult.object[i] = { ...newResult.object[i], box: box5, boxRaw };
|
||||
}
|
||||
}
|
||||
if (newResult.persons) {
|
||||
|
@ -12507,7 +12446,7 @@ function calc2(newResult, config3) {
|
|||
bufferedResult.persons = JSON.parse(JSON.stringify(newPersons));
|
||||
} else {
|
||||
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 y = [];
|
||||
const extractXY = (box4) => {
|
||||
if (box4 && box4.length === 4) {
|
||||
x.push(box4[0], box4[0] + box4[2]);
|
||||
y.push(box4[1], box4[1] + box4[3]);
|
||||
const extractXY = (box5) => {
|
||||
if (box5 && box5.length === 4) {
|
||||
x.push(box5[0], box5[0] + box5[2]);
|
||||
y.push(box5[1], box5[1] + box5[3]);
|
||||
}
|
||||
};
|
||||
extractXY((_k = person2.face) == null ? void 0 : _k.box);
|
||||
|
|
|
@ -981,8 +981,8 @@ function GLImageFilter() {
|
|||
// src/image/enhance.ts
|
||||
var tf = __toModule(require_tfjs_esm());
|
||||
async function histogramEqualization(inputImage) {
|
||||
const squeeze11 = inputImage.shape.length === 4 ? tf.squeeze(inputImage) : inputImage;
|
||||
const channels = tf.split(squeeze11, 3, 2);
|
||||
const squeeze10 = inputImage.shape.length === 4 ? tf.squeeze(inputImage) : inputImage;
|
||||
const channels = tf.split(squeeze10, 3, 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 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 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 reshape8 = tf.reshape(rgb2, [1, squeeze11.shape[0], squeeze11.shape[1], 3]);
|
||||
tf.dispose([...channels, ...min2, ...max4, ...sub10, ...range, ...fact, ...enh, rgb2, squeeze11]);
|
||||
const reshape8 = tf.reshape(rgb2, [1, squeeze10.shape[0], squeeze10.shape[1], 3]);
|
||||
tf.dispose([...channels, ...min2, ...max4, ...sub10, ...range, ...fact, ...enh, rgb2, squeeze10]);
|
||||
return reshape8;
|
||||
}
|
||||
|
||||
|
@ -1415,8 +1415,8 @@ async function predict(image29, config3, idx, count2) {
|
|||
if (!(model == null ? void 0 : model.inputs[0].shape))
|
||||
return;
|
||||
const t = {};
|
||||
const box4 = [[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]]);
|
||||
const box5 = [[0, 0.1, 0.9, 0.9]];
|
||||
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: [] };
|
||||
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"]);
|
||||
|
@ -4912,44 +4912,44 @@ var UV33 = VTX33.map((x) => UV468[x]);
|
|||
var UV7 = VTX7.map((x) => UV468[x]);
|
||||
|
||||
// src/face/facemeshutil.ts
|
||||
var getBoxSize = (box4) => [Math.abs(box4.endPoint[0] - box4.startPoint[0]), Math.abs(box4.endPoint[1] - box4.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 getClampedBox = (box4, input) => box4 ? [
|
||||
Math.trunc(Math.max(0, box4.startPoint[0])),
|
||||
Math.trunc(Math.max(0, box4.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[1] || 0, box4.endPoint[1]) - Math.max(0, box4.startPoint[1]))
|
||||
var getBoxSize = (box5) => [Math.abs(box5.endPoint[0] - box5.startPoint[0]), Math.abs(box5.endPoint[1] - box5.startPoint[1])];
|
||||
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 = (box5, input) => box5 ? [
|
||||
Math.trunc(Math.max(0, box5.startPoint[0])),
|
||||
Math.trunc(Math.max(0, box5.startPoint[1])),
|
||||
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, box5.endPoint[1]) - Math.max(0, box5.startPoint[1]))
|
||||
] : [0, 0, 0, 0];
|
||||
var getRawBox = (box4, input) => box4 ? [
|
||||
box4.startPoint[0] / (input.shape[2] || 0),
|
||||
box4.startPoint[1] / (input.shape[1] || 0),
|
||||
(box4.endPoint[0] - box4.startPoint[0]) / (input.shape[2] || 0),
|
||||
(box4.endPoint[1] - box4.startPoint[1]) / (input.shape[1] || 0)
|
||||
var getRawBox = (box5, input) => box5 ? [
|
||||
box5.startPoint[0] / (input.shape[2] || 0),
|
||||
box5.startPoint[1] / (input.shape[1] || 0),
|
||||
(box5.endPoint[0] - box5.startPoint[0]) / (input.shape[2] || 0),
|
||||
(box5.endPoint[1] - box5.startPoint[1]) / (input.shape[1] || 0)
|
||||
] : [0, 0, 0, 0];
|
||||
var scaleBoxCoordinates = (box4, factor) => {
|
||||
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]];
|
||||
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]];
|
||||
return { startPoint, endPoint, landmarks: box4.landmarks, confidence: box4.confidence };
|
||||
var scaleBoxCoordinates = (box5, factor) => {
|
||||
const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
|
||||
const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
|
||||
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 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);
|
||||
tf9.dispose(crop2);
|
||||
return norm;
|
||||
};
|
||||
var enlargeBox = (box4, factor) => {
|
||||
const center = getBoxCenter(box4);
|
||||
const size2 = getBoxSize(box4);
|
||||
var enlargeBox = (box5, factor) => {
|
||||
const center = getBoxCenter(box5);
|
||||
const size2 = getBoxSize(box5);
|
||||
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) => {
|
||||
const centers = getBoxCenter(box4);
|
||||
const size2 = getBoxSize(box4);
|
||||
var squarifyBox = (box5) => {
|
||||
const centers = getBoxCenter(box5);
|
||||
const size2 = getBoxSize(box5);
|
||||
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) => {
|
||||
const xs = landmarks.map((d) => d[0]);
|
||||
|
@ -5017,8 +5017,8 @@ function generateAnchors(inputSize9) {
|
|||
}
|
||||
return anchors4;
|
||||
}
|
||||
function transformRawCoords(coordsRaw, box4, angle, rotationMatrix, inputSize9) {
|
||||
const boxSize = getBoxSize(box4);
|
||||
function transformRawCoords(coordsRaw, box5, angle, rotationMatrix, inputSize9) {
|
||||
const boxSize = getBoxSize(box5);
|
||||
const coordsScaled = coordsRaw.map((coord) => [
|
||||
boxSize[0] / inputSize9 * (coord[0] - 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 coordsRotated = largeAngle ? coordsScaled.map((coord) => [...rotatePoint(coord, coordsRotationMatrix), coord[2]]) : coordsScaled;
|
||||
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) => [
|
||||
Math.round(coord[0] + dot(boxCenter, inverseRotationMatrix[0])),
|
||||
Math.round(coord[1] + dot(boxCenter, inverseRotationMatrix[1])),
|
||||
Math.round(coord[2] || 0)
|
||||
]);
|
||||
}
|
||||
function correctFaceRotation(rotate, box4, input, inputSize9) {
|
||||
const symmetryLine = box4.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine;
|
||||
function correctFaceRotation(rotate, box5, input, inputSize9) {
|
||||
const symmetryLine = box5.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine;
|
||||
let angle = 0;
|
||||
let rotationMatrix = fixedRotationMatrix;
|
||||
let face5;
|
||||
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;
|
||||
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 rotated = tf9.image.rotateWithOffset(input, angle, 0, centerRaw);
|
||||
rotationMatrix = buildRotationMatrix(-angle, center);
|
||||
face5 = cutBoxFromImageAndResize(box4, rotated, [inputSize9, inputSize9]);
|
||||
face5 = cutBoxFromImageAndResize(box5, rotated, [inputSize9, inputSize9]);
|
||||
tf9.dispose(rotated);
|
||||
} else {
|
||||
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]);
|
||||
face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
|
||||
}
|
||||
} else {
|
||||
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]);
|
||||
face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
|
||||
}
|
||||
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)) };
|
||||
}
|
||||
var cropFactor = [5, 5];
|
||||
function decodeBoxes(boxesTensor, anchor) {
|
||||
return tf11.tidy(() => {
|
||||
const split5 = tf11.split(boxesTensor, 12, 1);
|
||||
let xCenter = tf11.squeeze(split5[0]);
|
||||
let yCenter = tf11.squeeze(split5[1]);
|
||||
let width = tf11.squeeze(split5[2]);
|
||||
let height = tf11.squeeze(split5[3]);
|
||||
xCenter = tf11.add(tf11.div(xCenter, inputSize2), anchor.x);
|
||||
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;
|
||||
});
|
||||
|
||||
// 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 box5 = [min2[0], min2[1], max4[0] - min2[0], max4[1] - min2[1]];
|
||||
const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
|
||||
return { box: box5, boxRaw };
|
||||
}
|
||||
async function decode(boxesTensor, logitsTensor, config3, outputSize2) {
|
||||
const t = {};
|
||||
t.boxes = decodeBoxes(boxesTensor, anchorTensor);
|
||||
t.scores = tf11.sigmoid(logitsTensor);
|
||||
t.argmax = tf11.argMax(t.scores);
|
||||
const i = (await t.argmax.data())[0];
|
||||
const scores = await t.scores.data();
|
||||
const detected = [];
|
||||
const minScore = config3.body["detector"] && config3.body["detector"]["minConfidence"] ? config3.body["detector"]["minConfidence"] : 0;
|
||||
if (scores[i] >= minScore) {
|
||||
const boxes = await t.boxes.array();
|
||||
const boxRaw = boxes[i];
|
||||
const box4 = [boxRaw[0] * outputSize2[0], boxRaw[1] * outputSize2[1], boxRaw[2] * outputSize2[0], boxRaw[3] * outputSize2[1]];
|
||||
detected.push({ box: box4, boxRaw, score: scores[i] });
|
||||
}
|
||||
Object.keys(t).forEach((tensor3) => tf11.dispose(t[tensor3]));
|
||||
return detected;
|
||||
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 box5 = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];
|
||||
const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
|
||||
return { box: box5, boxRaw };
|
||||
}
|
||||
function scale(box5, scaleFact) {
|
||||
const dist = [box5[2] * scaleFact, box5[3] * scaleFact];
|
||||
const newBox = [
|
||||
box5[0] - (dist[0] - box5[2]) / 2,
|
||||
box5[1] - (dist[1] - box5[3]) / 2,
|
||||
dist[0],
|
||||
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
|
||||
|
@ -5286,7 +5284,7 @@ var outputNodes = {
|
|||
detector: []
|
||||
};
|
||||
var cache = null;
|
||||
var lastBox;
|
||||
var cropBox;
|
||||
var padding = [[0, 0], [0, 0], [0, 0], [0, 0]];
|
||||
var lastTime5 = 0;
|
||||
var sigmoid3 = (x) => 1 - 1 / (1 + Math.exp(x));
|
||||
|
@ -5323,39 +5321,37 @@ async function loadPose(config3) {
|
|||
log("cached model:", models.landmarks["modelUrl"]);
|
||||
return models.landmarks;
|
||||
}
|
||||
function calculateBoxes(keypoints, outputSize2) {
|
||||
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) {
|
||||
async function prepareImage(input, size2) {
|
||||
const t = {};
|
||||
if (!input.shape || !input.shape[1] || !input.shape[2])
|
||||
return input;
|
||||
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]) {
|
||||
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 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];
|
||||
const height = [
|
||||
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 = [
|
||||
[0, 0],
|
||||
height,
|
||||
width,
|
||||
[0, 0]
|
||||
];
|
||||
if (box4) {
|
||||
t.resize = tf12.image.cropAndResize(input, [box4], [0], [size2, size2]);
|
||||
} else {
|
||||
t.pad = tf12.pad(input, padding);
|
||||
t.resize = tf12.image.resizeBilinear(t.pad, [size2, size2]);
|
||||
}
|
||||
t.pad = tf12.pad(t.cropped || input, padding);
|
||||
t.resize = tf12.image.resizeBilinear(t.pad, [size2, size2]);
|
||||
final = tf12.div(t.resize, constants.tf255);
|
||||
} 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);
|
||||
} else {
|
||||
final = tf12.div(input, constants.tf255);
|
||||
final = tf12.div(t.cropped || input, constants.tf255);
|
||||
}
|
||||
Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3]));
|
||||
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]];
|
||||
}
|
||||
return keypoints;
|
||||
}
|
||||
function rescaleBoxes(boxes, outputSize2) {
|
||||
for (const box4 of boxes) {
|
||||
box4.box = [
|
||||
Math.trunc(box4.box[0] * (outputSize2[0] + padding[2][0] + padding[2][1]) / outputSize2[0]),
|
||||
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]),
|
||||
Math.trunc(box4.box[3] * (outputSize2[1] + padding[1][0] + padding[1][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]];
|
||||
if (cropBox) {
|
||||
for (const kpt4 of keypoints) {
|
||||
kpt4.positionRaw = [
|
||||
kpt4.positionRaw[0] + cropBox[1],
|
||||
kpt4.positionRaw[1] + cropBox[0],
|
||||
kpt4.positionRaw[2]
|
||||
];
|
||||
kpt4.position = [
|
||||
Math.trunc(kpt4.positionRaw[0] * outputSize2[0]),
|
||||
Math.trunc(kpt4.positionRaw[1] * outputSize2[1]),
|
||||
kpt4.positionRaw[2]
|
||||
];
|
||||
}
|
||||
}
|
||||
return boxes;
|
||||
return keypoints;
|
||||
}
|
||||
async function detectLandmarks(input, config3, outputSize2) {
|
||||
var _a;
|
||||
|
@ -5403,7 +5401,8 @@ async function detectLandmarks(input, config3, outputSize2) {
|
|||
if (poseScore < (config3.body.minConfidence || 0))
|
||||
return null;
|
||||
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 = {};
|
||||
for (const [name, indexes] of Object.entries(connected)) {
|
||||
const pt = [];
|
||||
|
@ -5415,22 +5414,9 @@ async function detectLandmarks(input, config3, outputSize2) {
|
|||
}
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
const outputSize2 = [input.shape[2] || 0, input.shape[1] || 0];
|
||||
const skipTime = (config3.body.skipTime || 0) > now() - lastTime5;
|
||||
|
@ -5439,26 +5425,13 @@ async function predict5(input, config3) {
|
|||
skipped5++;
|
||||
} else {
|
||||
const t = {};
|
||||
if (config3.body["detector"] && config3.body["detector"]["enabled"]) {
|
||||
t.detector = await prepareImage(input, 224);
|
||||
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);
|
||||
}
|
||||
t.landmarks = await prepareImage(input, 256);
|
||||
cache = await detectLandmarks(t.landmarks, config3, outputSize2);
|
||||
Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3]));
|
||||
lastTime5 = now();
|
||||
skipped5 = 0;
|
||||
}
|
||||
if (cache)
|
||||
return [cache];
|
||||
return [];
|
||||
return cache ? [cache] : [];
|
||||
}
|
||||
|
||||
// src/object/centernet.ts
|
||||
|
@ -5599,13 +5572,13 @@ async function process3(res, outputShape, config3) {
|
|||
detections[0][id][2] / inputSize4 - x,
|
||||
detections[0][id][3] / inputSize4 - y
|
||||
];
|
||||
const box4 = [
|
||||
const box5 = [
|
||||
Math.trunc(boxRaw[0] * outputShape[0]),
|
||||
Math.trunc(boxRaw[1] * outputShape[1]),
|
||||
Math.trunc(boxRaw[2] * outputShape[0]),
|
||||
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]));
|
||||
return results;
|
||||
|
@ -5726,10 +5699,10 @@ async function predict7(image29, config3) {
|
|||
tf14.dispose(tensor3);
|
||||
if (resT) {
|
||||
cache2.keypoints.length = 0;
|
||||
const squeeze11 = resT.squeeze();
|
||||
const squeeze10 = resT.squeeze();
|
||||
tf14.dispose(resT);
|
||||
const stack5 = squeeze11.unstack(2);
|
||||
tf14.dispose(squeeze11);
|
||||
const stack5 = squeeze10.unstack(2);
|
||||
tf14.dispose(squeeze10);
|
||||
for (let id = 0; id < stack5.length; id++) {
|
||||
const [x2, y2, partScore] = await max2d(stack5[id], config3.body.minConfidence);
|
||||
if (partScore > (((_a = config3.body) == null ? void 0 : _a.minConfidence) || 0)) {
|
||||
|
@ -5947,20 +5920,20 @@ var getLeftToRightEyeDepthDifference = (rawCoords) => {
|
|||
return leftEyeZ - rightEyeZ;
|
||||
};
|
||||
var getEyeBox = (rawCoords, face5, eyeInnerCornerIndex, eyeOuterCornerIndex, meshSize, flip = false) => {
|
||||
const box4 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge));
|
||||
const boxSize = getBoxSize(box4);
|
||||
const box5 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge));
|
||||
const boxSize = getBoxSize(box5);
|
||||
let crop2 = tf17.image.cropAndResize(face5, [[
|
||||
box4.startPoint[1] / meshSize,
|
||||
box4.startPoint[0] / meshSize,
|
||||
box4.endPoint[1] / meshSize,
|
||||
box4.endPoint[0] / meshSize
|
||||
box5.startPoint[1] / meshSize,
|
||||
box5.startPoint[0] / meshSize,
|
||||
box5.endPoint[1] / meshSize,
|
||||
box5.endPoint[0] / meshSize
|
||||
]], [0], [inputSize5, inputSize5]);
|
||||
if (flip && env.kernels.includes("flipleftright")) {
|
||||
const flipped = tf17.image.flipLeftRight(crop2);
|
||||
tf17.dispose(crop2);
|
||||
crop2 = flipped;
|
||||
}
|
||||
return { box: box4, boxSize, crop: crop2 };
|
||||
return { box: box5, boxSize, crop: crop2 };
|
||||
};
|
||||
var getEyeCoords = (eyeData, eyeBox, eyeBoxSize, flip = false) => {
|
||||
const eyeRawCoords = [];
|
||||
|
@ -6054,7 +6027,7 @@ async function predict10(input, config3) {
|
|||
const newCache = [];
|
||||
let id = 0;
|
||||
for (let i = 0; i < boxCache.length; i++) {
|
||||
let box4 = boxCache[i];
|
||||
let box5 = boxCache[i];
|
||||
let angle = 0;
|
||||
let rotationMatrix;
|
||||
const face5 = {
|
||||
|
@ -6068,20 +6041,20 @@ async function predict10(input, config3) {
|
|||
faceScore: 0,
|
||||
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) {
|
||||
const equilized = await histogramEqualization(face5.tensor);
|
||||
tf18.dispose(face5.tensor);
|
||||
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)) {
|
||||
face5.box = getClampedBox(box4, input);
|
||||
face5.boxRaw = getRawBox(box4, input);
|
||||
face5.box = getClampedBox(box5, input);
|
||||
face5.boxRaw = getRawBox(box5, input);
|
||||
face5.score = face5.boxScore;
|
||||
face5.mesh = box4.landmarks.map((pt) => [
|
||||
(box4.startPoint[0] + box4.endPoint[0]) / 2 + (box4.endPoint[0] + box4.startPoint[0]) * pt[0] / size(),
|
||||
(box4.startPoint[1] + box4.endPoint[1]) / 2 + (box4.endPoint[1] + box4.startPoint[1]) * pt[1] / size()
|
||||
face5.mesh = box5.landmarks.map((pt) => [
|
||||
(box5.startPoint[0] + box5.endPoint[0]) / 2 + (box5.endPoint[0] + box5.startPoint[0]) * pt[0] / 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]);
|
||||
for (const key of Object.keys(blazeFaceLandmarks))
|
||||
|
@ -6097,24 +6070,24 @@ async function predict10(input, config3) {
|
|||
let rawCoords = await coordsReshaped.array();
|
||||
tf18.dispose([contourCoords, coordsReshaped, confidence, contours]);
|
||||
if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
|
||||
box4.confidence = face5.faceScore;
|
||||
box5.confidence = face5.faceScore;
|
||||
} else {
|
||||
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
|
||||
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]);
|
||||
for (const key of Object.keys(meshAnnotations))
|
||||
face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]);
|
||||
const boxCalculated = calculateLandmarksBoundingBox(face5.mesh);
|
||||
const boxEnlarged = enlargeBox(boxCalculated, ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6);
|
||||
const boxSquared = squarifyBox(boxEnlarged);
|
||||
box4 = { ...boxSquared, confidence: box4.confidence };
|
||||
face5.box = getClampedBox(box4, input);
|
||||
face5.boxRaw = getRawBox(box4, input);
|
||||
box5 = { ...boxSquared, confidence: box5.confidence };
|
||||
face5.box = getClampedBox(box5, input);
|
||||
face5.boxRaw = getRawBox(box5, input);
|
||||
face5.score = face5.faceScore;
|
||||
newCache.push(box4);
|
||||
newCache.push(box5);
|
||||
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);
|
||||
|
@ -6227,54 +6200,54 @@ var tf21 = __toModule(require_tfjs_esm());
|
|||
|
||||
// src/hand/handposeutil.ts
|
||||
var tf20 = __toModule(require_tfjs_esm());
|
||||
function getBoxSize2(box4) {
|
||||
function getBoxSize2(box5) {
|
||||
return [
|
||||
Math.abs(box4.endPoint[0] - box4.startPoint[0]),
|
||||
Math.abs(box4.endPoint[1] - box4.startPoint[1])
|
||||
Math.abs(box5.endPoint[0] - box5.startPoint[0]),
|
||||
Math.abs(box5.endPoint[1] - box5.startPoint[1])
|
||||
];
|
||||
}
|
||||
function getBoxCenter2(box4) {
|
||||
function getBoxCenter2(box5) {
|
||||
return [
|
||||
box4.startPoint[0] + (box4.endPoint[0] - box4.startPoint[0]) / 2,
|
||||
box4.startPoint[1] + (box4.endPoint[1] - box4.startPoint[1]) / 2
|
||||
box5.startPoint[0] + (box5.endPoint[0] - box5.startPoint[0]) / 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 w = image29.shape[2];
|
||||
const boxes = [[
|
||||
box4.startPoint[1] / h,
|
||||
box4.startPoint[0] / w,
|
||||
box4.endPoint[1] / h,
|
||||
box4.endPoint[0] / w
|
||||
box5.startPoint[1] / h,
|
||||
box5.startPoint[0] / w,
|
||||
box5.endPoint[1] / h,
|
||||
box5.endPoint[0] / w
|
||||
]];
|
||||
return tf20.image.cropAndResize(image29, boxes, [0], cropSize);
|
||||
}
|
||||
function scaleBoxCoordinates2(box4, factor) {
|
||||
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]];
|
||||
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]];
|
||||
const palmLandmarks = box4.palmLandmarks.map((coord) => {
|
||||
function scaleBoxCoordinates2(box5, factor) {
|
||||
const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
|
||||
const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
|
||||
const palmLandmarks = box5.palmLandmarks.map((coord) => {
|
||||
const scaledCoord = [coord[0] * factor[0], coord[1] * factor[1]];
|
||||
return scaledCoord;
|
||||
});
|
||||
return { startPoint, endPoint, palmLandmarks, confidence: box4.confidence };
|
||||
return { startPoint, endPoint, palmLandmarks, confidence: box5.confidence };
|
||||
}
|
||||
function enlargeBox2(box4, factor = 1.5) {
|
||||
const center = getBoxCenter2(box4);
|
||||
const size2 = getBoxSize2(box4);
|
||||
function enlargeBox2(box5, factor = 1.5) {
|
||||
const center = getBoxCenter2(box5);
|
||||
const size2 = getBoxSize2(box5);
|
||||
const newHalfSize = [factor * size2[0] / 2, factor * size2[1] / 2];
|
||||
const startPoint = [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) {
|
||||
const centers = getBoxCenter2(box4);
|
||||
const size2 = getBoxSize2(box4);
|
||||
function squarifyBox2(box5) {
|
||||
const centers = getBoxCenter2(box5);
|
||||
const size2 = getBoxSize2(box5);
|
||||
const maxEdge = Math.max(...size2);
|
||||
const halfSize = maxEdge / 2;
|
||||
const startPoint = [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) {
|
||||
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.norm = this.normalizeLandmarks(p.slice, index2);
|
||||
p.palmLandmarks = tf21.reshape(p.norm, [-1, 2]);
|
||||
const box4 = await p.box.data();
|
||||
const startPoint = box4.slice(0, 2);
|
||||
const endPoint = box4.slice(2, 4);
|
||||
const box5 = await p.box.data();
|
||||
const startPoint = box5.slice(0, 2);
|
||||
const endPoint = box5.slice(2, 4);
|
||||
const palmLandmarks = await p.palmLandmarks.array();
|
||||
const hand3 = { startPoint, endPoint, palmLandmarks, confidence: scores[index2] };
|
||||
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;
|
||||
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];
|
||||
if (keypoints && keypoints.length > 0) {
|
||||
for (const pt of keypoints) {
|
||||
if (pt[0] < box4[0])
|
||||
box4[0] = pt[0];
|
||||
if (pt[1] < box4[1])
|
||||
box4[1] = pt[1];
|
||||
if (pt[0] > box4[2])
|
||||
box4[2] = pt[0];
|
||||
if (pt[1] > box4[3])
|
||||
box4[3] = pt[1];
|
||||
if (pt[0] < box5[0])
|
||||
box5[0] = pt[0];
|
||||
if (pt[1] < box5[1])
|
||||
box5[1] = pt[1];
|
||||
if (pt[0] > box5[2])
|
||||
box5[2] = pt[0];
|
||||
if (pt[1] > box5[3])
|
||||
box5[3] = pt[1];
|
||||
}
|
||||
box4[2] -= box4[0];
|
||||
box4[3] -= box4[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)];
|
||||
box5[2] -= box5[0];
|
||||
box5[3] -= box5[1];
|
||||
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 {
|
||||
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[1])),
|
||||
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,
|
||||
fingerScore: Math.round(100 * predictions[i].fingerConfidence) / 100,
|
||||
label: "hand",
|
||||
box: box4,
|
||||
box: box5,
|
||||
boxRaw,
|
||||
keypoints,
|
||||
annotations: annotations2,
|
||||
|
@ -10015,40 +9988,6 @@ async function load13(config3) {
|
|||
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
|
||||
var tf24 = __toModule(require_tfjs_esm());
|
||||
var models2 = [null, null];
|
||||
|
@ -10067,11 +10006,11 @@ var cache3 = {
|
|||
hands: []
|
||||
};
|
||||
var fingerMap = {
|
||||
thumb: [1, 2, 3, 4],
|
||||
index: [5, 6, 7, 8],
|
||||
middle: [9, 10, 11, 12],
|
||||
ring: [13, 14, 15, 16],
|
||||
pinky: [17, 18, 19, 20],
|
||||
thumb: [0, 1, 2, 3, 4],
|
||||
index: [0, 5, 6, 7, 8],
|
||||
middle: [0, 9, 10, 11, 12],
|
||||
ring: [0, 13, 14, 15, 16],
|
||||
pinky: [0, 17, 18, 19, 20],
|
||||
palm: [0]
|
||||
};
|
||||
async function loadDetect2(config3) {
|
||||
|
@ -10622,7 +10561,7 @@ async function process4(res, inputSize9, outputShape, config3) {
|
|||
];
|
||||
let boxRaw = [x, y, w, h];
|
||||
boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1)));
|
||||
const box4 = [
|
||||
const box5 = [
|
||||
boxRaw[0] * outputShape[0],
|
||||
boxRaw[1] * outputShape[1],
|
||||
boxRaw[2] * outputShape[0],
|
||||
|
@ -10633,7 +10572,7 @@ async function process4(res, inputSize9, outputShape, config3) {
|
|||
score: Math.round(100 * score) / 100,
|
||||
class: j + 1,
|
||||
label: labels[j].label,
|
||||
box: box4.map((a) => Math.trunc(a)),
|
||||
box: box5.map((a) => Math.trunc(a)),
|
||||
boxRaw
|
||||
};
|
||||
results.push(result);
|
||||
|
@ -10976,7 +10915,7 @@ function getInstanceScore(existingPoses, keypoints) {
|
|||
}, 0);
|
||||
return notOverlappedKeypointScores / keypoints.length;
|
||||
}
|
||||
function decode2(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) {
|
||||
function decode(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) {
|
||||
const poses = [];
|
||||
const queue = buildPartWithScoreQueue(minConfidence2, scores);
|
||||
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);
|
||||
keypoints = keypoints.filter((a) => a.score > minConfidence2);
|
||||
const score = getInstanceScore(poses, keypoints);
|
||||
const box4 = getBoundingBox(keypoints);
|
||||
const box5 = getBoundingBox(keypoints);
|
||||
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;
|
||||
}
|
||||
|
@ -11007,7 +10946,7 @@ async function predict17(input, config3) {
|
|||
const buffers = await Promise.all(res.map((tensor3) => tensor3.buffer()));
|
||||
for (const t of res)
|
||||
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)
|
||||
return [];
|
||||
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;
|
||||
if (isNaN(thetaZ))
|
||||
thetaZ = 0;
|
||||
return { pitch: 2 * -thetaX, yaw: 2 * -thetaY, roll: 2 * -thetaZ };
|
||||
return { pitch: -thetaX, yaw: -thetaY, roll: -thetaZ };
|
||||
};
|
||||
const meshToEulerAngle = (mesh2) => {
|
||||
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));
|
||||
} else {
|
||||
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 keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({
|
||||
score: newKpt.score,
|
||||
|
@ -12446,14 +12385,14 @@ function calc2(newResult, config3) {
|
|||
}
|
||||
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) {
|
||||
bufferedResult.hand = JSON.parse(JSON.stringify(newResult.hand));
|
||||
} else {
|
||||
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);
|
||||
if (bufferedResult.hand[i].keypoints.length !== newResult.hand[i].keypoints.length)
|
||||
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;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
bufferedResult.face = JSON.parse(JSON.stringify(newResult.face));
|
||||
} else {
|
||||
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);
|
||||
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 } };
|
||||
|
@ -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,
|
||||
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) {
|
||||
bufferedResult.object = JSON.parse(JSON.stringify(newResult.object));
|
||||
} else {
|
||||
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);
|
||||
bufferedResult.object[i] = { ...newResult.object[i], box: box4, boxRaw };
|
||||
bufferedResult.object[i] = { ...newResult.object[i], box: box5, boxRaw };
|
||||
}
|
||||
}
|
||||
if (newResult.persons) {
|
||||
|
@ -12508,7 +12447,7 @@ function calc2(newResult, config3) {
|
|||
bufferedResult.persons = JSON.parse(JSON.stringify(newPersons));
|
||||
} else {
|
||||
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 y = [];
|
||||
const extractXY = (box4) => {
|
||||
if (box4 && box4.length === 4) {
|
||||
x.push(box4[0], box4[0] + box4[2]);
|
||||
y.push(box4[1], box4[1] + box4[3]);
|
||||
const extractXY = (box5) => {
|
||||
if (box5 && box5.length === 4) {
|
||||
x.push(box5[0], box5[0] + box5[2]);
|
||||
y.push(box5[1], box5[1] + box5[3]);
|
||||
}
|
||||
};
|
||||
extractXY((_k = person2.face) == null ? void 0 : _k.box);
|
||||
|
|
|
@ -980,8 +980,8 @@ function GLImageFilter() {
|
|||
// src/image/enhance.ts
|
||||
var tf = __toModule(require_tfjs_esm());
|
||||
async function histogramEqualization(inputImage) {
|
||||
const squeeze11 = inputImage.shape.length === 4 ? tf.squeeze(inputImage) : inputImage;
|
||||
const channels = tf.split(squeeze11, 3, 2);
|
||||
const squeeze10 = inputImage.shape.length === 4 ? tf.squeeze(inputImage) : inputImage;
|
||||
const channels = tf.split(squeeze10, 3, 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 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 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 reshape8 = tf.reshape(rgb2, [1, squeeze11.shape[0], squeeze11.shape[1], 3]);
|
||||
tf.dispose([...channels, ...min2, ...max4, ...sub10, ...range, ...fact, ...enh, rgb2, squeeze11]);
|
||||
const reshape8 = tf.reshape(rgb2, [1, squeeze10.shape[0], squeeze10.shape[1], 3]);
|
||||
tf.dispose([...channels, ...min2, ...max4, ...sub10, ...range, ...fact, ...enh, rgb2, squeeze10]);
|
||||
return reshape8;
|
||||
}
|
||||
|
||||
|
@ -1414,8 +1414,8 @@ async function predict(image29, config3, idx, count2) {
|
|||
if (!(model == null ? void 0 : model.inputs[0].shape))
|
||||
return;
|
||||
const t = {};
|
||||
const box4 = [[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]]);
|
||||
const box5 = [[0, 0.1, 0.9, 0.9]];
|
||||
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: [] };
|
||||
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"]);
|
||||
|
@ -4911,44 +4911,44 @@ var UV33 = VTX33.map((x) => UV468[x]);
|
|||
var UV7 = VTX7.map((x) => UV468[x]);
|
||||
|
||||
// src/face/facemeshutil.ts
|
||||
var getBoxSize = (box4) => [Math.abs(box4.endPoint[0] - box4.startPoint[0]), Math.abs(box4.endPoint[1] - box4.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 getClampedBox = (box4, input) => box4 ? [
|
||||
Math.trunc(Math.max(0, box4.startPoint[0])),
|
||||
Math.trunc(Math.max(0, box4.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[1] || 0, box4.endPoint[1]) - Math.max(0, box4.startPoint[1]))
|
||||
var getBoxSize = (box5) => [Math.abs(box5.endPoint[0] - box5.startPoint[0]), Math.abs(box5.endPoint[1] - box5.startPoint[1])];
|
||||
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 = (box5, input) => box5 ? [
|
||||
Math.trunc(Math.max(0, box5.startPoint[0])),
|
||||
Math.trunc(Math.max(0, box5.startPoint[1])),
|
||||
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, box5.endPoint[1]) - Math.max(0, box5.startPoint[1]))
|
||||
] : [0, 0, 0, 0];
|
||||
var getRawBox = (box4, input) => box4 ? [
|
||||
box4.startPoint[0] / (input.shape[2] || 0),
|
||||
box4.startPoint[1] / (input.shape[1] || 0),
|
||||
(box4.endPoint[0] - box4.startPoint[0]) / (input.shape[2] || 0),
|
||||
(box4.endPoint[1] - box4.startPoint[1]) / (input.shape[1] || 0)
|
||||
var getRawBox = (box5, input) => box5 ? [
|
||||
box5.startPoint[0] / (input.shape[2] || 0),
|
||||
box5.startPoint[1] / (input.shape[1] || 0),
|
||||
(box5.endPoint[0] - box5.startPoint[0]) / (input.shape[2] || 0),
|
||||
(box5.endPoint[1] - box5.startPoint[1]) / (input.shape[1] || 0)
|
||||
] : [0, 0, 0, 0];
|
||||
var scaleBoxCoordinates = (box4, factor) => {
|
||||
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]];
|
||||
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]];
|
||||
return { startPoint, endPoint, landmarks: box4.landmarks, confidence: box4.confidence };
|
||||
var scaleBoxCoordinates = (box5, factor) => {
|
||||
const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
|
||||
const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
|
||||
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 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);
|
||||
tf9.dispose(crop2);
|
||||
return norm;
|
||||
};
|
||||
var enlargeBox = (box4, factor) => {
|
||||
const center = getBoxCenter(box4);
|
||||
const size2 = getBoxSize(box4);
|
||||
var enlargeBox = (box5, factor) => {
|
||||
const center = getBoxCenter(box5);
|
||||
const size2 = getBoxSize(box5);
|
||||
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) => {
|
||||
const centers = getBoxCenter(box4);
|
||||
const size2 = getBoxSize(box4);
|
||||
var squarifyBox = (box5) => {
|
||||
const centers = getBoxCenter(box5);
|
||||
const size2 = getBoxSize(box5);
|
||||
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) => {
|
||||
const xs = landmarks.map((d) => d[0]);
|
||||
|
@ -5016,8 +5016,8 @@ function generateAnchors(inputSize9) {
|
|||
}
|
||||
return anchors4;
|
||||
}
|
||||
function transformRawCoords(coordsRaw, box4, angle, rotationMatrix, inputSize9) {
|
||||
const boxSize = getBoxSize(box4);
|
||||
function transformRawCoords(coordsRaw, box5, angle, rotationMatrix, inputSize9) {
|
||||
const boxSize = getBoxSize(box5);
|
||||
const coordsScaled = coordsRaw.map((coord) => [
|
||||
boxSize[0] / inputSize9 * (coord[0] - 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 coordsRotated = largeAngle ? coordsScaled.map((coord) => [...rotatePoint(coord, coordsRotationMatrix), coord[2]]) : coordsScaled;
|
||||
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) => [
|
||||
Math.round(coord[0] + dot(boxCenter, inverseRotationMatrix[0])),
|
||||
Math.round(coord[1] + dot(boxCenter, inverseRotationMatrix[1])),
|
||||
Math.round(coord[2] || 0)
|
||||
]);
|
||||
}
|
||||
function correctFaceRotation(rotate, box4, input, inputSize9) {
|
||||
const symmetryLine = box4.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine;
|
||||
function correctFaceRotation(rotate, box5, input, inputSize9) {
|
||||
const symmetryLine = box5.landmarks.length >= meshLandmarks.count ? meshLandmarks.symmetryLine : blazeFaceLandmarks.symmetryLine;
|
||||
let angle = 0;
|
||||
let rotationMatrix = fixedRotationMatrix;
|
||||
let face5;
|
||||
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;
|
||||
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 rotated = tf9.image.rotateWithOffset(input, angle, 0, centerRaw);
|
||||
rotationMatrix = buildRotationMatrix(-angle, center);
|
||||
face5 = cutBoxFromImageAndResize(box4, rotated, [inputSize9, inputSize9]);
|
||||
face5 = cutBoxFromImageAndResize(box5, rotated, [inputSize9, inputSize9]);
|
||||
tf9.dispose(rotated);
|
||||
} else {
|
||||
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]);
|
||||
face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
|
||||
}
|
||||
} else {
|
||||
face5 = cutBoxFromImageAndResize(box4, input, [inputSize9, inputSize9]);
|
||||
face5 = cutBoxFromImageAndResize(box5, input, [inputSize9, inputSize9]);
|
||||
}
|
||||
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)) };
|
||||
}
|
||||
var cropFactor = [5, 5];
|
||||
function decodeBoxes(boxesTensor, anchor) {
|
||||
return tf11.tidy(() => {
|
||||
const split5 = tf11.split(boxesTensor, 12, 1);
|
||||
let xCenter = tf11.squeeze(split5[0]);
|
||||
let yCenter = tf11.squeeze(split5[1]);
|
||||
let width = tf11.squeeze(split5[2]);
|
||||
let height = tf11.squeeze(split5[3]);
|
||||
xCenter = tf11.add(tf11.div(xCenter, inputSize2), anchor.x);
|
||||
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;
|
||||
});
|
||||
|
||||
// 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 box5 = [min2[0], min2[1], max4[0] - min2[0], max4[1] - min2[1]];
|
||||
const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
|
||||
return { box: box5, boxRaw };
|
||||
}
|
||||
async function decode(boxesTensor, logitsTensor, config3, outputSize2) {
|
||||
const t = {};
|
||||
t.boxes = decodeBoxes(boxesTensor, anchorTensor);
|
||||
t.scores = tf11.sigmoid(logitsTensor);
|
||||
t.argmax = tf11.argMax(t.scores);
|
||||
const i = (await t.argmax.data())[0];
|
||||
const scores = await t.scores.data();
|
||||
const detected = [];
|
||||
const minScore = config3.body["detector"] && config3.body["detector"]["minConfidence"] ? config3.body["detector"]["minConfidence"] : 0;
|
||||
if (scores[i] >= minScore) {
|
||||
const boxes = await t.boxes.array();
|
||||
const boxRaw = boxes[i];
|
||||
const box4 = [boxRaw[0] * outputSize2[0], boxRaw[1] * outputSize2[1], boxRaw[2] * outputSize2[0], boxRaw[3] * outputSize2[1]];
|
||||
detected.push({ box: box4, boxRaw, score: scores[i] });
|
||||
}
|
||||
Object.keys(t).forEach((tensor3) => tf11.dispose(t[tensor3]));
|
||||
return detected;
|
||||
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 box5 = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];
|
||||
const boxRaw = [box5[0] / outputSize2[0], box5[1] / outputSize2[1], box5[2] / outputSize2[0], box5[3] / outputSize2[1]];
|
||||
return { box: box5, boxRaw };
|
||||
}
|
||||
function scale(box5, scaleFact) {
|
||||
const dist = [box5[2] * scaleFact, box5[3] * scaleFact];
|
||||
const newBox = [
|
||||
box5[0] - (dist[0] - box5[2]) / 2,
|
||||
box5[1] - (dist[1] - box5[3]) / 2,
|
||||
dist[0],
|
||||
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
|
||||
|
@ -5285,7 +5283,7 @@ var outputNodes = {
|
|||
detector: []
|
||||
};
|
||||
var cache = null;
|
||||
var lastBox;
|
||||
var cropBox;
|
||||
var padding = [[0, 0], [0, 0], [0, 0], [0, 0]];
|
||||
var lastTime5 = 0;
|
||||
var sigmoid3 = (x) => 1 - 1 / (1 + Math.exp(x));
|
||||
|
@ -5322,39 +5320,37 @@ async function loadPose(config3) {
|
|||
log("cached model:", models.landmarks["modelUrl"]);
|
||||
return models.landmarks;
|
||||
}
|
||||
function calculateBoxes(keypoints, outputSize2) {
|
||||
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) {
|
||||
async function prepareImage(input, size2) {
|
||||
const t = {};
|
||||
if (!input.shape || !input.shape[1] || !input.shape[2])
|
||||
return input;
|
||||
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]) {
|
||||
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 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];
|
||||
const height = [
|
||||
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 = [
|
||||
[0, 0],
|
||||
height,
|
||||
width,
|
||||
[0, 0]
|
||||
];
|
||||
if (box4) {
|
||||
t.resize = tf12.image.cropAndResize(input, [box4], [0], [size2, size2]);
|
||||
} else {
|
||||
t.pad = tf12.pad(input, padding);
|
||||
t.resize = tf12.image.resizeBilinear(t.pad, [size2, size2]);
|
||||
}
|
||||
t.pad = tf12.pad(t.cropped || input, padding);
|
||||
t.resize = tf12.image.resizeBilinear(t.pad, [size2, size2]);
|
||||
final = tf12.div(t.resize, constants.tf255);
|
||||
} 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);
|
||||
} else {
|
||||
final = tf12.div(input, constants.tf255);
|
||||
final = tf12.div(t.cropped || input, constants.tf255);
|
||||
}
|
||||
Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3]));
|
||||
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]];
|
||||
}
|
||||
return keypoints;
|
||||
}
|
||||
function rescaleBoxes(boxes, outputSize2) {
|
||||
for (const box4 of boxes) {
|
||||
box4.box = [
|
||||
Math.trunc(box4.box[0] * (outputSize2[0] + padding[2][0] + padding[2][1]) / outputSize2[0]),
|
||||
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]),
|
||||
Math.trunc(box4.box[3] * (outputSize2[1] + padding[1][0] + padding[1][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]];
|
||||
if (cropBox) {
|
||||
for (const kpt4 of keypoints) {
|
||||
kpt4.positionRaw = [
|
||||
kpt4.positionRaw[0] + cropBox[1],
|
||||
kpt4.positionRaw[1] + cropBox[0],
|
||||
kpt4.positionRaw[2]
|
||||
];
|
||||
kpt4.position = [
|
||||
Math.trunc(kpt4.positionRaw[0] * outputSize2[0]),
|
||||
Math.trunc(kpt4.positionRaw[1] * outputSize2[1]),
|
||||
kpt4.positionRaw[2]
|
||||
];
|
||||
}
|
||||
}
|
||||
return boxes;
|
||||
return keypoints;
|
||||
}
|
||||
async function detectLandmarks(input, config3, outputSize2) {
|
||||
var _a;
|
||||
|
@ -5402,7 +5400,8 @@ async function detectLandmarks(input, config3, outputSize2) {
|
|||
if (poseScore < (config3.body.minConfidence || 0))
|
||||
return null;
|
||||
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 = {};
|
||||
for (const [name, indexes] of Object.entries(connected)) {
|
||||
const pt = [];
|
||||
|
@ -5414,22 +5413,9 @@ async function detectLandmarks(input, config3, outputSize2) {
|
|||
}
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
const outputSize2 = [input.shape[2] || 0, input.shape[1] || 0];
|
||||
const skipTime = (config3.body.skipTime || 0) > now() - lastTime5;
|
||||
|
@ -5438,26 +5424,13 @@ async function predict5(input, config3) {
|
|||
skipped5++;
|
||||
} else {
|
||||
const t = {};
|
||||
if (config3.body["detector"] && config3.body["detector"]["enabled"]) {
|
||||
t.detector = await prepareImage(input, 224);
|
||||
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);
|
||||
}
|
||||
t.landmarks = await prepareImage(input, 256);
|
||||
cache = await detectLandmarks(t.landmarks, config3, outputSize2);
|
||||
Object.keys(t).forEach((tensor3) => tf12.dispose(t[tensor3]));
|
||||
lastTime5 = now();
|
||||
skipped5 = 0;
|
||||
}
|
||||
if (cache)
|
||||
return [cache];
|
||||
return [];
|
||||
return cache ? [cache] : [];
|
||||
}
|
||||
|
||||
// src/object/centernet.ts
|
||||
|
@ -5598,13 +5571,13 @@ async function process3(res, outputShape, config3) {
|
|||
detections[0][id][2] / inputSize4 - x,
|
||||
detections[0][id][3] / inputSize4 - y
|
||||
];
|
||||
const box4 = [
|
||||
const box5 = [
|
||||
Math.trunc(boxRaw[0] * outputShape[0]),
|
||||
Math.trunc(boxRaw[1] * outputShape[1]),
|
||||
Math.trunc(boxRaw[2] * outputShape[0]),
|
||||
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]));
|
||||
return results;
|
||||
|
@ -5725,10 +5698,10 @@ async function predict7(image29, config3) {
|
|||
tf14.dispose(tensor3);
|
||||
if (resT) {
|
||||
cache2.keypoints.length = 0;
|
||||
const squeeze11 = resT.squeeze();
|
||||
const squeeze10 = resT.squeeze();
|
||||
tf14.dispose(resT);
|
||||
const stack5 = squeeze11.unstack(2);
|
||||
tf14.dispose(squeeze11);
|
||||
const stack5 = squeeze10.unstack(2);
|
||||
tf14.dispose(squeeze10);
|
||||
for (let id = 0; id < stack5.length; id++) {
|
||||
const [x2, y2, partScore] = await max2d(stack5[id], config3.body.minConfidence);
|
||||
if (partScore > (((_a = config3.body) == null ? void 0 : _a.minConfidence) || 0)) {
|
||||
|
@ -5946,20 +5919,20 @@ var getLeftToRightEyeDepthDifference = (rawCoords) => {
|
|||
return leftEyeZ - rightEyeZ;
|
||||
};
|
||||
var getEyeBox = (rawCoords, face5, eyeInnerCornerIndex, eyeOuterCornerIndex, meshSize, flip = false) => {
|
||||
const box4 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge));
|
||||
const boxSize = getBoxSize(box4);
|
||||
const box5 = squarifyBox(enlargeBox(calculateLandmarksBoundingBox([rawCoords[eyeInnerCornerIndex], rawCoords[eyeOuterCornerIndex]]), irisEnlarge));
|
||||
const boxSize = getBoxSize(box5);
|
||||
let crop2 = tf17.image.cropAndResize(face5, [[
|
||||
box4.startPoint[1] / meshSize,
|
||||
box4.startPoint[0] / meshSize,
|
||||
box4.endPoint[1] / meshSize,
|
||||
box4.endPoint[0] / meshSize
|
||||
box5.startPoint[1] / meshSize,
|
||||
box5.startPoint[0] / meshSize,
|
||||
box5.endPoint[1] / meshSize,
|
||||
box5.endPoint[0] / meshSize
|
||||
]], [0], [inputSize5, inputSize5]);
|
||||
if (flip && env.kernels.includes("flipleftright")) {
|
||||
const flipped = tf17.image.flipLeftRight(crop2);
|
||||
tf17.dispose(crop2);
|
||||
crop2 = flipped;
|
||||
}
|
||||
return { box: box4, boxSize, crop: crop2 };
|
||||
return { box: box5, boxSize, crop: crop2 };
|
||||
};
|
||||
var getEyeCoords = (eyeData, eyeBox, eyeBoxSize, flip = false) => {
|
||||
const eyeRawCoords = [];
|
||||
|
@ -6053,7 +6026,7 @@ async function predict10(input, config3) {
|
|||
const newCache = [];
|
||||
let id = 0;
|
||||
for (let i = 0; i < boxCache.length; i++) {
|
||||
let box4 = boxCache[i];
|
||||
let box5 = boxCache[i];
|
||||
let angle = 0;
|
||||
let rotationMatrix;
|
||||
const face5 = {
|
||||
|
@ -6067,20 +6040,20 @@ async function predict10(input, config3) {
|
|||
faceScore: 0,
|
||||
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) {
|
||||
const equilized = await histogramEqualization(face5.tensor);
|
||||
tf18.dispose(face5.tensor);
|
||||
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)) {
|
||||
face5.box = getClampedBox(box4, input);
|
||||
face5.boxRaw = getRawBox(box4, input);
|
||||
face5.box = getClampedBox(box5, input);
|
||||
face5.boxRaw = getRawBox(box5, input);
|
||||
face5.score = face5.boxScore;
|
||||
face5.mesh = box4.landmarks.map((pt) => [
|
||||
(box4.startPoint[0] + box4.endPoint[0]) / 2 + (box4.endPoint[0] + box4.startPoint[0]) * pt[0] / size(),
|
||||
(box4.startPoint[1] + box4.endPoint[1]) / 2 + (box4.endPoint[1] + box4.startPoint[1]) * pt[1] / size()
|
||||
face5.mesh = box5.landmarks.map((pt) => [
|
||||
(box5.startPoint[0] + box5.endPoint[0]) / 2 + (box5.endPoint[0] + box5.startPoint[0]) * pt[0] / 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]);
|
||||
for (const key of Object.keys(blazeFaceLandmarks))
|
||||
|
@ -6096,24 +6069,24 @@ async function predict10(input, config3) {
|
|||
let rawCoords = await coordsReshaped.array();
|
||||
tf18.dispose([contourCoords, coordsReshaped, confidence, contours]);
|
||||
if (face5.faceScore < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
|
||||
box4.confidence = face5.faceScore;
|
||||
box5.confidence = face5.faceScore;
|
||||
} else {
|
||||
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
|
||||
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]);
|
||||
for (const key of Object.keys(meshAnnotations))
|
||||
face5.annotations[key] = meshAnnotations[key].map((index2) => face5.mesh[index2]);
|
||||
const boxCalculated = calculateLandmarksBoundingBox(face5.mesh);
|
||||
const boxEnlarged = enlargeBox(boxCalculated, ((_j = config3.face.detector) == null ? void 0 : _j.cropFactor) || 1.6);
|
||||
const boxSquared = squarifyBox(boxEnlarged);
|
||||
box4 = { ...boxSquared, confidence: box4.confidence };
|
||||
face5.box = getClampedBox(box4, input);
|
||||
face5.boxRaw = getRawBox(box4, input);
|
||||
box5 = { ...boxSquared, confidence: box5.confidence };
|
||||
face5.box = getClampedBox(box5, input);
|
||||
face5.boxRaw = getRawBox(box5, input);
|
||||
face5.score = face5.faceScore;
|
||||
newCache.push(box4);
|
||||
newCache.push(box5);
|
||||
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);
|
||||
|
@ -6226,54 +6199,54 @@ var tf21 = __toModule(require_tfjs_esm());
|
|||
|
||||
// src/hand/handposeutil.ts
|
||||
var tf20 = __toModule(require_tfjs_esm());
|
||||
function getBoxSize2(box4) {
|
||||
function getBoxSize2(box5) {
|
||||
return [
|
||||
Math.abs(box4.endPoint[0] - box4.startPoint[0]),
|
||||
Math.abs(box4.endPoint[1] - box4.startPoint[1])
|
||||
Math.abs(box5.endPoint[0] - box5.startPoint[0]),
|
||||
Math.abs(box5.endPoint[1] - box5.startPoint[1])
|
||||
];
|
||||
}
|
||||
function getBoxCenter2(box4) {
|
||||
function getBoxCenter2(box5) {
|
||||
return [
|
||||
box4.startPoint[0] + (box4.endPoint[0] - box4.startPoint[0]) / 2,
|
||||
box4.startPoint[1] + (box4.endPoint[1] - box4.startPoint[1]) / 2
|
||||
box5.startPoint[0] + (box5.endPoint[0] - box5.startPoint[0]) / 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 w = image29.shape[2];
|
||||
const boxes = [[
|
||||
box4.startPoint[1] / h,
|
||||
box4.startPoint[0] / w,
|
||||
box4.endPoint[1] / h,
|
||||
box4.endPoint[0] / w
|
||||
box5.startPoint[1] / h,
|
||||
box5.startPoint[0] / w,
|
||||
box5.endPoint[1] / h,
|
||||
box5.endPoint[0] / w
|
||||
]];
|
||||
return tf20.image.cropAndResize(image29, boxes, [0], cropSize);
|
||||
}
|
||||
function scaleBoxCoordinates2(box4, factor) {
|
||||
const startPoint = [box4.startPoint[0] * factor[0], box4.startPoint[1] * factor[1]];
|
||||
const endPoint = [box4.endPoint[0] * factor[0], box4.endPoint[1] * factor[1]];
|
||||
const palmLandmarks = box4.palmLandmarks.map((coord) => {
|
||||
function scaleBoxCoordinates2(box5, factor) {
|
||||
const startPoint = [box5.startPoint[0] * factor[0], box5.startPoint[1] * factor[1]];
|
||||
const endPoint = [box5.endPoint[0] * factor[0], box5.endPoint[1] * factor[1]];
|
||||
const palmLandmarks = box5.palmLandmarks.map((coord) => {
|
||||
const scaledCoord = [coord[0] * factor[0], coord[1] * factor[1]];
|
||||
return scaledCoord;
|
||||
});
|
||||
return { startPoint, endPoint, palmLandmarks, confidence: box4.confidence };
|
||||
return { startPoint, endPoint, palmLandmarks, confidence: box5.confidence };
|
||||
}
|
||||
function enlargeBox2(box4, factor = 1.5) {
|
||||
const center = getBoxCenter2(box4);
|
||||
const size2 = getBoxSize2(box4);
|
||||
function enlargeBox2(box5, factor = 1.5) {
|
||||
const center = getBoxCenter2(box5);
|
||||
const size2 = getBoxSize2(box5);
|
||||
const newHalfSize = [factor * size2[0] / 2, factor * size2[1] / 2];
|
||||
const startPoint = [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) {
|
||||
const centers = getBoxCenter2(box4);
|
||||
const size2 = getBoxSize2(box4);
|
||||
function squarifyBox2(box5) {
|
||||
const centers = getBoxCenter2(box5);
|
||||
const size2 = getBoxSize2(box5);
|
||||
const maxEdge = Math.max(...size2);
|
||||
const halfSize = maxEdge / 2;
|
||||
const startPoint = [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) {
|
||||
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.norm = this.normalizeLandmarks(p.slice, index2);
|
||||
p.palmLandmarks = tf21.reshape(p.norm, [-1, 2]);
|
||||
const box4 = await p.box.data();
|
||||
const startPoint = box4.slice(0, 2);
|
||||
const endPoint = box4.slice(2, 4);
|
||||
const box5 = await p.box.data();
|
||||
const startPoint = box5.slice(0, 2);
|
||||
const endPoint = box5.slice(2, 4);
|
||||
const palmLandmarks = await p.palmLandmarks.array();
|
||||
const hand3 = { startPoint, endPoint, palmLandmarks, confidence: scores[index2] };
|
||||
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;
|
||||
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];
|
||||
if (keypoints && keypoints.length > 0) {
|
||||
for (const pt of keypoints) {
|
||||
if (pt[0] < box4[0])
|
||||
box4[0] = pt[0];
|
||||
if (pt[1] < box4[1])
|
||||
box4[1] = pt[1];
|
||||
if (pt[0] > box4[2])
|
||||
box4[2] = pt[0];
|
||||
if (pt[1] > box4[3])
|
||||
box4[3] = pt[1];
|
||||
if (pt[0] < box5[0])
|
||||
box5[0] = pt[0];
|
||||
if (pt[1] < box5[1])
|
||||
box5[1] = pt[1];
|
||||
if (pt[0] > box5[2])
|
||||
box5[2] = pt[0];
|
||||
if (pt[1] > box5[3])
|
||||
box5[3] = pt[1];
|
||||
}
|
||||
box4[2] -= box4[0];
|
||||
box4[3] -= box4[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)];
|
||||
box5[2] -= box5[0];
|
||||
box5[3] -= box5[1];
|
||||
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 {
|
||||
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[1])),
|
||||
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,
|
||||
fingerScore: Math.round(100 * predictions[i].fingerConfidence) / 100,
|
||||
label: "hand",
|
||||
box: box4,
|
||||
box: box5,
|
||||
boxRaw,
|
||||
keypoints,
|
||||
annotations: annotations2,
|
||||
|
@ -10014,40 +9987,6 @@ async function load13(config3) {
|
|||
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
|
||||
var tf24 = __toModule(require_tfjs_esm());
|
||||
var models2 = [null, null];
|
||||
|
@ -10066,11 +10005,11 @@ var cache3 = {
|
|||
hands: []
|
||||
};
|
||||
var fingerMap = {
|
||||
thumb: [1, 2, 3, 4],
|
||||
index: [5, 6, 7, 8],
|
||||
middle: [9, 10, 11, 12],
|
||||
ring: [13, 14, 15, 16],
|
||||
pinky: [17, 18, 19, 20],
|
||||
thumb: [0, 1, 2, 3, 4],
|
||||
index: [0, 5, 6, 7, 8],
|
||||
middle: [0, 9, 10, 11, 12],
|
||||
ring: [0, 13, 14, 15, 16],
|
||||
pinky: [0, 17, 18, 19, 20],
|
||||
palm: [0]
|
||||
};
|
||||
async function loadDetect2(config3) {
|
||||
|
@ -10621,7 +10560,7 @@ async function process4(res, inputSize9, outputShape, config3) {
|
|||
];
|
||||
let boxRaw = [x, y, w, h];
|
||||
boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1)));
|
||||
const box4 = [
|
||||
const box5 = [
|
||||
boxRaw[0] * outputShape[0],
|
||||
boxRaw[1] * outputShape[1],
|
||||
boxRaw[2] * outputShape[0],
|
||||
|
@ -10632,7 +10571,7 @@ async function process4(res, inputSize9, outputShape, config3) {
|
|||
score: Math.round(100 * score) / 100,
|
||||
class: j + 1,
|
||||
label: labels[j].label,
|
||||
box: box4.map((a) => Math.trunc(a)),
|
||||
box: box5.map((a) => Math.trunc(a)),
|
||||
boxRaw
|
||||
};
|
||||
results.push(result);
|
||||
|
@ -10975,7 +10914,7 @@ function getInstanceScore(existingPoses, keypoints) {
|
|||
}, 0);
|
||||
return notOverlappedKeypointScores / keypoints.length;
|
||||
}
|
||||
function decode2(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) {
|
||||
function decode(offsets, scores, displacementsFwd, displacementsBwd, maxDetected, minConfidence2) {
|
||||
const poses = [];
|
||||
const queue = buildPartWithScoreQueue(minConfidence2, scores);
|
||||
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);
|
||||
keypoints = keypoints.filter((a) => a.score > minConfidence2);
|
||||
const score = getInstanceScore(poses, keypoints);
|
||||
const box4 = getBoundingBox(keypoints);
|
||||
const box5 = getBoundingBox(keypoints);
|
||||
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;
|
||||
}
|
||||
|
@ -11006,7 +10945,7 @@ async function predict17(input, config3) {
|
|||
const buffers = await Promise.all(res.map((tensor3) => tensor3.buffer()));
|
||||
for (const t of res)
|
||||
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)
|
||||
return [];
|
||||
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;
|
||||
if (isNaN(thetaZ))
|
||||
thetaZ = 0;
|
||||
return { pitch: 2 * -thetaX, yaw: 2 * -thetaY, roll: 2 * -thetaZ };
|
||||
return { pitch: -thetaX, yaw: -thetaY, roll: -thetaZ };
|
||||
};
|
||||
const meshToEulerAngle = (mesh2) => {
|
||||
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));
|
||||
} else {
|
||||
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 keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({
|
||||
score: newKpt.score,
|
||||
|
@ -12445,14 +12384,14 @@ function calc2(newResult, config3) {
|
|||
}
|
||||
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) {
|
||||
bufferedResult.hand = JSON.parse(JSON.stringify(newResult.hand));
|
||||
} else {
|
||||
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);
|
||||
if (bufferedResult.hand[i].keypoints.length !== newResult.hand[i].keypoints.length)
|
||||
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;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
bufferedResult.face = JSON.parse(JSON.stringify(newResult.face));
|
||||
} else {
|
||||
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);
|
||||
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 } };
|
||||
|
@ -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,
|
||||
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) {
|
||||
bufferedResult.object = JSON.parse(JSON.stringify(newResult.object));
|
||||
} else {
|
||||
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);
|
||||
bufferedResult.object[i] = { ...newResult.object[i], box: box4, boxRaw };
|
||||
bufferedResult.object[i] = { ...newResult.object[i], box: box5, boxRaw };
|
||||
}
|
||||
}
|
||||
if (newResult.persons) {
|
||||
|
@ -12507,7 +12446,7 @@ function calc2(newResult, config3) {
|
|||
bufferedResult.persons = JSON.parse(JSON.stringify(newPersons));
|
||||
} else {
|
||||
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 y = [];
|
||||
const extractXY = (box4) => {
|
||||
if (box4 && box4.length === 4) {
|
||||
x.push(box4[0], box4[0] + box4[2]);
|
||||
y.push(box4[1], box4[1] + box4[3]);
|
||||
const extractXY = (box5) => {
|
||||
if (box5 && box5.length === 4) {
|
||||
x.push(box5[0], box5[0] + box5[2]);
|
||||
y.push(box5[1], box5[1] + box5[3]);
|
||||
}
|
||||
};
|
||||
extractXY((_k = person2.face) == null ? void 0 : _k.box);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
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 __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
|
@ -48697,19 +48697,20 @@ var PackProgram = class {
|
|||
this.packedInputs = false;
|
||||
this.packedOutput = true;
|
||||
this.outputShape = outputShape;
|
||||
const rank = outputShape.length;
|
||||
if (rank === 0) {
|
||||
this.rank = outputShape.length;
|
||||
this.enableShapeUniforms = useShapeUniforms(this.outputShape.length);
|
||||
if (this.rank === 0) {
|
||||
this.userCode = `
|
||||
void main() {
|
||||
setOutput(vec4(getA(), 0., 0., 0.));
|
||||
}
|
||||
`;
|
||||
} else {
|
||||
const channels = getChannels("rc", rank);
|
||||
const dtype = getCoordsDataType(rank);
|
||||
const outOfBoundsCondition = getOutOfBoundsCondition(rank, outputShape, channels);
|
||||
const setup46 = getSetup(rank, outputShape[outputShape.length - 1], outputShape[outputShape.length - 2], channels);
|
||||
const output = getOutput(outputShape, channels);
|
||||
const channels = getChannels("rc", this.rank);
|
||||
const dtype = getCoordsDataType(this.rank);
|
||||
const outOfBoundsCondition = this.getOutOfBoundsCondition(channels);
|
||||
const setup46 = this.getSetup(channels);
|
||||
const output = this.getOutput(channels);
|
||||
this.userCode = `
|
||||
void main() {
|
||||
${dtype} rc = getOutputCoords();
|
||||
|
@ -48725,61 +48726,62 @@ var PackProgram = class {
|
|||
`;
|
||||
}
|
||||
}
|
||||
};
|
||||
function getSourceCoordsArr(rank, dims) {
|
||||
const coords3 = [];
|
||||
for (let row = 0; row <= 1; row++) {
|
||||
for (let col = 0; col <= 1; col++) {
|
||||
let coord = `${row === 0 ? "r" : "rp1"}, ${col === 0 ? "c" : "cp1"}`;
|
||||
for (let d = 2; d < rank; d++) {
|
||||
coord = `${dims[dims.length - 1 - d]},` + coord;
|
||||
getSourceCoordsArr(dims) {
|
||||
const coords3 = [];
|
||||
for (let row = 0; row <= 1; row++) {
|
||||
for (let col = 0; col <= 1; col++) {
|
||||
let coord = `${row === 0 ? "r" : "rp1"}, ${col === 0 ? "c" : "cp1"}`;
|
||||
for (let d = 2; d < this.rank; d++) {
|
||||
coord = `${dims[dims.length - 1 - d]},` + coord;
|
||||
}
|
||||
coords3.push(coord);
|
||||
}
|
||||
coords3.push(coord);
|
||||
}
|
||||
return coords3;
|
||||
}
|
||||
return coords3;
|
||||
}
|
||||
function getOutOfBoundsCondition(rank, shape, dims) {
|
||||
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 += "||";
|
||||
getOutOfBoundsCondition(dims) {
|
||||
if (this.rank === 1) {
|
||||
return `rc > ${this.enableShapeUniforms ? "outShape" : this.outputShape[0]}`;
|
||||
}
|
||||
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;
|
||||
}
|
||||
function getSetup(rank, cols, rows, dims) {
|
||||
if (rank === 1) {
|
||||
return "";
|
||||
}
|
||||
const innerDims = dims.slice(-2);
|
||||
return `
|
||||
int r = ${innerDims[0]};
|
||||
int c = ${innerDims[1]};
|
||||
int rp1 = r + 1;
|
||||
int cp1 = c + 1;
|
||||
getSetup(dims) {
|
||||
if (this.rank === 1) {
|
||||
return "";
|
||||
}
|
||||
const innerDims = dims.slice(-2);
|
||||
const col = this.enableShapeUniforms ? `outShape[${this.rank} - 1]` : this.outputShape[this.rank - 1];
|
||||
const row = this.enableShapeUniforms ? `outShape[${this.rank} - 2]` : this.outputShape[this.rank - 2];
|
||||
return `
|
||||
int r = ${innerDims[0]};
|
||||
int c = ${innerDims[1]};
|
||||
int rp1 = r + 1;
|
||||
int cp1 = c + 1;
|
||||
|
||||
bool cEdge = cp1 >= ${cols};
|
||||
bool rEdge = rp1 >= ${rows};
|
||||
`;
|
||||
}
|
||||
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`;
|
||||
bool cEdge = cp1 >= ${col};
|
||||
bool rEdge = rp1 >= ${row};
|
||||
`;
|
||||
}
|
||||
return `getA(${sourceCoords[0]}),
|
||||
cEdge ? 0. : getA(${sourceCoords[1]}),
|
||||
rEdge ? 0. : getA(${sourceCoords[2]}),
|
||||
rEdge || cEdge ? 0. : getA(${sourceCoords[3]})`;
|
||||
}
|
||||
getOutput(dims) {
|
||||
const sourceCoords = this.getSourceCoordsArr(dims);
|
||||
if (this.rank === 1) {
|
||||
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 {
|
||||
constructor(outputShape, inputShape) {
|
||||
this.variableNames = ["A"];
|
||||
|
@ -49122,6 +49124,7 @@ var UnpackProgram = class {
|
|||
this.packedInputs = true;
|
||||
this.packedOutput = false;
|
||||
this.outputShape = outputShape;
|
||||
this.enableShapeUniforms = useShapeUniforms(this.outputShape.length);
|
||||
const rank = outputShape.length;
|
||||
const channels = getChannels("rc", rank);
|
||||
const dtype = getCoordsDataType(rank);
|
||||
|
@ -69967,7 +69970,7 @@ registerBackend("wasm", async () => {
|
|||
const { wasm } = await init();
|
||||
return new BackendWasm(wasm);
|
||||
}, WASM_PRIORITY);
|
||||
var externalVersion = "3.11.0-20211123";
|
||||
var externalVersion = "3.11.0-20211124";
|
||||
var version8 = {
|
||||
tfjs: externalVersion,
|
||||
"tfjs-core": externalVersion,
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
"@tensorflow/tfjs-layers": "^3.11.0",
|
||||
"@tensorflow/tfjs-node": "^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",
|
||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||
"@typescript-eslint/parser": "^5.4.0",
|
||||
|
|
|
@ -10,8 +10,7 @@ import type { GraphModel, Tensor } from '../tfjs/types';
|
|||
import type { Config } from '../config';
|
||||
import * as coords from './blazeposecoords';
|
||||
import * as detect from './blazeposedetector';
|
||||
|
||||
interface DetectedBox { box: Box, boxRaw: Box, score: number }
|
||||
import * as box from '../util/box';
|
||||
|
||||
const env = { initial: true };
|
||||
// const models: [GraphModel | null, GraphModel | null] = [null, null];
|
||||
|
@ -24,7 +23,7 @@ const outputNodes: { detector: string[], landmarks: string[] } = {
|
|||
};
|
||||
|
||||
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 lastTime = 0;
|
||||
|
||||
|
@ -63,50 +62,43 @@ export async function load(config: Config): Promise<[GraphModel | null, GraphMod
|
|||
return [models.detector, models.landmarks];
|
||||
}
|
||||
|
||||
function calculateBoxes(keypoints: Array<BodyKeypoint>, outputSize: [number, number]): { keypointsBox: Box, keypointsBoxRaw: Box } {
|
||||
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> {
|
||||
async function prepareImage(input: Tensor, size: number): Promise<Tensor> {
|
||||
const t: Record<string, Tensor> = {};
|
||||
if (!input.shape || !input.shape[1] || !input.shape[2]) return input;
|
||||
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
|
||||
const height: [number, number] = box
|
||||
? [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];
|
||||
const width: [number, number] = box
|
||||
? [Math.trunc(input.shape[2] * box[0]), Math.trunc(input.shape[2] * (box[0] + box[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];
|
||||
const height: [number, number] = [
|
||||
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] = [
|
||||
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 = [
|
||||
[0, 0], // dont touch batch
|
||||
height, // height before&after
|
||||
width, // width before&after
|
||||
[0, 0], // dont touch rbg
|
||||
];
|
||||
if (box) {
|
||||
t.resize = tf.image.cropAndResize(input, [box], [0], [size, size]);
|
||||
} else {
|
||||
t.pad = tf.pad(input, padding);
|
||||
t.resize = tf.image.resizeBilinear(t.pad, [size, size]);
|
||||
}
|
||||
t.pad = tf.pad(t.cropped || input, padding); // use cropped box if it exists
|
||||
t.resize = tf.image.resizeBilinear(t.pad, [size, size]);
|
||||
final = tf.div(t.resize, constants.tf255);
|
||||
} 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);
|
||||
} 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]));
|
||||
return final;
|
||||
}
|
||||
|
||||
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 = [
|
||||
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]),
|
||||
|
@ -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];
|
||||
}
|
||||
return keypoints;
|
||||
}
|
||||
|
||||
function rescaleBoxes(boxes: Array<DetectedBox>, outputSize: [number, number]): Array<DetectedBox> {
|
||||
for (const box of boxes) {
|
||||
box.box = [
|
||||
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]),
|
||||
Math.trunc(box.box[2] * (outputSize[0] + padding[2][0] + padding[2][1]) / outputSize[0]),
|
||||
Math.trunc(box.box[3] * (outputSize[1] + padding[1][0] + padding[1][1]) / outputSize[1]),
|
||||
];
|
||||
box.boxRaw = [box.box[0] / outputSize[0], box.box[1] / outputSize[1], box.box[2] / outputSize[0], box.box[3] / outputSize[1]];
|
||||
if (cropBox) { // second rescale due to cropping
|
||||
for (const kpt of keypoints) {
|
||||
kpt.positionRaw = [
|
||||
kpt.positionRaw[0] + cropBox[1], // correct offset due to crop
|
||||
kpt.positionRaw[1] + cropBox[0], // correct offset due to crop
|
||||
kpt.positionRaw[2] as number,
|
||||
];
|
||||
kpt.position = [
|
||||
Math.trunc(kpt.positionRaw[0] * outputSize[0]),
|
||||
Math.trunc(kpt.positionRaw[1] * outputSize[1]),
|
||||
kpt.positionRaw[2] as number,
|
||||
];
|
||||
}
|
||||
}
|
||||
return boxes;
|
||||
return keypoints;
|
||||
}
|
||||
|
||||
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;
|
||||
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[][]> = {};
|
||||
for (const [name, indexes] of Object.entries(coords.connected)) {
|
||||
const pt: Array<Point[]> = [];
|
||||
for (let i = 0; i < indexes.length - 1; i++) {
|
||||
const pt0 = keypoints.find((kpt) => kpt.part === indexes[i]);
|
||||
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]);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
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]) {
|
||||
const t: Record<string, 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]));
|
||||
return boxes;
|
||||
}
|
||||
*/
|
||||
|
||||
export async function predict(input: Tensor, config: Config): Promise<BodyResult[]> {
|
||||
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++;
|
||||
} else {
|
||||
const t: Record<string, Tensor> = {};
|
||||
/*
|
||||
if (config.body['detector'] && config.body['detector']['enabled']) {
|
||||
t.detector = await prepareImage(input, 224);
|
||||
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]));
|
||||
// if (cache && boxes.length > 0) cache.box = boxes[0].box;
|
||||
lastTime = now();
|
||||
skipped = 0;
|
||||
}
|
||||
if (cache) return [cache];
|
||||
return [];
|
||||
return cache ? [cache] : [];
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ export const calculateFaceAngle = (face, imageSize): {
|
|||
if (isNaN(thetaX)) thetaX = 0;
|
||||
if (isNaN(thetaY)) thetaY = 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
|
||||
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
|
||||
|
|
|
@ -51,11 +51,11 @@ const cache: {
|
|||
};
|
||||
|
||||
const fingerMap = {
|
||||
thumb: [1, 2, 3, 4],
|
||||
index: [5, 6, 7, 8],
|
||||
middle: [9, 10, 11, 12],
|
||||
ring: [13, 14, 15, 16],
|
||||
pinky: [17, 18, 19, 20],
|
||||
thumb: [0, 1, 2, 3, 4],
|
||||
index: [0, 5, 6, 7, 8],
|
||||
middle: [0, 9, 10, 11, 12],
|
||||
ring: [0, 13, 14, 15, 16],
|
||||
pinky: [0, 17, 18, 19, 20],
|
||||
palm: [0],
|
||||
};
|
||||
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
2021-11-23 10:21:50 [36mINFO: [39m Application: {"name":"@vladmandic/human","version":"2.5.4"}
|
||||
2021-11-23 10:21:50 [36mINFO: [39m Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
|
||||
2021-11-23 10:21:50 [36mINFO: [39m 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 [36mINFO: [39m Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
|
||||
2021-11-23 10:21:50 [35mSTATE:[39m Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]}
|
||||
2021-11-23 10:21:50 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":102,"outputBytes":1275}
|
||||
2021-11-23 10:21:50 [35mSTATE:[39m 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-23 10:21:50 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":1283}
|
||||
2021-11-23 10:21:50 [35mSTATE:[39m 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-23 10:21:50 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":149,"outputBytes":1350}
|
||||
2021-11-23 10:21:50 [35mSTATE:[39m 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-23 10:21:50 [35mSTATE:[39m Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1063,"outputBytes":1652}
|
||||
2021-11-23 10:21:50 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":2326,"outputBytes":912}
|
||||
2021-11-23 10:21:50 [35mSTATE:[39m 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-23 10:21:51 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/custom","format":"esm","platform":"browser","input":"tfjs/tf-custom.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":2500868}
|
||||
2021-11-23 10:21:51 [35mSTATE:[39m 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-23 10:21:51 [35mSTATE:[39m 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-23 10:22:12 [35mSTATE:[39m Typings: {"input":"src/human.ts","output":"types/lib","files":110}
|
||||
2021-11-23 10:22:12 [33mWARN: [39m 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 [35mSTATE:[39m TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":52,"generated":true}
|
||||
2021-11-23 10:22:20 [35mSTATE:[39m 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-23 10:22:20 [35mSTATE:[39m Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15174,"outputBytes":11794}
|
||||
2021-11-23 10:23:03 [35mSTATE:[39m Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":94,"errors":0,"warnings":0}
|
||||
2021-11-23 10:23:04 [35mSTATE:[39m ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
|
||||
2021-11-23 10:23:04 [36mINFO: [39m Done...
|
||||
2021-11-24 16:12:45 [36mINFO: [39m Application: {"name":"@vladmandic/human","version":"2.5.4"}
|
||||
2021-11-24 16:12:45 [36mINFO: [39m Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
|
||||
2021-11-24 16:12:45 [36mINFO: [39m 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 [36mINFO: [39m Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
|
||||
2021-11-24 16:12:45 [35mSTATE:[39m Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]}
|
||||
2021-11-24 16:12:45 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":102,"outputBytes":1275}
|
||||
2021-11-24 16:12:45 [35mSTATE:[39m 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-24 16:12:45 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":1283}
|
||||
2021-11-24 16:12:45 [35mSTATE:[39m 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-24 16:12:45 [35mSTATE:[39m Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":149,"outputBytes":1350}
|
||||
2021-11-24 16:12:45 [35mSTATE:[39m 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-24 16:12:45 [35mSTATE:[39m Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1063,"outputBytes":1652}
|
||||
2021-11-24 16:12:45 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":2326,"outputBytes":912}
|
||||
2021-11-24 16:12:45 [35mSTATE:[39m 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-24 16:12:46 [35mSTATE:[39m Compile: {"name":"tfjs/browser/esm/custom","format":"esm","platform":"browser","input":"tfjs/tf-custom.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":2501333}
|
||||
2021-11-24 16:12:46 [35mSTATE:[39m 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-24 16:12:47 [35mSTATE:[39m 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-24 16:13:08 [35mSTATE:[39m Typings: {"input":"src/human.ts","output":"types/lib","files":110}
|
||||
2021-11-24 16:13:08 [33mWARN: [39m 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:16 [35mSTATE:[39m TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":52,"generated":true}
|
||||
2021-11-24 16:13:16 [35mSTATE:[39m 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-24 16:13:16 [35mSTATE:[39m Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15174,"outputBytes":11794}
|
||||
2021-11-24 16:13:55 [35mSTATE:[39m Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":94,"errors":0,"warnings":0}
|
||||
2021-11-24 16:13:55 [35mSTATE:[39m ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
|
||||
2021-11-24 16:13:55 [36mINFO: [39m Done...
|
||||
|
|
1368
test/test.log
1368
test/test.log
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue