update movenet-multipose and samples
|
@ -4,16 +4,16 @@ const process = require('process');
|
|||
const log = require('@vladmandic/pilogger');
|
||||
const canvas = require('canvas');
|
||||
const tf = require('@tensorflow/tfjs-node'); // for nodejs, `tfjs-node` or `tfjs-node-gpu` should be loaded before using Human
|
||||
const Human = require('../dist/human.node.js'); // this is 'const Human = require('../dist/human.node-gpu.js').default;'
|
||||
const Human = require('../../dist/human.node.js'); // this is 'const Human = require('../dist/human.node-gpu.js').default;'
|
||||
|
||||
const config = { // just enable all and leave default settings
|
||||
debug: true,
|
||||
async: false,
|
||||
cacheSensitivity: 0,
|
||||
face: { enabled: true },
|
||||
face: { enabled: true, detector: { maxDetected: 20 } },
|
||||
object: { enabled: true },
|
||||
gesture: { enabled: true },
|
||||
hand: { enabled: true, minConfidence: 0.4, detector: { modelPath: 'handtrack.json' } },
|
||||
hand: { enabled: true },
|
||||
body: { enabled: true, modelPath: 'https://vladmandic.github.io/human-models/models/movenet-multipose.json' },
|
||||
};
|
||||
|
|
@ -4951,7 +4951,6 @@ async function predict(input, config3) {
|
|||
tfjs_esm_exports.dispose(coordsReshaped);
|
||||
if (faceConfidence < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
|
||||
box4.confidence = faceConfidence;
|
||||
tfjs_esm_exports.dispose(face5.tensor);
|
||||
} else {
|
||||
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
|
||||
rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize3);
|
||||
|
@ -9967,6 +9966,25 @@ async function load9(config3) {
|
|||
inputSize6 = 256;
|
||||
return model8;
|
||||
}
|
||||
function createBox2(points) {
|
||||
const x = points.map((a) => a.position[0]);
|
||||
const y = points.map((a) => a.position[1]);
|
||||
const box4 = [
|
||||
Math.min(...x),
|
||||
Math.min(...y),
|
||||
Math.max(...x) - Math.min(...x),
|
||||
Math.max(...y) - Math.min(...y)
|
||||
];
|
||||
const xRaw = points.map((a) => a.positionRaw[0]);
|
||||
const yRaw = points.map((a) => a.positionRaw[1]);
|
||||
const boxRaw2 = [
|
||||
Math.min(...xRaw),
|
||||
Math.min(...yRaw),
|
||||
Math.max(...xRaw) - Math.min(...xRaw),
|
||||
Math.max(...yRaw) - Math.min(...yRaw)
|
||||
];
|
||||
return [box4, boxRaw2];
|
||||
}
|
||||
async function parseSinglePose(res, config3, image24, inputBox) {
|
||||
const kpt = res[0][0];
|
||||
keypoints2.length = 0;
|
||||
|
@ -9990,23 +10008,8 @@ async function parseSinglePose(res, config3, image24, inputBox) {
|
|||
}
|
||||
}
|
||||
score2 = keypoints2.reduce((prev, curr) => curr.score > prev ? curr.score : prev, 0);
|
||||
const x = keypoints2.map((a) => a.position[0]);
|
||||
const y = keypoints2.map((a) => a.position[1]);
|
||||
const box4 = [
|
||||
Math.min(...x),
|
||||
Math.min(...y),
|
||||
Math.max(...x) - Math.min(...x),
|
||||
Math.max(...y) - Math.min(...y)
|
||||
];
|
||||
const xRaw = keypoints2.map((a) => a.positionRaw[0]);
|
||||
const yRaw = keypoints2.map((a) => a.positionRaw[1]);
|
||||
const boxRaw2 = [
|
||||
Math.min(...xRaw),
|
||||
Math.min(...yRaw),
|
||||
Math.max(...xRaw) - Math.min(...xRaw),
|
||||
Math.max(...yRaw) - Math.min(...yRaw)
|
||||
];
|
||||
const bodies = [];
|
||||
const [box4, boxRaw2] = createBox2(keypoints2);
|
||||
bodies.push({ id: 0, score: score2, box: box4, boxRaw: boxRaw2, keypoints: keypoints2 });
|
||||
return bodies;
|
||||
}
|
||||
|
@ -10014,39 +10017,35 @@ async function parseMultiPose(res, config3, image24, inputBox) {
|
|||
const bodies = [];
|
||||
for (let id = 0; id < res[0].length; id++) {
|
||||
const kpt = res[0][id];
|
||||
const score2 = Math.round(100 * kpt[51 + 4]) / 100;
|
||||
if (score2 < config3.body.minConfidence)
|
||||
continue;
|
||||
const totalScore = Math.round(100 * kpt[51 + 4]) / 100;
|
||||
if (totalScore > config3.body.minConfidence) {
|
||||
keypoints2.length = 0;
|
||||
for (let i = 0; i < 17; i++) {
|
||||
const partScore = Math.round(100 * kpt[3 * i + 2]) / 100;
|
||||
if (partScore > config3.body.minConfidence) {
|
||||
const score2 = kpt[3 * i + 2];
|
||||
if (score2 > config3.body.minConfidence) {
|
||||
const positionRaw = [
|
||||
(inputBox[3] - inputBox[1]) * kpt[3 * i + 1] + inputBox[1],
|
||||
(inputBox[2] - inputBox[0]) * kpt[3 * i + 0] + inputBox[0]
|
||||
];
|
||||
keypoints2.push({
|
||||
part: bodyParts2[i],
|
||||
score: partScore,
|
||||
score: Math.round(100 * score2) / 100,
|
||||
positionRaw,
|
||||
position: [Math.trunc(positionRaw[0] * (image24.shape[2] || 0)), Math.trunc(positionRaw[0] * (image24.shape[1] || 0))]
|
||||
position: [
|
||||
Math.round((image24.shape[2] || 0) * positionRaw[0]),
|
||||
Math.round((image24.shape[1] || 0) * positionRaw[1])
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
const boxRaw2 = [kpt[51 + 1], kpt[51 + 0], kpt[51 + 3] - kpt[51 + 1], kpt[51 + 2] - kpt[51 + 0]];
|
||||
bodies.push({
|
||||
id,
|
||||
score: score2,
|
||||
boxRaw: boxRaw2,
|
||||
box: [
|
||||
Math.trunc(boxRaw2[0] * (image24.shape[2] || 0)),
|
||||
Math.trunc(boxRaw2[1] * (image24.shape[1] || 0)),
|
||||
Math.trunc(boxRaw2[2] * (image24.shape[2] || 0)),
|
||||
Math.trunc(boxRaw2[3] * (image24.shape[1] || 0))
|
||||
],
|
||||
keypoints: [...keypoints2]
|
||||
});
|
||||
const box4 = [Math.trunc(boxRaw2[0] * (image24.shape[2] || 0)), Math.trunc(boxRaw2[1] * (image24.shape[1] || 0)), Math.trunc(boxRaw2[2] * (image24.shape[2] || 0)), Math.trunc(boxRaw2[3] * (image24.shape[1] || 0))];
|
||||
bodies.push({ id, score: totalScore, boxRaw: boxRaw2, box: box4, keypoints: [...keypoints2] });
|
||||
}
|
||||
}
|
||||
bodies.sort((a, b) => b.score - a.score);
|
||||
if (bodies.length > config3.body.maxDetected)
|
||||
bodies.length = config3.body.maxDetected;
|
||||
return bodies;
|
||||
}
|
||||
async function predict9(input, config3) {
|
||||
|
|
|
@ -65019,7 +65019,6 @@ async function predict(input2, config3) {
|
|||
dispose(coordsReshaped);
|
||||
if (faceConfidence < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
|
||||
box4.confidence = faceConfidence;
|
||||
dispose(face5.tensor);
|
||||
} else {
|
||||
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
|
||||
rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize3);
|
||||
|
@ -70035,6 +70034,25 @@ async function load9(config3) {
|
|||
inputSize6 = 256;
|
||||
return model9;
|
||||
}
|
||||
function createBox2(points) {
|
||||
const x = points.map((a) => a.position[0]);
|
||||
const y = points.map((a) => a.position[1]);
|
||||
const box4 = [
|
||||
Math.min(...x),
|
||||
Math.min(...y),
|
||||
Math.max(...x) - Math.min(...x),
|
||||
Math.max(...y) - Math.min(...y)
|
||||
];
|
||||
const xRaw = points.map((a) => a.positionRaw[0]);
|
||||
const yRaw = points.map((a) => a.positionRaw[1]);
|
||||
const boxRaw2 = [
|
||||
Math.min(...xRaw),
|
||||
Math.min(...yRaw),
|
||||
Math.max(...xRaw) - Math.min(...xRaw),
|
||||
Math.max(...yRaw) - Math.min(...yRaw)
|
||||
];
|
||||
return [box4, boxRaw2];
|
||||
}
|
||||
async function parseSinglePose(res, config3, image7, inputBox) {
|
||||
const kpt = res[0][0];
|
||||
keypoints2.length = 0;
|
||||
|
@ -70058,23 +70076,8 @@ async function parseSinglePose(res, config3, image7, inputBox) {
|
|||
}
|
||||
}
|
||||
score2 = keypoints2.reduce((prev, curr) => curr.score > prev ? curr.score : prev, 0);
|
||||
const x = keypoints2.map((a) => a.position[0]);
|
||||
const y = keypoints2.map((a) => a.position[1]);
|
||||
const box4 = [
|
||||
Math.min(...x),
|
||||
Math.min(...y),
|
||||
Math.max(...x) - Math.min(...x),
|
||||
Math.max(...y) - Math.min(...y)
|
||||
];
|
||||
const xRaw = keypoints2.map((a) => a.positionRaw[0]);
|
||||
const yRaw = keypoints2.map((a) => a.positionRaw[1]);
|
||||
const boxRaw2 = [
|
||||
Math.min(...xRaw),
|
||||
Math.min(...yRaw),
|
||||
Math.max(...xRaw) - Math.min(...xRaw),
|
||||
Math.max(...yRaw) - Math.min(...yRaw)
|
||||
];
|
||||
const bodies = [];
|
||||
const [box4, boxRaw2] = createBox2(keypoints2);
|
||||
bodies.push({ id: 0, score: score2, box: box4, boxRaw: boxRaw2, keypoints: keypoints2 });
|
||||
return bodies;
|
||||
}
|
||||
|
@ -70082,39 +70085,35 @@ async function parseMultiPose(res, config3, image7, inputBox) {
|
|||
const bodies = [];
|
||||
for (let id = 0; id < res[0].length; id++) {
|
||||
const kpt = res[0][id];
|
||||
const score2 = Math.round(100 * kpt[51 + 4]) / 100;
|
||||
if (score2 < config3.body.minConfidence)
|
||||
continue;
|
||||
const totalScore = Math.round(100 * kpt[51 + 4]) / 100;
|
||||
if (totalScore > config3.body.minConfidence) {
|
||||
keypoints2.length = 0;
|
||||
for (let i = 0; i < 17; i++) {
|
||||
const partScore = Math.round(100 * kpt[3 * i + 2]) / 100;
|
||||
if (partScore > config3.body.minConfidence) {
|
||||
const score2 = kpt[3 * i + 2];
|
||||
if (score2 > config3.body.minConfidence) {
|
||||
const positionRaw = [
|
||||
(inputBox[3] - inputBox[1]) * kpt[3 * i + 1] + inputBox[1],
|
||||
(inputBox[2] - inputBox[0]) * kpt[3 * i + 0] + inputBox[0]
|
||||
];
|
||||
keypoints2.push({
|
||||
part: bodyParts2[i],
|
||||
score: partScore,
|
||||
score: Math.round(100 * score2) / 100,
|
||||
positionRaw,
|
||||
position: [Math.trunc(positionRaw[0] * (image7.shape[2] || 0)), Math.trunc(positionRaw[0] * (image7.shape[1] || 0))]
|
||||
position: [
|
||||
Math.round((image7.shape[2] || 0) * positionRaw[0]),
|
||||
Math.round((image7.shape[1] || 0) * positionRaw[1])
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
const boxRaw2 = [kpt[51 + 1], kpt[51 + 0], kpt[51 + 3] - kpt[51 + 1], kpt[51 + 2] - kpt[51 + 0]];
|
||||
bodies.push({
|
||||
id,
|
||||
score: score2,
|
||||
boxRaw: boxRaw2,
|
||||
box: [
|
||||
Math.trunc(boxRaw2[0] * (image7.shape[2] || 0)),
|
||||
Math.trunc(boxRaw2[1] * (image7.shape[1] || 0)),
|
||||
Math.trunc(boxRaw2[2] * (image7.shape[2] || 0)),
|
||||
Math.trunc(boxRaw2[3] * (image7.shape[1] || 0))
|
||||
],
|
||||
keypoints: [...keypoints2]
|
||||
});
|
||||
const box4 = [Math.trunc(boxRaw2[0] * (image7.shape[2] || 0)), Math.trunc(boxRaw2[1] * (image7.shape[1] || 0)), Math.trunc(boxRaw2[2] * (image7.shape[2] || 0)), Math.trunc(boxRaw2[3] * (image7.shape[1] || 0))];
|
||||
bodies.push({ id, score: totalScore, boxRaw: boxRaw2, box: box4, keypoints: [...keypoints2] });
|
||||
}
|
||||
}
|
||||
bodies.sort((a, b) => b.score - a.score);
|
||||
if (bodies.length > config3.body.maxDetected)
|
||||
bodies.length = config3.body.maxDetected;
|
||||
return bodies;
|
||||
}
|
||||
async function predict9(input2, config3) {
|
||||
|
|
|
@ -4983,7 +4983,6 @@ async function predict(input, config3) {
|
|||
tf6.dispose(coordsReshaped);
|
||||
if (faceConfidence < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
|
||||
box4.confidence = faceConfidence;
|
||||
tf6.dispose(face5.tensor);
|
||||
} else {
|
||||
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
|
||||
rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize3);
|
||||
|
@ -10024,6 +10023,25 @@ async function load9(config3) {
|
|||
inputSize6 = 256;
|
||||
return model8;
|
||||
}
|
||||
function createBox2(points) {
|
||||
const x = points.map((a) => a.position[0]);
|
||||
const y = points.map((a) => a.position[1]);
|
||||
const box4 = [
|
||||
Math.min(...x),
|
||||
Math.min(...y),
|
||||
Math.max(...x) - Math.min(...x),
|
||||
Math.max(...y) - Math.min(...y)
|
||||
];
|
||||
const xRaw = points.map((a) => a.positionRaw[0]);
|
||||
const yRaw = points.map((a) => a.positionRaw[1]);
|
||||
const boxRaw2 = [
|
||||
Math.min(...xRaw),
|
||||
Math.min(...yRaw),
|
||||
Math.max(...xRaw) - Math.min(...xRaw),
|
||||
Math.max(...yRaw) - Math.min(...yRaw)
|
||||
];
|
||||
return [box4, boxRaw2];
|
||||
}
|
||||
async function parseSinglePose(res, config3, image24, inputBox) {
|
||||
const kpt = res[0][0];
|
||||
keypoints2.length = 0;
|
||||
|
@ -10047,23 +10065,8 @@ async function parseSinglePose(res, config3, image24, inputBox) {
|
|||
}
|
||||
}
|
||||
score2 = keypoints2.reduce((prev, curr) => curr.score > prev ? curr.score : prev, 0);
|
||||
const x = keypoints2.map((a) => a.position[0]);
|
||||
const y = keypoints2.map((a) => a.position[1]);
|
||||
const box4 = [
|
||||
Math.min(...x),
|
||||
Math.min(...y),
|
||||
Math.max(...x) - Math.min(...x),
|
||||
Math.max(...y) - Math.min(...y)
|
||||
];
|
||||
const xRaw = keypoints2.map((a) => a.positionRaw[0]);
|
||||
const yRaw = keypoints2.map((a) => a.positionRaw[1]);
|
||||
const boxRaw2 = [
|
||||
Math.min(...xRaw),
|
||||
Math.min(...yRaw),
|
||||
Math.max(...xRaw) - Math.min(...xRaw),
|
||||
Math.max(...yRaw) - Math.min(...yRaw)
|
||||
];
|
||||
const bodies = [];
|
||||
const [box4, boxRaw2] = createBox2(keypoints2);
|
||||
bodies.push({ id: 0, score: score2, box: box4, boxRaw: boxRaw2, keypoints: keypoints2 });
|
||||
return bodies;
|
||||
}
|
||||
|
@ -10071,39 +10074,35 @@ async function parseMultiPose(res, config3, image24, inputBox) {
|
|||
const bodies = [];
|
||||
for (let id = 0; id < res[0].length; id++) {
|
||||
const kpt = res[0][id];
|
||||
const score2 = Math.round(100 * kpt[51 + 4]) / 100;
|
||||
if (score2 < config3.body.minConfidence)
|
||||
continue;
|
||||
const totalScore = Math.round(100 * kpt[51 + 4]) / 100;
|
||||
if (totalScore > config3.body.minConfidence) {
|
||||
keypoints2.length = 0;
|
||||
for (let i = 0; i < 17; i++) {
|
||||
const partScore = Math.round(100 * kpt[3 * i + 2]) / 100;
|
||||
if (partScore > config3.body.minConfidence) {
|
||||
const score2 = kpt[3 * i + 2];
|
||||
if (score2 > config3.body.minConfidence) {
|
||||
const positionRaw = [
|
||||
(inputBox[3] - inputBox[1]) * kpt[3 * i + 1] + inputBox[1],
|
||||
(inputBox[2] - inputBox[0]) * kpt[3 * i + 0] + inputBox[0]
|
||||
];
|
||||
keypoints2.push({
|
||||
part: bodyParts2[i],
|
||||
score: partScore,
|
||||
score: Math.round(100 * score2) / 100,
|
||||
positionRaw,
|
||||
position: [Math.trunc(positionRaw[0] * (image24.shape[2] || 0)), Math.trunc(positionRaw[0] * (image24.shape[1] || 0))]
|
||||
position: [
|
||||
Math.round((image24.shape[2] || 0) * positionRaw[0]),
|
||||
Math.round((image24.shape[1] || 0) * positionRaw[1])
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
const boxRaw2 = [kpt[51 + 1], kpt[51 + 0], kpt[51 + 3] - kpt[51 + 1], kpt[51 + 2] - kpt[51 + 0]];
|
||||
bodies.push({
|
||||
id,
|
||||
score: score2,
|
||||
boxRaw: boxRaw2,
|
||||
box: [
|
||||
Math.trunc(boxRaw2[0] * (image24.shape[2] || 0)),
|
||||
Math.trunc(boxRaw2[1] * (image24.shape[1] || 0)),
|
||||
Math.trunc(boxRaw2[2] * (image24.shape[2] || 0)),
|
||||
Math.trunc(boxRaw2[3] * (image24.shape[1] || 0))
|
||||
],
|
||||
keypoints: [...keypoints2]
|
||||
});
|
||||
const box4 = [Math.trunc(boxRaw2[0] * (image24.shape[2] || 0)), Math.trunc(boxRaw2[1] * (image24.shape[1] || 0)), Math.trunc(boxRaw2[2] * (image24.shape[2] || 0)), Math.trunc(boxRaw2[3] * (image24.shape[1] || 0))];
|
||||
bodies.push({ id, score: totalScore, boxRaw: boxRaw2, box: box4, keypoints: [...keypoints2] });
|
||||
}
|
||||
}
|
||||
bodies.sort((a, b) => b.score - a.score);
|
||||
if (bodies.length > config3.body.maxDetected)
|
||||
bodies.length = config3.body.maxDetected;
|
||||
return bodies;
|
||||
}
|
||||
async function predict9(input, config3) {
|
||||
|
|
|
@ -4984,7 +4984,6 @@ async function predict(input, config3) {
|
|||
tf6.dispose(coordsReshaped);
|
||||
if (faceConfidence < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
|
||||
box4.confidence = faceConfidence;
|
||||
tf6.dispose(face5.tensor);
|
||||
} else {
|
||||
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
|
||||
rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize3);
|
||||
|
@ -10025,6 +10024,25 @@ async function load9(config3) {
|
|||
inputSize6 = 256;
|
||||
return model8;
|
||||
}
|
||||
function createBox2(points) {
|
||||
const x = points.map((a) => a.position[0]);
|
||||
const y = points.map((a) => a.position[1]);
|
||||
const box4 = [
|
||||
Math.min(...x),
|
||||
Math.min(...y),
|
||||
Math.max(...x) - Math.min(...x),
|
||||
Math.max(...y) - Math.min(...y)
|
||||
];
|
||||
const xRaw = points.map((a) => a.positionRaw[0]);
|
||||
const yRaw = points.map((a) => a.positionRaw[1]);
|
||||
const boxRaw2 = [
|
||||
Math.min(...xRaw),
|
||||
Math.min(...yRaw),
|
||||
Math.max(...xRaw) - Math.min(...xRaw),
|
||||
Math.max(...yRaw) - Math.min(...yRaw)
|
||||
];
|
||||
return [box4, boxRaw2];
|
||||
}
|
||||
async function parseSinglePose(res, config3, image24, inputBox) {
|
||||
const kpt = res[0][0];
|
||||
keypoints2.length = 0;
|
||||
|
@ -10048,23 +10066,8 @@ async function parseSinglePose(res, config3, image24, inputBox) {
|
|||
}
|
||||
}
|
||||
score2 = keypoints2.reduce((prev, curr) => curr.score > prev ? curr.score : prev, 0);
|
||||
const x = keypoints2.map((a) => a.position[0]);
|
||||
const y = keypoints2.map((a) => a.position[1]);
|
||||
const box4 = [
|
||||
Math.min(...x),
|
||||
Math.min(...y),
|
||||
Math.max(...x) - Math.min(...x),
|
||||
Math.max(...y) - Math.min(...y)
|
||||
];
|
||||
const xRaw = keypoints2.map((a) => a.positionRaw[0]);
|
||||
const yRaw = keypoints2.map((a) => a.positionRaw[1]);
|
||||
const boxRaw2 = [
|
||||
Math.min(...xRaw),
|
||||
Math.min(...yRaw),
|
||||
Math.max(...xRaw) - Math.min(...xRaw),
|
||||
Math.max(...yRaw) - Math.min(...yRaw)
|
||||
];
|
||||
const bodies = [];
|
||||
const [box4, boxRaw2] = createBox2(keypoints2);
|
||||
bodies.push({ id: 0, score: score2, box: box4, boxRaw: boxRaw2, keypoints: keypoints2 });
|
||||
return bodies;
|
||||
}
|
||||
|
@ -10072,39 +10075,35 @@ async function parseMultiPose(res, config3, image24, inputBox) {
|
|||
const bodies = [];
|
||||
for (let id = 0; id < res[0].length; id++) {
|
||||
const kpt = res[0][id];
|
||||
const score2 = Math.round(100 * kpt[51 + 4]) / 100;
|
||||
if (score2 < config3.body.minConfidence)
|
||||
continue;
|
||||
const totalScore = Math.round(100 * kpt[51 + 4]) / 100;
|
||||
if (totalScore > config3.body.minConfidence) {
|
||||
keypoints2.length = 0;
|
||||
for (let i = 0; i < 17; i++) {
|
||||
const partScore = Math.round(100 * kpt[3 * i + 2]) / 100;
|
||||
if (partScore > config3.body.minConfidence) {
|
||||
const score2 = kpt[3 * i + 2];
|
||||
if (score2 > config3.body.minConfidence) {
|
||||
const positionRaw = [
|
||||
(inputBox[3] - inputBox[1]) * kpt[3 * i + 1] + inputBox[1],
|
||||
(inputBox[2] - inputBox[0]) * kpt[3 * i + 0] + inputBox[0]
|
||||
];
|
||||
keypoints2.push({
|
||||
part: bodyParts2[i],
|
||||
score: partScore,
|
||||
score: Math.round(100 * score2) / 100,
|
||||
positionRaw,
|
||||
position: [Math.trunc(positionRaw[0] * (image24.shape[2] || 0)), Math.trunc(positionRaw[0] * (image24.shape[1] || 0))]
|
||||
position: [
|
||||
Math.round((image24.shape[2] || 0) * positionRaw[0]),
|
||||
Math.round((image24.shape[1] || 0) * positionRaw[1])
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
const boxRaw2 = [kpt[51 + 1], kpt[51 + 0], kpt[51 + 3] - kpt[51 + 1], kpt[51 + 2] - kpt[51 + 0]];
|
||||
bodies.push({
|
||||
id,
|
||||
score: score2,
|
||||
boxRaw: boxRaw2,
|
||||
box: [
|
||||
Math.trunc(boxRaw2[0] * (image24.shape[2] || 0)),
|
||||
Math.trunc(boxRaw2[1] * (image24.shape[1] || 0)),
|
||||
Math.trunc(boxRaw2[2] * (image24.shape[2] || 0)),
|
||||
Math.trunc(boxRaw2[3] * (image24.shape[1] || 0))
|
||||
],
|
||||
keypoints: [...keypoints2]
|
||||
});
|
||||
const box4 = [Math.trunc(boxRaw2[0] * (image24.shape[2] || 0)), Math.trunc(boxRaw2[1] * (image24.shape[1] || 0)), Math.trunc(boxRaw2[2] * (image24.shape[2] || 0)), Math.trunc(boxRaw2[3] * (image24.shape[1] || 0))];
|
||||
bodies.push({ id, score: totalScore, boxRaw: boxRaw2, box: box4, keypoints: [...keypoints2] });
|
||||
}
|
||||
}
|
||||
bodies.sort((a, b) => b.score - a.score);
|
||||
if (bodies.length > config3.body.maxDetected)
|
||||
bodies.length = config3.body.maxDetected;
|
||||
return bodies;
|
||||
}
|
||||
async function predict9(input, config3) {
|
||||
|
|
|
@ -4983,7 +4983,6 @@ async function predict(input, config3) {
|
|||
tf6.dispose(coordsReshaped);
|
||||
if (faceConfidence < (((_h = config3.face.detector) == null ? void 0 : _h.minConfidence) || 1)) {
|
||||
box4.confidence = faceConfidence;
|
||||
tf6.dispose(face5.tensor);
|
||||
} else {
|
||||
if ((_i = config3.face.iris) == null ? void 0 : _i.enabled)
|
||||
rawCoords = await augmentIris(rawCoords, face5.tensor, config3, inputSize3);
|
||||
|
@ -10024,6 +10023,25 @@ async function load9(config3) {
|
|||
inputSize6 = 256;
|
||||
return model8;
|
||||
}
|
||||
function createBox2(points) {
|
||||
const x = points.map((a) => a.position[0]);
|
||||
const y = points.map((a) => a.position[1]);
|
||||
const box4 = [
|
||||
Math.min(...x),
|
||||
Math.min(...y),
|
||||
Math.max(...x) - Math.min(...x),
|
||||
Math.max(...y) - Math.min(...y)
|
||||
];
|
||||
const xRaw = points.map((a) => a.positionRaw[0]);
|
||||
const yRaw = points.map((a) => a.positionRaw[1]);
|
||||
const boxRaw2 = [
|
||||
Math.min(...xRaw),
|
||||
Math.min(...yRaw),
|
||||
Math.max(...xRaw) - Math.min(...xRaw),
|
||||
Math.max(...yRaw) - Math.min(...yRaw)
|
||||
];
|
||||
return [box4, boxRaw2];
|
||||
}
|
||||
async function parseSinglePose(res, config3, image24, inputBox) {
|
||||
const kpt = res[0][0];
|
||||
keypoints2.length = 0;
|
||||
|
@ -10047,23 +10065,8 @@ async function parseSinglePose(res, config3, image24, inputBox) {
|
|||
}
|
||||
}
|
||||
score2 = keypoints2.reduce((prev, curr) => curr.score > prev ? curr.score : prev, 0);
|
||||
const x = keypoints2.map((a) => a.position[0]);
|
||||
const y = keypoints2.map((a) => a.position[1]);
|
||||
const box4 = [
|
||||
Math.min(...x),
|
||||
Math.min(...y),
|
||||
Math.max(...x) - Math.min(...x),
|
||||
Math.max(...y) - Math.min(...y)
|
||||
];
|
||||
const xRaw = keypoints2.map((a) => a.positionRaw[0]);
|
||||
const yRaw = keypoints2.map((a) => a.positionRaw[1]);
|
||||
const boxRaw2 = [
|
||||
Math.min(...xRaw),
|
||||
Math.min(...yRaw),
|
||||
Math.max(...xRaw) - Math.min(...xRaw),
|
||||
Math.max(...yRaw) - Math.min(...yRaw)
|
||||
];
|
||||
const bodies = [];
|
||||
const [box4, boxRaw2] = createBox2(keypoints2);
|
||||
bodies.push({ id: 0, score: score2, box: box4, boxRaw: boxRaw2, keypoints: keypoints2 });
|
||||
return bodies;
|
||||
}
|
||||
|
@ -10071,39 +10074,35 @@ async function parseMultiPose(res, config3, image24, inputBox) {
|
|||
const bodies = [];
|
||||
for (let id = 0; id < res[0].length; id++) {
|
||||
const kpt = res[0][id];
|
||||
const score2 = Math.round(100 * kpt[51 + 4]) / 100;
|
||||
if (score2 < config3.body.minConfidence)
|
||||
continue;
|
||||
const totalScore = Math.round(100 * kpt[51 + 4]) / 100;
|
||||
if (totalScore > config3.body.minConfidence) {
|
||||
keypoints2.length = 0;
|
||||
for (let i = 0; i < 17; i++) {
|
||||
const partScore = Math.round(100 * kpt[3 * i + 2]) / 100;
|
||||
if (partScore > config3.body.minConfidence) {
|
||||
const score2 = kpt[3 * i + 2];
|
||||
if (score2 > config3.body.minConfidence) {
|
||||
const positionRaw = [
|
||||
(inputBox[3] - inputBox[1]) * kpt[3 * i + 1] + inputBox[1],
|
||||
(inputBox[2] - inputBox[0]) * kpt[3 * i + 0] + inputBox[0]
|
||||
];
|
||||
keypoints2.push({
|
||||
part: bodyParts2[i],
|
||||
score: partScore,
|
||||
score: Math.round(100 * score2) / 100,
|
||||
positionRaw,
|
||||
position: [Math.trunc(positionRaw[0] * (image24.shape[2] || 0)), Math.trunc(positionRaw[0] * (image24.shape[1] || 0))]
|
||||
position: [
|
||||
Math.round((image24.shape[2] || 0) * positionRaw[0]),
|
||||
Math.round((image24.shape[1] || 0) * positionRaw[1])
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
const boxRaw2 = [kpt[51 + 1], kpt[51 + 0], kpt[51 + 3] - kpt[51 + 1], kpt[51 + 2] - kpt[51 + 0]];
|
||||
bodies.push({
|
||||
id,
|
||||
score: score2,
|
||||
boxRaw: boxRaw2,
|
||||
box: [
|
||||
Math.trunc(boxRaw2[0] * (image24.shape[2] || 0)),
|
||||
Math.trunc(boxRaw2[1] * (image24.shape[1] || 0)),
|
||||
Math.trunc(boxRaw2[2] * (image24.shape[2] || 0)),
|
||||
Math.trunc(boxRaw2[3] * (image24.shape[1] || 0))
|
||||
],
|
||||
keypoints: [...keypoints2]
|
||||
});
|
||||
const box4 = [Math.trunc(boxRaw2[0] * (image24.shape[2] || 0)), Math.trunc(boxRaw2[1] * (image24.shape[1] || 0)), Math.trunc(boxRaw2[2] * (image24.shape[2] || 0)), Math.trunc(boxRaw2[3] * (image24.shape[1] || 0))];
|
||||
bodies.push({ id, score: totalScore, boxRaw: boxRaw2, box: box4, keypoints: [...keypoints2] });
|
||||
}
|
||||
}
|
||||
bodies.sort((a, b) => b.score - a.score);
|
||||
if (bodies.length > config3.body.maxDetected)
|
||||
bodies.length = config3.body.maxDetected;
|
||||
return bodies;
|
||||
}
|
||||
async function predict9(input, config3) {
|
||||
|
|
|
@ -5,8 +5,6 @@ Not required for normal funcioning of library
|
|||
|
||||
Samples were generated using command:
|
||||
|
||||
```shell
|
||||
node test/test-node-canvas.js samples/in/ samples/out/
|
||||
```
|
||||
> node demo/nodejs/process-folder.js samples/in/ samples/out/
|
||||
|
||||
Samples galery viewer: <https://vladmandic.github.io/human/samples/samples.html>
|
||||
|
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 288 KiB After Width: | Height: | Size: 263 KiB |
Before Width: | Height: | Size: 306 KiB After Width: | Height: | Size: 306 KiB |
Before Width: | Height: | Size: 285 KiB After Width: | Height: | Size: 263 KiB |
Before Width: | Height: | Size: 274 KiB After Width: | Height: | Size: 277 KiB |
Before Width: | Height: | Size: 284 KiB After Width: | Height: | Size: 263 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 114 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 100 KiB |
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 166 KiB After Width: | Height: | Size: 165 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 190 KiB After Width: | Height: | Size: 192 KiB |
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 83 KiB |
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 179 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 163 KiB After Width: | Height: | Size: 162 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 374 KiB After Width: | Height: | Size: 368 KiB |
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 124 KiB |
Before Width: | Height: | Size: 321 KiB After Width: | Height: | Size: 323 KiB |
Before Width: | Height: | Size: 327 KiB After Width: | Height: | Size: 309 KiB |
Before Width: | Height: | Size: 424 KiB After Width: | Height: | Size: 423 KiB |
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 209 KiB |
Before Width: | Height: | Size: 232 KiB After Width: | Height: | Size: 233 KiB |
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 98 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 127 KiB |
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 119 KiB |
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 174 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 115 KiB |
Before Width: | Height: | Size: 181 KiB After Width: | Height: | Size: 182 KiB |
|
@ -21,12 +21,14 @@
|
|||
::-webkit-scrollbar-track { margin: 3px; }
|
||||
.text { margin: 24px }
|
||||
.strip { display: flex; width: 100%; overflow-x: auto; overflow-y: hidden; scroll-behavior: smooth; }
|
||||
.thumb { height: 180px; margin: 2px; padding: 2px; }
|
||||
.thumb { height: 180px; margin: 2px; padding: 2px; cursor: grab; }
|
||||
.thumb:hover { filter: grayscale(1); transform: scale(1.08); transition : all 0.3s ease; }
|
||||
.image-container { margin: 24px 3px 3px 3px }
|
||||
.image-container { margin: 24px 3px 3px 3px; cursor: nwse-resize; }
|
||||
.image-zoomwidth { max-width: 94vw; }
|
||||
.image-zoomheight { max-height: 70vh; }
|
||||
.image-zoomfull { max-height: -webkit-fill-available; }
|
||||
.arrow { font-size: 2rem; font-weight: bolder; background: grey; border-radius: 4px; position: fixed; top: 140px; opacity: 65%; cursor: pointer; }
|
||||
.arrow:hover { background: white; color: grey }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -34,6 +36,8 @@
|
|||
<div id="strip" class="strip"></div>
|
||||
<div class="image-container">
|
||||
<img id="image" src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" alt="" class="image-zoomwidth" />
|
||||
<div class="arrow" id="arrow-left" style="left: 10px"><</div>
|
||||
<div class="arrow" id="arrow-right" style="right: 10px">></div>
|
||||
</div>
|
||||
<script>
|
||||
const samples = [
|
||||
|
@ -54,13 +58,14 @@
|
|||
else if (image.classList.contains('image-zoomfull')) image.className = 'image-zoomwidth';
|
||||
});
|
||||
const strip = document.getElementById('strip');
|
||||
document.getElementById('arrow-left').addEventListener('click', () => strip.scrollLeft -= strip.offsetWidth);
|
||||
document.getElementById('arrow-right').addEventListener('click', () => strip.scrollLeft += strip.offsetWidth);
|
||||
for (const sample of samples) {
|
||||
const el = document.createElement('img');
|
||||
el.className = 'thumb';
|
||||
el.src = el.title = el.alt = `/samples/in/${sample}`;
|
||||
el.addEventListener('click', (evt) => {
|
||||
image.src = image.alt = image.title = el.src.replace('/in/', '/out/');
|
||||
console.log(evt);
|
||||
strip.scrollLeft = evt.target.offsetLeft - window.innerWidth / 2 + evt.target.offsetWidth / 2;
|
||||
});
|
||||
strip.appendChild(el);
|
||||
|
|
|
@ -38,6 +38,26 @@ export async function load(config: Config): Promise<GraphModel> {
|
|||
return model;
|
||||
}
|
||||
|
||||
function createBox(points): [Box, Box] {
|
||||
const x = points.map((a) => a.position[0]);
|
||||
const y = points.map((a) => a.position[1]);
|
||||
const box: Box = [
|
||||
Math.min(...x),
|
||||
Math.min(...y),
|
||||
Math.max(...x) - Math.min(...x),
|
||||
Math.max(...y) - Math.min(...y),
|
||||
];
|
||||
const xRaw = points.map((a) => a.positionRaw[0]);
|
||||
const yRaw = points.map((a) => a.positionRaw[1]);
|
||||
const boxRaw: Box = [
|
||||
Math.min(...xRaw),
|
||||
Math.min(...yRaw),
|
||||
Math.max(...xRaw) - Math.min(...xRaw),
|
||||
Math.max(...yRaw) - Math.min(...yRaw),
|
||||
];
|
||||
return [box, boxRaw];
|
||||
}
|
||||
|
||||
async function parseSinglePose(res, config, image, inputBox) {
|
||||
const kpt = res[0][0];
|
||||
keypoints.length = 0;
|
||||
|
@ -61,23 +81,8 @@ async function parseSinglePose(res, config, image, inputBox) {
|
|||
}
|
||||
}
|
||||
score = keypoints.reduce((prev, curr) => (curr.score > prev ? curr.score : prev), 0);
|
||||
const x = keypoints.map((a) => a.position[0]);
|
||||
const y = keypoints.map((a) => a.position[1]);
|
||||
const box: Box = [
|
||||
Math.min(...x),
|
||||
Math.min(...y),
|
||||
Math.max(...x) - Math.min(...x),
|
||||
Math.max(...y) - Math.min(...y),
|
||||
];
|
||||
const xRaw = keypoints.map((a) => a.positionRaw[0]);
|
||||
const yRaw = keypoints.map((a) => a.positionRaw[1]);
|
||||
const boxRaw: Box = [
|
||||
Math.min(...xRaw),
|
||||
Math.min(...yRaw),
|
||||
Math.max(...xRaw) - Math.min(...xRaw),
|
||||
Math.max(...yRaw) - Math.min(...yRaw),
|
||||
];
|
||||
const bodies: Array<Body> = [];
|
||||
const [box, boxRaw] = createBox(keypoints);
|
||||
bodies.push({ id: 0, score, box, boxRaw, keypoints });
|
||||
return bodies;
|
||||
}
|
||||
|
@ -86,39 +91,36 @@ async function parseMultiPose(res, config, image, inputBox) {
|
|||
const bodies: Array<Body> = [];
|
||||
for (let id = 0; id < res[0].length; id++) {
|
||||
const kpt = res[0][id];
|
||||
const score = Math.round(100 * kpt[51 + 4]) / 100;
|
||||
// eslint-disable-next-line no-continue
|
||||
if (score < config.body.minConfidence) continue;
|
||||
const totalScore = Math.round(100 * kpt[51 + 4]) / 100;
|
||||
if (totalScore > config.body.minConfidence) {
|
||||
keypoints.length = 0;
|
||||
for (let i = 0; i < 17; i++) {
|
||||
const partScore = Math.round(100 * kpt[3 * i + 2]) / 100;
|
||||
if (partScore > config.body.minConfidence) {
|
||||
const score = kpt[3 * i + 2];
|
||||
if (score > config.body.minConfidence) {
|
||||
const positionRaw: Point = [
|
||||
(inputBox[3] - inputBox[1]) * kpt[3 * i + 1] + inputBox[1],
|
||||
(inputBox[2] - inputBox[0]) * kpt[3 * i + 0] + inputBox[0],
|
||||
];
|
||||
keypoints.push({
|
||||
part: bodyParts[i],
|
||||
score: partScore,
|
||||
score: Math.round(100 * score) / 100,
|
||||
positionRaw,
|
||||
position: [Math.trunc(positionRaw[0] * (image.shape[2] || 0)), Math.trunc(positionRaw[0] * (image.shape[1] || 0))],
|
||||
});
|
||||
}
|
||||
}
|
||||
const boxRaw: Box = [kpt[51 + 1], kpt[51 + 0], kpt[51 + 3] - kpt[51 + 1], kpt[51 + 2] - kpt[51 + 0]];
|
||||
bodies.push({
|
||||
id,
|
||||
score,
|
||||
boxRaw,
|
||||
box: [
|
||||
Math.trunc(boxRaw[0] * (image.shape[2] || 0)),
|
||||
Math.trunc(boxRaw[1] * (image.shape[1] || 0)),
|
||||
Math.trunc(boxRaw[2] * (image.shape[2] || 0)),
|
||||
Math.trunc(boxRaw[3] * (image.shape[1] || 0)),
|
||||
position: [
|
||||
Math.round((image.shape[2] || 0) * positionRaw[0]),
|
||||
Math.round((image.shape[1] || 0) * positionRaw[1]),
|
||||
],
|
||||
keypoints: [...keypoints],
|
||||
});
|
||||
}
|
||||
}
|
||||
// const [box, boxRaw] = createBox(keypoints);
|
||||
// movenet-multipose has built-in box details
|
||||
const boxRaw: Box = [kpt[51 + 1], kpt[51 + 0], kpt[51 + 3] - kpt[51 + 1], kpt[51 + 2] - kpt[51 + 0]];
|
||||
const box: Box = [Math.trunc(boxRaw[0] * (image.shape[2] || 0)), Math.trunc(boxRaw[1] * (image.shape[1] || 0)), Math.trunc(boxRaw[2] * (image.shape[2] || 0)), Math.trunc(boxRaw[3] * (image.shape[1] || 0))];
|
||||
bodies.push({ id, score: totalScore, boxRaw, box, keypoints: [...keypoints] });
|
||||
}
|
||||
}
|
||||
bodies.sort((a, b) => b.score - a.score);
|
||||
if (bodies.length > config.body.maxDetected) bodies.length = config.body.maxDetected;
|
||||
return bodies;
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,6 @@ export async function predict(input: Tensor, config: Config): Promise<FaceResult
|
|||
tf.dispose(coordsReshaped);
|
||||
if (faceConfidence < (config.face.detector?.minConfidence || 1)) {
|
||||
box.confidence = faceConfidence; // reset confidence of cached box
|
||||
tf.dispose(face.tensor);
|
||||
} else {
|
||||
if (config.face.iris?.enabled) rawCoords = await iris.augmentIris(rawCoords, face.tensor, config, inputSize); // augment results with iris
|
||||
face.mesh = util.transformRawCoords(rawCoords, box, angle, rotationMatrix, inputSize); // get processed mesh
|
||||
|
|