release preview

pull/233/head
Vladimir Mandic 2021-11-23 10:40:40 -05:00
parent f01296cc2d
commit db6fe46741
19 changed files with 1261 additions and 2234 deletions

View File

@ -9,6 +9,10 @@
## Changelog ## Changelog
### **HEAD -> main** 2021/11/23 mandic00@live.com
- cleanup
### **2.5.4** 2021/11/22 mandic00@live.com ### **2.5.4** 2021/11/22 mandic00@live.com
- prototype blazepose detector - prototype blazepose detector

10
TODO.md
View File

@ -31,13 +31,6 @@ Feature is automatically disabled in NodeJS without user impact
- Backend NodeJS missing kernel op `RotateWithOffset` - Backend NodeJS missing kernel op `RotateWithOffset`
<https://github.com/tensorflow/tfjs/issues/5473> <https://github.com/tensorflow/tfjs/issues/5473>
### Body Detection
MoveNet MultiPose model does not work with WASM backend due to missing F32 broadcast implementation
- Backend WASM missing F32 broadcat implementation
<https://github.com/tensorflow/tfjs/issues/5516>
<br><hr><br> <br><hr><br>
## Pending Release Notes ## Pending Release Notes
@ -61,3 +54,6 @@ Other:
- Improved VSCode out-of-the-box experience - Improved VSCode out-of-the-box experience
- Fix for optional `gear`, `ssrnet`, `mobilefacenet` modules - Fix for optional `gear`, `ssrnet`, `mobilefacenet` modules
- Fix for Firefox WebGPU compatibility issue - Fix for Firefox WebGPU compatibility issue
- Fix face detect box scale and rotation
- Fix body interpolation
- Updated `blazepose` implementation

View File

@ -5099,10 +5099,8 @@ async function getBoxes(inputImage, config3) {
b.landmarks = tfjs_esm_exports.reshape(b.squeeze, [keypointsCount, -1]); b.landmarks = tfjs_esm_exports.reshape(b.squeeze, [keypointsCount, -1]);
const points = await b.bbox.data(); const points = await b.bbox.data();
boxes.push({ boxes.push({
box: { startPoint: [points[0], points[1]],
startPoint: [points[0], points[1]], endPoint: [points[2], points[3]],
endPoint: [points[2], points[3]]
},
landmarks: await b.landmarks.array(), landmarks: await b.landmarks.array(),
confidence confidence
}); });
@ -5988,14 +5986,9 @@ async function predict10(input, config3) {
lastTime10 = now(); lastTime10 = now();
boxCache = []; boxCache = [];
for (const possible of possibleBoxes.boxes) { for (const possible of possibleBoxes.boxes) {
const box4 = { const boxScaled = scaleBoxCoordinates(possible, possibleBoxes.scaleFactor);
startPoint: possible.box.startPoint, const detectedWidth = (boxScaled.endPoint[0] - boxScaled.startPoint[0]) / (input.shape[2] || 1e3);
endPoint: possible.box.endPoint, const calcFactor = (((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6) / (detectedWidth + 0.75) / 1.34;
landmarks: possible.landmarks,
confidence: possible.confidence
};
const boxScaled = scaleBoxCoordinates(box4, possibleBoxes.scaleFactor);
const calcFactor = (((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6) * 1400 / (boxScaled.endPoint[0] - boxScaled.startPoint[0] + 1400);
const boxEnlarged = enlargeBox(boxScaled, calcFactor); const boxEnlarged = enlargeBox(boxScaled, calcFactor);
const boxSquared = squarifyBox(boxEnlarged); const boxSquared = squarifyBox(boxEnlarged);
boxCache.push(boxSquared); boxCache.push(boxSquared);
@ -12341,20 +12334,20 @@ function calc2(newResult, config3) {
bufferedResult.body = JSON.parse(JSON.stringify(newResult.body)); bufferedResult.body = JSON.parse(JSON.stringify(newResult.body));
} else { } else {
for (let i = 0; i < newResult.body.length; i++) { for (let i = 0; i < newResult.body.length; i++) {
const box4 = newResult.body[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + b) / bufferedFactor); const box4 = newResult.body[i].box.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor);
const boxRaw = newResult.body[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + b) / 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((keypoint, j) => ({ const keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({
score: keypoint.score, score: newKpt.score,
part: keypoint.part, part: newKpt.part,
position: [ position: [
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].position[0] + keypoint.position[0]) / bufferedFactor : keypoint.position[0], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[0] || 0) + (newKpt.position[0] || 0)) / bufferedFactor : newKpt.position[0],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].position[1] + keypoint.position[1]) / bufferedFactor : keypoint.position[1], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[1] || 0) + (newKpt.position[1] || 0)) / bufferedFactor : newKpt.position[1],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[2] || 0) + (keypoint.position[2] || 0)) / bufferedFactor : keypoint.position[2] bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[2] || 0) + (newKpt.position[2] || 0)) / bufferedFactor : newKpt.position[2]
], ],
positionRaw: [ positionRaw: [
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].positionRaw[0] + keypoint.positionRaw[0]) / bufferedFactor : keypoint.position[0], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[0] || 0) + (newKpt.positionRaw[0] || 0)) / bufferedFactor : newKpt.position[0],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].positionRaw[1] + keypoint.positionRaw[1]) / bufferedFactor : keypoint.position[1], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[1] || 0) + (newKpt.positionRaw[1] || 0)) / bufferedFactor : newKpt.position[1],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[2] || 0) + (keypoint.positionRaw[2] || 0)) / bufferedFactor : keypoint.position[1] bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[2] || 0) + (newKpt.positionRaw[2] || 0)) / bufferedFactor : newKpt.position[2]
] ]
})); }));
const annotations2 = {}; const annotations2 = {};
@ -12370,7 +12363,7 @@ function calc2(newResult, config3) {
for (let j = 0; j < indexes.length - 1; j++) { for (let j = 0; j < indexes.length - 1; j++) {
const pt0 = keypoints.find((kp) => kp.part === indexes[j]); const pt0 = keypoints.find((kp) => kp.part === indexes[j]);
const pt1 = keypoints.find((kp) => kp.part === indexes[j + 1]); const pt1 = keypoints.find((kp) => kp.part === indexes[j + 1]);
if (pt0 && pt1 && pt0.score > (config3.body.minConfidence || 0) && pt1.score > (config3.body.minConfidence || 0)) if (pt0 && pt1)
pt.push([pt0.position, pt1.position]); pt.push([pt0.position, pt1.position]);
} }
annotations2[name] = pt; annotations2[name] = pt;

File diff suppressed because one or more lines are too long

218
dist/human.esm.js vendored
View File

@ -2277,7 +2277,7 @@ var require_tfjs_backend_wasm_threaded_simd = __commonJS({
readyPromiseReject = reject; readyPromiseReject = reject;
}); });
var beforeListeners; var beforeListeners;
if (process && process.listeners) { if (typeof process !== "undefined" && process.listeners) {
beforeListeners = { uncaughtException: process.listeners("uncaughtException"), unhandledRejection: process.listeners("unhandledRejection") }; beforeListeners = { uncaughtException: process.listeners("uncaughtException"), unhandledRejection: process.listeners("unhandledRejection") };
} }
var moduleOverrides = {}; var moduleOverrides = {};
@ -2913,9 +2913,9 @@ var require_tfjs_backend_wasm_threaded_simd = __commonJS({
instantiateAsync().catch(readyPromiseReject); instantiateAsync().catch(readyPromiseReject);
return {}; return {};
} }
var ASM_CONSTS = { 10072: function() { var ASM_CONSTS = { 10128: function() {
throw "Canceled!"; throw "Canceled!";
}, 10090: function($0, $1) { }, 10146: function($0, $1) {
setTimeout(function() { setTimeout(function() {
__emscripten_do_dispatch_to_thread($0, $1); __emscripten_do_dispatch_to_thread($0, $1);
}, 0); }, 0);
@ -4426,8 +4426,8 @@ var require_tfjs_backend_wasm_threaded_simd = __commonJS({
var _memalign = Module["_memalign"] = function() { var _memalign = Module["_memalign"] = function() {
return (_memalign = Module["_memalign"] = Module["asm"]["Cb"]).apply(null, arguments); return (_memalign = Module["_memalign"] = Module["asm"]["Cb"]).apply(null, arguments);
}; };
var __emscripten_allow_main_runtime_queued_calls = Module["__emscripten_allow_main_runtime_queued_calls"] = 10064; var __emscripten_allow_main_runtime_queued_calls = Module["__emscripten_allow_main_runtime_queued_calls"] = 10120;
var __emscripten_main_thread_futex = Module["__emscripten_main_thread_futex"] = 10268; var __emscripten_main_thread_futex = Module["__emscripten_main_thread_futex"] = 10332;
Module["cwrap"] = cwrap; Module["cwrap"] = cwrap;
Module["PThread"] = PThread; Module["PThread"] = PThread;
Module["PThread"] = PThread; Module["PThread"] = PThread;
@ -4529,19 +4529,26 @@ var require_tfjs_backend_wasm_threaded_simd = __commonJS({
return !beforeListeners.unhandledRejection.indexOf(listener) > -1; return !beforeListeners.unhandledRejection.indexOf(listener) > -1;
}) }; }) };
} }
var actualModule = WasmBackendModule || WasmBackendModuleThreadedSimd3; var actualModule;
var tmpDispose = actualModule["_dispose"]; if (typeof WasmBackendModule !== "undefined") {
actualModule["_dispose"] = function() { actualModule = WasmBackendModule;
tmpDispose(); } else if (typeof WasmBackendModuleThreadedSimd3 !== "undefined") {
if (listenersAdded) { actualModule = WasmBackendModuleThreadedSimd3;
} else {
throw new Error("Could not find wasm module in post.js");
}
if (listenersAdded) {
var tmpDispose = actualModule["_dispose"];
actualModule["_dispose"] = function() {
tmpDispose();
listenersAdded.uncaughtException.forEach(function(listener) { listenersAdded.uncaughtException.forEach(function(listener) {
process.removeListener("uncaughtException", listener); process.removeListener("uncaughtException", listener);
}); });
listenersAdded.unhandledRejection.forEach(function(listener) { listenersAdded.unhandledRejection.forEach(function(listener) {
process.removeListener("unhandledRejection", listener); process.removeListener("unhandledRejection", listener);
}); });
} };
}; }
return WasmBackendModuleThreadedSimd3.ready; return WasmBackendModuleThreadedSimd3.ready;
}; };
}(); }();
@ -4570,7 +4577,7 @@ var require_tfjs_backend_wasm = __commonJS({
readyPromiseReject = reject; readyPromiseReject = reject;
}); });
var beforeListeners; var beforeListeners;
if (process && process.listeners) { if (typeof process !== "undefined" && process.listeners) {
beforeListeners = { uncaughtException: process.listeners("uncaughtException"), unhandledRejection: process.listeners("unhandledRejection") }; beforeListeners = { uncaughtException: process.listeners("uncaughtException"), unhandledRejection: process.listeners("unhandledRejection") };
} }
var moduleOverrides = {}; var moduleOverrides = {};
@ -5537,19 +5544,26 @@ var require_tfjs_backend_wasm = __commonJS({
return !beforeListeners.unhandledRejection.indexOf(listener) > -1; return !beforeListeners.unhandledRejection.indexOf(listener) > -1;
}) }; }) };
} }
var actualModule = WasmBackendModule3 || WasmBackendModuleThreadedSimd; var actualModule;
var tmpDispose = actualModule["_dispose"]; if (typeof WasmBackendModule3 !== "undefined") {
actualModule["_dispose"] = function() { actualModule = WasmBackendModule3;
tmpDispose(); } else if (typeof WasmBackendModuleThreadedSimd !== "undefined") {
if (listenersAdded) { actualModule = WasmBackendModuleThreadedSimd;
} else {
throw new Error("Could not find wasm module in post.js");
}
if (listenersAdded) {
var tmpDispose = actualModule["_dispose"];
actualModule["_dispose"] = function() {
tmpDispose();
listenersAdded.uncaughtException.forEach(function(listener) { listenersAdded.uncaughtException.forEach(function(listener) {
process.removeListener("uncaughtException", listener); process.removeListener("uncaughtException", listener);
}); });
listenersAdded.unhandledRejection.forEach(function(listener) { listenersAdded.unhandledRejection.forEach(function(listener) {
process.removeListener("unhandledRejection", listener); process.removeListener("unhandledRejection", listener);
}); });
} };
}; }
return WasmBackendModule3.ready; return WasmBackendModule3.ready;
}; };
}(); }();
@ -62604,6 +62618,7 @@ var clipByValueConfig2 = {
}; };
var ConcatProgram2 = class { var ConcatProgram2 = class {
constructor(shapes) { constructor(shapes) {
this.uniforms = "";
this.workPerThread = 4; this.workPerThread = 4;
this.workGroupSize = [64, 1, 1]; this.workGroupSize = [64, 1, 1];
this.size = true; this.size = true;
@ -62611,25 +62626,22 @@ var ConcatProgram2 = class {
this.variableNames = shapes.map((_, i) => `T${i}`); this.variableNames = shapes.map((_, i) => `T${i}`);
this.dispatchLayout = flatDispatchLayout(this.outputShape); this.dispatchLayout = flatDispatchLayout(this.outputShape);
this.dispatch = computeDispatch(this.dispatchLayout, this.outputShape, this.workGroupSize, [this.workPerThread, 1, 1]); this.dispatch = computeDispatch(this.dispatchLayout, this.outputShape, this.workGroupSize, [this.workPerThread, 1, 1]);
this.shapes = shapes; this.offsetLength = shapes.length - 1;
this.shaderKey = `concat${shapes}`; for (let i = 0; i < this.offsetLength; i++) {
this.uniforms += `offset${i} : i32;`;
}
this.shaderKey = "concat";
} }
getUserCode() { getUserCode() {
const offsets = new Array(this.shapes.length - 1);
const snippets = []; const snippets = [];
if (offsets.length > 0) { if (this.offsetLength > 0) {
offsets[0] = this.shapes[0][1]; snippets.push(`if (yC < uniforms.offset0){ setOutput(coords.x, coords.y, getT0(yR, yC)); }`);
for (let i = 1; i < offsets.length; i++) { for (let i = 1; i < this.offsetLength; i++) {
offsets[i] = offsets[i - 1] + this.shapes[i][1]; snippets.push(`elseif (yC < uniforms.offset${[i]}){ setOutput(coords.x, coords.y, getT${i}(yR, yC - uniforms.offset${i - 1})); }`);
} }
snippets.push(`if (yC < ${offsets[0]}){ setOutput(coords.x, coords.y, getT0(yR, yC)); }`); const lastIndex = this.offsetLength;
for (let i = 1; i < offsets.length; i++) { const lastShiftIndex = this.offsetLength - 1;
const shift = offsets[i - 1]; snippets.push(`else { setOutput(coords.x, coords.y, getT${lastIndex}(yR, yC - uniforms.offset${lastShiftIndex})); }`);
snippets.push(`elseif (yC < ${offsets[i]}){ setOutput(coords.x, coords.y, getT${i}(yR, yC - ${shift})); }`);
}
const lastIndex = offsets.length;
const lastShift = offsets[offsets.length - 1];
snippets.push(`else { setOutput(coords.x, coords.y, getT${lastIndex}(yR, yC - ${lastShift})); }`);
} else { } else {
snippets.push(`setOutput(coords.x, coords.y, getT0(yR, yC));`); snippets.push(`setOutput(coords.x, coords.y, getT0(yR, yC));`);
} }
@ -62697,8 +62709,19 @@ function concatImpl3(inputs, axis, backend22) {
return outInfo; return outInfo;
} }
const { tensors2D, outShape } = computeTensors2D2(inputs, axis, backend22); const { tensors2D, outShape } = computeTensors2D2(inputs, axis, backend22);
const program = new ConcatProgram2(tensors2D.map((t) => t.shape)); const shapes = tensors2D.map((t) => t.shape);
const res = backend22.runWebGPUProgram(program, tensors2D, tensors2D[0].dtype); const program = new ConcatProgram2(shapes);
const uniformData = [];
const offsets = new Array(shapes.length - 1);
if (offsets.length > 0) {
offsets[0] = shapes[0][1];
uniformData.push({ type: "int32", data: [offsets[0]] });
for (let i = 1; i < offsets.length; i++) {
offsets[i] = offsets[i - 1] + shapes[i][1];
uniformData.push({ type: "int32", data: [offsets[i]] });
}
}
const res = backend22.runWebGPUProgram(program, tensors2D, tensors2D[0].dtype, uniformData);
tensors2D.forEach((r) => backend22.disposeData(r.dataId)); tensors2D.forEach((r) => backend22.disposeData(r.dataId));
const reshapedResult = reshape5({ inputs: { x: res }, backend: backend22, attrs: { shape: outShape } }); const reshapedResult = reshape5({ inputs: { x: res }, backend: backend22, attrs: { shape: outShape } });
backend22.disposeData(res.dataId); backend22.disposeData(res.dataId);
@ -65251,20 +65274,17 @@ var relu6Config3 = {
kernelFunc: relu64 kernelFunc: relu64
}; };
var ResizeBilinearProgram2 = class { var ResizeBilinearProgram2 = class {
constructor(inputShape, newHeight, newWidth, alignCorners, halfPixelCenters) { constructor(inputShape, newHeight, newWidth) {
this.variableNames = ["x"]; this.variableNames = ["x"];
this.uniforms = "adjustHeightWidth : vec2<f32>; halfPixelCenters : f32;";
this.workGroupSize = [64, 1, 1]; this.workGroupSize = [64, 1, 1];
this.size = true; this.size = true;
this.outputShape = [inputShape[0], newHeight, newWidth, inputShape[3]]; this.outputShape = [inputShape[0], newHeight, newWidth, inputShape[3]];
this.dispatchLayout = flatDispatchLayout(this.outputShape); this.dispatchLayout = flatDispatchLayout(this.outputShape);
this.dispatch = computeDispatch(this.dispatchLayout, this.outputShape, this.workGroupSize); this.dispatch = computeDispatch(this.dispatchLayout, this.outputShape, this.workGroupSize);
this.alignCorners = alignCorners; this.shaderKey = `resizeBilinear`;
this.halfPixelCenters = halfPixelCenters;
this.shaderKey = `resizeBilinear_${alignCorners}_${halfPixelCenters}_${this.outputShape[1] > 1}_${this.outputShape[2] > 1}`;
} }
getUserCode() { getUserCode() {
const adjustHeight = this.alignCorners && this.outputShape[1] > 1;
const adjustWidth = this.alignCorners && this.outputShape[2] > 1;
const userCode = ` const userCode = `
${getMainHeaderAndGlobalIndexString()} ${getMainHeaderAndGlobalIndexString()}
if (index < uniforms.size) { if (index < uniforms.size) {
@ -65274,18 +65294,20 @@ var ResizeBilinearProgram2 = class {
let rc = coords.yz; let rc = coords.yz;
let effectiveInSize = vec2<f32>( let effectiveInSize = vec2<f32>(
${adjustHeight ? `f32(uniforms.xShape.y) - 1.0` : `f32(uniforms.xShape.y)`}, f32(uniforms.xShape.y) - uniforms.adjustHeightWidth[0],
${adjustWidth ? `f32(uniforms.xShape.z) - 1.0` : `f32(uniforms.xShape.z)`}); f32(uniforms.xShape.z) - uniforms.adjustHeightWidth[1]);
let effectiveOutSize = vec2<f32>( let effectiveOutSize = vec2<f32>(
${adjustHeight ? `f32(uniforms.outShape.y) - 1.0` : `f32(uniforms.outShape.y)`}, f32(uniforms.outShape.y) - uniforms.adjustHeightWidth[0],
${adjustWidth ? `f32(uniforms.outShape.z) - 1.0` : `f32(uniforms.outShape.z)`}); f32(uniforms.outShape.z) - uniforms.adjustHeightWidth[1]);
let effectiveInputOverOutputRatioRC = let effectiveInputOverOutputRatioRC =
effectiveInSize / effectiveOutSize; effectiveInSize / effectiveOutSize;
// Fractional source index // Fractional source index
let sourceFracIndexRC = ${this.halfPixelCenters ? "(vec2<f32>(rc) + vec2<f32>(0.5)) * effectiveInputOverOutputRatioRC - vec2<f32>(0.5)" : "vec2<f32>(rc) * effectiveInputOverOutputRatioRC"}; let sourceFracIndexRC =
(vec2<f32>(rc) + vec2<f32>(uniforms.halfPixelCenters)) *
effectiveInputOverOutputRatioRC - vec2<f32>(uniforms.halfPixelCenters);
// Compute the four integer indices. // Compute the four integer indices.
let sourceFloorRC = vec2<i32>(sourceFracIndexRC); let sourceFloorRC = vec2<i32>(sourceFracIndexRC);
@ -65315,8 +65337,15 @@ function resizeBilinear4(args) {
const { images } = inputs; const { images } = inputs;
const { alignCorners, size: size2, halfPixelCenters } = attrs; const { alignCorners, size: size2, halfPixelCenters } = attrs;
const [newHeight, newWidth] = size2; const [newHeight, newWidth] = size2;
const program = new ResizeBilinearProgram2(images.shape, newHeight, newWidth, alignCorners, halfPixelCenters); const adjustHeight = alignCorners && newHeight > 1 ? 1 : 0;
return backend22.runWebGPUProgram(program, [images], "float32"); const adjustWidth = alignCorners && newWidth > 1 ? 1 : 0;
const halfPixelCentersValue = halfPixelCenters ? 0.5 : 0;
const uniformData = [
{ type: "float32", data: [adjustHeight, adjustWidth] },
{ type: "float32", data: [halfPixelCentersValue] }
];
const program = new ResizeBilinearProgram2(images.shape, newHeight, newWidth);
return backend22.runWebGPUProgram(program, [images], "float32", uniformData);
} }
var resizeBilinearConfig3 = { var resizeBilinearConfig3 = {
kernelName: ResizeBilinear, kernelName: ResizeBilinear,
@ -65324,27 +65353,24 @@ var resizeBilinearConfig3 = {
kernelFunc: resizeBilinear4 kernelFunc: resizeBilinear4
}; };
var ResizeNearestNeighborProgram2 = class { var ResizeNearestNeighborProgram2 = class {
constructor(inputShape, newHeight, newWidth, alignCorners, halfPixelCenters) { constructor(inputShape, newHeight, newWidth, halfPixelCenters) {
this.variableNames = ["x"]; this.variableNames = ["x"];
this.uniforms = "adjustHeightWidth : vec2<f32>; roundBase : f32;";
this.workGroupSize = [64, 1, 1]; this.workGroupSize = [64, 1, 1];
this.size = true; this.size = true;
this.outputShape = [inputShape[0], newHeight, newWidth, inputShape[3]]; this.outputShape = [inputShape[0], newHeight, newWidth, inputShape[3]];
this.dispatchLayout = flatDispatchLayout(this.outputShape); this.dispatchLayout = flatDispatchLayout(this.outputShape);
this.dispatch = computeDispatch(this.dispatchLayout, this.outputShape, this.workGroupSize); this.dispatch = computeDispatch(this.dispatchLayout, this.outputShape, this.workGroupSize);
this.alignCorners = alignCorners;
this.halfPixelCenters = halfPixelCenters; this.halfPixelCenters = halfPixelCenters;
this.shaderKey = `resizeNearest_${alignCorners}_${this.outputShape[1] > 1}_${this.outputShape[2] > 1}_${halfPixelCenters}`; this.shaderKey = `resizeNearest_${halfPixelCenters}`;
} }
getUserCode() { getUserCode() {
const roundBase = this.alignCorners ? "0.5" : "0.0";
let sourceFracIndexRC; let sourceFracIndexRC;
if (this.halfPixelCenters) { if (this.halfPixelCenters) {
sourceFracIndexRC = `max((vec2<f32>(rc) + vec2<f32>(0.5)) * effectiveInputOverOutputRatioRC, vec2<f32>(0.0))`; sourceFracIndexRC = `max((vec2<f32>(rc) + vec2<f32>(0.5)) * effectiveInputOverOutputRatioRC, vec2<f32>(0.0))`;
} else { } else {
sourceFracIndexRC = `vec2<f32>(rc) * effectiveInputOverOutputRatioRC`; sourceFracIndexRC = `vec2<f32>(rc) * effectiveInputOverOutputRatioRC`;
} }
const adjustHeight = this.alignCorners && this.outputShape[1] > 1;
const adjustWidth = this.alignCorners && this.outputShape[2] > 1;
const userCode = ` const userCode = `
${getMainHeaderAndGlobalIndexString()} ${getMainHeaderAndGlobalIndexString()}
if (index < uniforms.size) { if (index < uniforms.size) {
@ -65354,12 +65380,12 @@ var ResizeNearestNeighborProgram2 = class {
let rc = coords.yz; let rc = coords.yz;
let effectiveInSize = vec2<f32>( let effectiveInSize = vec2<f32>(
${adjustHeight ? `f32(uniforms.xShape.y) - 1.0` : `f32(uniforms.xShape.y)`}, f32(uniforms.xShape.y) - uniforms.adjustHeightWidth[0],
${adjustWidth ? `f32(uniforms.xShape.z) - 1.0` : `f32(uniforms.xShape.z)`}); f32(uniforms.xShape.z) - uniforms.adjustHeightWidth[1]);
let effectiveOutSize = vec2<f32>( let effectiveOutSize = vec2<f32>(
${adjustHeight ? `f32(uniforms.outShape.y) - 1.0` : `f32(uniforms.outShape.y)`}, f32(uniforms.outShape.y) - uniforms.adjustHeightWidth[0],
${adjustWidth ? `f32(uniforms.outShape.z) - 1.0` : `f32(uniforms.outShape.z)`}); f32(uniforms.outShape.z) - uniforms.adjustHeightWidth[1]);
let effectiveInputOverOutputRatioRC = let effectiveInputOverOutputRatioRC =
effectiveInSize / effectiveOutSize; effectiveInSize / effectiveOutSize;
@ -65370,7 +65396,7 @@ var ResizeNearestNeighborProgram2 = class {
// Compute the coordinators of nearest neighbor point. // Compute the coordinators of nearest neighbor point.
let inputShapeRC = vec2<f32>(f32(uniforms.xShape.y), f32(uniforms.xShape.z)); let inputShapeRC = vec2<f32>(f32(uniforms.xShape.y), f32(uniforms.xShape.z));
let sourceNearestRC = vec2<i32>( let sourceNearestRC = vec2<i32>(
min(inputShapeRC - 1.0, floor(sourceFracIndexRC + ${roundBase}))); min(inputShapeRC - 1.0, floor(sourceFracIndexRC + uniforms.roundBase)));
let newValue = getX(b, sourceNearestRC.x, sourceNearestRC.y, d); let newValue = getX(b, sourceNearestRC.x, sourceNearestRC.y, d);
setOutputFlat(index, newValue); setOutputFlat(index, newValue);
@ -65385,8 +65411,15 @@ function resizeNearestNeighbor4(args) {
const { images } = inputs; const { images } = inputs;
const { alignCorners, halfPixelCenters, size: size2 } = attrs; const { alignCorners, halfPixelCenters, size: size2 } = attrs;
const [newHeight, newWidth] = size2; const [newHeight, newWidth] = size2;
const program = new ResizeNearestNeighborProgram2(images.shape, newHeight, newWidth, alignCorners, halfPixelCenters); const adjustHeight = alignCorners && newHeight > 1 ? 1 : 0;
return backend22.runWebGPUProgram(program, [images], images.dtype); const adjustWidth = alignCorners && newWidth > 1 ? 1 : 0;
const roundBase = alignCorners ? 0.5 : 0;
const uniformData = [
{ type: "float32", data: [adjustHeight, adjustWidth] },
{ type: "float32", data: [roundBase] }
];
const program = new ResizeNearestNeighborProgram2(images.shape, newHeight, newWidth, halfPixelCenters);
return backend22.runWebGPUProgram(program, [images], images.dtype, uniformData);
} }
var resizeNearestNeighborConfig3 = { var resizeNearestNeighborConfig3 = {
kernelName: ResizeNearestNeighbor, kernelName: ResizeNearestNeighbor,
@ -67639,20 +67672,8 @@ function createBinaryKernelConfig(kernelName, supportsFullBroadcast17, dtype) {
const bShapeBytes = new Uint8Array(new Int32Array(b.shape).buffer); const bShapeBytes = new Uint8Array(new Int32Array(b.shape).buffer);
const outId = backend22.dataIdMap.get(out.dataId).id; const outId = backend22.dataIdMap.get(out.dataId).id;
const kernelFunc4 = () => wasmFunc9(aId, aShapeBytes, a.shape.length, bId, bShapeBytes, b.shape.length, CppDType[a.dtype], outId); const kernelFunc4 = () => wasmFunc9(aId, aShapeBytes, a.shape.length, bId, bShapeBytes, b.shape.length, CppDType[a.dtype], outId);
if (supportsFullBroadcast17 && a.dtype === "float32") { kernelFunc4();
kernelFunc4(); return out;
return out;
}
const aBroadcastDims = backend_util_exports.getBroadcastDims(a.shape, newShape);
const bBroadcastDims = backend_util_exports.getBroadcastDims(b.shape, newShape);
const loopsOverAllOfA = aBroadcastDims.every((v, i) => v === i);
const loopsOverAllOfB = bBroadcastDims.every((v, i) => v === i);
if (loopsOverAllOfA && loopsOverAllOfB) {
kernelFunc4();
return out;
} else {
throw new Error(`Broadcasting along outer dims is not yet supported for ${a.dtype} ${kernelName}.`);
}
} }
return { kernelName, backendName: "wasm", setupFunc: setupFunc3, kernelFunc: kernelFunc3 }; return { kernelName, backendName: "wasm", setupFunc: setupFunc3, kernelFunc: kernelFunc3 };
} }
@ -70651,7 +70672,7 @@ registerBackend("wasm", async () => {
const { wasm } = await init(); const { wasm } = await init();
return new BackendWasm(wasm); return new BackendWasm(wasm);
}, WASM_PRIORITY); }, WASM_PRIORITY);
var externalVersion = "3.11.0-20211121"; var externalVersion = "3.11.0-20211123";
var version8 = { var version8 = {
tfjs: externalVersion, tfjs: externalVersion,
"tfjs-core": externalVersion, "tfjs-core": externalVersion,
@ -75506,10 +75527,8 @@ async function getBoxes(inputImage, config3) {
b.landmarks = reshape(b.squeeze, [keypointsCount, -1]); b.landmarks = reshape(b.squeeze, [keypointsCount, -1]);
const points = await b.bbox.data(); const points = await b.bbox.data();
boxes.push({ boxes.push({
box: { startPoint: [points[0], points[1]],
startPoint: [points[0], points[1]], endPoint: [points[2], points[3]],
endPoint: [points[2], points[3]]
},
landmarks: await b.landmarks.array(), landmarks: await b.landmarks.array(),
confidence confidence
}); });
@ -76395,14 +76414,9 @@ async function predict10(input2, config3) {
lastTime10 = now(); lastTime10 = now();
boxCache = []; boxCache = [];
for (const possible of possibleBoxes.boxes) { for (const possible of possibleBoxes.boxes) {
const box4 = { const boxScaled = scaleBoxCoordinates(possible, possibleBoxes.scaleFactor);
startPoint: possible.box.startPoint, const detectedWidth = (boxScaled.endPoint[0] - boxScaled.startPoint[0]) / (input2.shape[2] || 1e3);
endPoint: possible.box.endPoint, const calcFactor = (((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6) / (detectedWidth + 0.75) / 1.34;
landmarks: possible.landmarks,
confidence: possible.confidence
};
const boxScaled = scaleBoxCoordinates(box4, possibleBoxes.scaleFactor);
const calcFactor = (((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6) * 1400 / (boxScaled.endPoint[0] - boxScaled.startPoint[0] + 1400);
const boxEnlarged = enlargeBox(boxScaled, calcFactor); const boxEnlarged = enlargeBox(boxScaled, calcFactor);
const boxSquared = squarifyBox(boxEnlarged); const boxSquared = squarifyBox(boxEnlarged);
boxCache.push(boxSquared); boxCache.push(boxSquared);
@ -82748,20 +82762,20 @@ function calc2(newResult, config3) {
bufferedResult.body = JSON.parse(JSON.stringify(newResult.body)); bufferedResult.body = JSON.parse(JSON.stringify(newResult.body));
} else { } else {
for (let i = 0; i < newResult.body.length; i++) { for (let i = 0; i < newResult.body.length; i++) {
const box4 = newResult.body[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + b) / bufferedFactor); const box4 = newResult.body[i].box.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor);
const boxRaw = newResult.body[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + b) / 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((keypoint, j) => ({ const keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({
score: keypoint.score, score: newKpt.score,
part: keypoint.part, part: newKpt.part,
position: [ position: [
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].position[0] + keypoint.position[0]) / bufferedFactor : keypoint.position[0], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[0] || 0) + (newKpt.position[0] || 0)) / bufferedFactor : newKpt.position[0],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].position[1] + keypoint.position[1]) / bufferedFactor : keypoint.position[1], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[1] || 0) + (newKpt.position[1] || 0)) / bufferedFactor : newKpt.position[1],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[2] || 0) + (keypoint.position[2] || 0)) / bufferedFactor : keypoint.position[2] bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[2] || 0) + (newKpt.position[2] || 0)) / bufferedFactor : newKpt.position[2]
], ],
positionRaw: [ positionRaw: [
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].positionRaw[0] + keypoint.positionRaw[0]) / bufferedFactor : keypoint.position[0], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[0] || 0) + (newKpt.positionRaw[0] || 0)) / bufferedFactor : newKpt.position[0],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].positionRaw[1] + keypoint.positionRaw[1]) / bufferedFactor : keypoint.position[1], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[1] || 0) + (newKpt.positionRaw[1] || 0)) / bufferedFactor : newKpt.position[1],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[2] || 0) + (keypoint.positionRaw[2] || 0)) / bufferedFactor : keypoint.position[1] bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[2] || 0) + (newKpt.positionRaw[2] || 0)) / bufferedFactor : newKpt.position[2]
] ]
})); }));
const annotations2 = {}; const annotations2 = {};
@ -82777,7 +82791,7 @@ function calc2(newResult, config3) {
for (let j = 0; j < indexes.length - 1; j++) { for (let j = 0; j < indexes.length - 1; j++) {
const pt0 = keypoints.find((kp) => kp.part === indexes[j]); const pt0 = keypoints.find((kp) => kp.part === indexes[j]);
const pt1 = keypoints.find((kp) => kp.part === indexes[j + 1]); const pt1 = keypoints.find((kp) => kp.part === indexes[j + 1]);
if (pt0 && pt1 && pt0.score > (config3.body.minConfidence || 0) && pt1.score > (config3.body.minConfidence || 0)) if (pt0 && pt1)
pt.push([pt0.position, pt1.position]); pt.push([pt0.position, pt1.position]);
} }
annotations2[name] = pt; annotations2[name] = pt;

File diff suppressed because one or more lines are too long

446
dist/human.js vendored

File diff suppressed because one or more lines are too long

View File

@ -5135,10 +5135,8 @@ async function getBoxes(inputImage, config3) {
b.landmarks = tf10.reshape(b.squeeze, [keypointsCount, -1]); b.landmarks = tf10.reshape(b.squeeze, [keypointsCount, -1]);
const points = await b.bbox.data(); const points = await b.bbox.data();
boxes.push({ boxes.push({
box: { startPoint: [points[0], points[1]],
startPoint: [points[0], points[1]], endPoint: [points[2], points[3]],
endPoint: [points[2], points[3]]
},
landmarks: await b.landmarks.array(), landmarks: await b.landmarks.array(),
confidence confidence
}); });
@ -6040,14 +6038,9 @@ async function predict10(input, config3) {
lastTime10 = now(); lastTime10 = now();
boxCache = []; boxCache = [];
for (const possible of possibleBoxes.boxes) { for (const possible of possibleBoxes.boxes) {
const box4 = { const boxScaled = scaleBoxCoordinates(possible, possibleBoxes.scaleFactor);
startPoint: possible.box.startPoint, const detectedWidth = (boxScaled.endPoint[0] - boxScaled.startPoint[0]) / (input.shape[2] || 1e3);
endPoint: possible.box.endPoint, const calcFactor = (((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6) / (detectedWidth + 0.75) / 1.34;
landmarks: possible.landmarks,
confidence: possible.confidence
};
const boxScaled = scaleBoxCoordinates(box4, possibleBoxes.scaleFactor);
const calcFactor = (((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6) * 1400 / (boxScaled.endPoint[0] - boxScaled.startPoint[0] + 1400);
const boxEnlarged = enlargeBox(boxScaled, calcFactor); const boxEnlarged = enlargeBox(boxScaled, calcFactor);
const boxSquared = squarifyBox(boxEnlarged); const boxSquared = squarifyBox(boxEnlarged);
boxCache.push(boxSquared); boxCache.push(boxSquared);
@ -12418,20 +12411,20 @@ function calc2(newResult, config3) {
bufferedResult.body = JSON.parse(JSON.stringify(newResult.body)); bufferedResult.body = JSON.parse(JSON.stringify(newResult.body));
} else { } else {
for (let i = 0; i < newResult.body.length; i++) { for (let i = 0; i < newResult.body.length; i++) {
const box4 = newResult.body[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + b) / bufferedFactor); const box4 = newResult.body[i].box.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor);
const boxRaw = newResult.body[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + b) / 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((keypoint, j) => ({ const keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({
score: keypoint.score, score: newKpt.score,
part: keypoint.part, part: newKpt.part,
position: [ position: [
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].position[0] + keypoint.position[0]) / bufferedFactor : keypoint.position[0], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[0] || 0) + (newKpt.position[0] || 0)) / bufferedFactor : newKpt.position[0],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].position[1] + keypoint.position[1]) / bufferedFactor : keypoint.position[1], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[1] || 0) + (newKpt.position[1] || 0)) / bufferedFactor : newKpt.position[1],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[2] || 0) + (keypoint.position[2] || 0)) / bufferedFactor : keypoint.position[2] bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[2] || 0) + (newKpt.position[2] || 0)) / bufferedFactor : newKpt.position[2]
], ],
positionRaw: [ positionRaw: [
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].positionRaw[0] + keypoint.positionRaw[0]) / bufferedFactor : keypoint.position[0], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[0] || 0) + (newKpt.positionRaw[0] || 0)) / bufferedFactor : newKpt.position[0],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].positionRaw[1] + keypoint.positionRaw[1]) / bufferedFactor : keypoint.position[1], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[1] || 0) + (newKpt.positionRaw[1] || 0)) / bufferedFactor : newKpt.position[1],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[2] || 0) + (keypoint.positionRaw[2] || 0)) / bufferedFactor : keypoint.position[1] bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[2] || 0) + (newKpt.positionRaw[2] || 0)) / bufferedFactor : newKpt.position[2]
] ]
})); }));
const annotations2 = {}; const annotations2 = {};
@ -12447,7 +12440,7 @@ function calc2(newResult, config3) {
for (let j = 0; j < indexes.length - 1; j++) { for (let j = 0; j < indexes.length - 1; j++) {
const pt0 = keypoints.find((kp) => kp.part === indexes[j]); const pt0 = keypoints.find((kp) => kp.part === indexes[j]);
const pt1 = keypoints.find((kp) => kp.part === indexes[j + 1]); const pt1 = keypoints.find((kp) => kp.part === indexes[j + 1]);
if (pt0 && pt1 && pt0.score > (config3.body.minConfidence || 0) && pt1.score > (config3.body.minConfidence || 0)) if (pt0 && pt1)
pt.push([pt0.position, pt1.position]); pt.push([pt0.position, pt1.position]);
} }
annotations2[name] = pt; annotations2[name] = pt;

View File

@ -5136,10 +5136,8 @@ async function getBoxes(inputImage, config3) {
b.landmarks = tf10.reshape(b.squeeze, [keypointsCount, -1]); b.landmarks = tf10.reshape(b.squeeze, [keypointsCount, -1]);
const points = await b.bbox.data(); const points = await b.bbox.data();
boxes.push({ boxes.push({
box: { startPoint: [points[0], points[1]],
startPoint: [points[0], points[1]], endPoint: [points[2], points[3]],
endPoint: [points[2], points[3]]
},
landmarks: await b.landmarks.array(), landmarks: await b.landmarks.array(),
confidence confidence
}); });
@ -6041,14 +6039,9 @@ async function predict10(input, config3) {
lastTime10 = now(); lastTime10 = now();
boxCache = []; boxCache = [];
for (const possible of possibleBoxes.boxes) { for (const possible of possibleBoxes.boxes) {
const box4 = { const boxScaled = scaleBoxCoordinates(possible, possibleBoxes.scaleFactor);
startPoint: possible.box.startPoint, const detectedWidth = (boxScaled.endPoint[0] - boxScaled.startPoint[0]) / (input.shape[2] || 1e3);
endPoint: possible.box.endPoint, const calcFactor = (((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6) / (detectedWidth + 0.75) / 1.34;
landmarks: possible.landmarks,
confidence: possible.confidence
};
const boxScaled = scaleBoxCoordinates(box4, possibleBoxes.scaleFactor);
const calcFactor = (((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6) * 1400 / (boxScaled.endPoint[0] - boxScaled.startPoint[0] + 1400);
const boxEnlarged = enlargeBox(boxScaled, calcFactor); const boxEnlarged = enlargeBox(boxScaled, calcFactor);
const boxSquared = squarifyBox(boxEnlarged); const boxSquared = squarifyBox(boxEnlarged);
boxCache.push(boxSquared); boxCache.push(boxSquared);
@ -12419,20 +12412,20 @@ function calc2(newResult, config3) {
bufferedResult.body = JSON.parse(JSON.stringify(newResult.body)); bufferedResult.body = JSON.parse(JSON.stringify(newResult.body));
} else { } else {
for (let i = 0; i < newResult.body.length; i++) { for (let i = 0; i < newResult.body.length; i++) {
const box4 = newResult.body[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + b) / bufferedFactor); const box4 = newResult.body[i].box.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor);
const boxRaw = newResult.body[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + b) / 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((keypoint, j) => ({ const keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({
score: keypoint.score, score: newKpt.score,
part: keypoint.part, part: newKpt.part,
position: [ position: [
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].position[0] + keypoint.position[0]) / bufferedFactor : keypoint.position[0], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[0] || 0) + (newKpt.position[0] || 0)) / bufferedFactor : newKpt.position[0],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].position[1] + keypoint.position[1]) / bufferedFactor : keypoint.position[1], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[1] || 0) + (newKpt.position[1] || 0)) / bufferedFactor : newKpt.position[1],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[2] || 0) + (keypoint.position[2] || 0)) / bufferedFactor : keypoint.position[2] bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[2] || 0) + (newKpt.position[2] || 0)) / bufferedFactor : newKpt.position[2]
], ],
positionRaw: [ positionRaw: [
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].positionRaw[0] + keypoint.positionRaw[0]) / bufferedFactor : keypoint.position[0], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[0] || 0) + (newKpt.positionRaw[0] || 0)) / bufferedFactor : newKpt.position[0],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].positionRaw[1] + keypoint.positionRaw[1]) / bufferedFactor : keypoint.position[1], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[1] || 0) + (newKpt.positionRaw[1] || 0)) / bufferedFactor : newKpt.position[1],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[2] || 0) + (keypoint.positionRaw[2] || 0)) / bufferedFactor : keypoint.position[1] bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[2] || 0) + (newKpt.positionRaw[2] || 0)) / bufferedFactor : newKpt.position[2]
] ]
})); }));
const annotations2 = {}; const annotations2 = {};
@ -12448,7 +12441,7 @@ function calc2(newResult, config3) {
for (let j = 0; j < indexes.length - 1; j++) { for (let j = 0; j < indexes.length - 1; j++) {
const pt0 = keypoints.find((kp) => kp.part === indexes[j]); const pt0 = keypoints.find((kp) => kp.part === indexes[j]);
const pt1 = keypoints.find((kp) => kp.part === indexes[j + 1]); const pt1 = keypoints.find((kp) => kp.part === indexes[j + 1]);
if (pt0 && pt1 && pt0.score > (config3.body.minConfidence || 0) && pt1.score > (config3.body.minConfidence || 0)) if (pt0 && pt1)
pt.push([pt0.position, pt1.position]); pt.push([pt0.position, pt1.position]);
} }
annotations2[name] = pt; annotations2[name] = pt;

41
dist/human.node.js vendored
View File

@ -5135,10 +5135,8 @@ async function getBoxes(inputImage, config3) {
b.landmarks = tf10.reshape(b.squeeze, [keypointsCount, -1]); b.landmarks = tf10.reshape(b.squeeze, [keypointsCount, -1]);
const points = await b.bbox.data(); const points = await b.bbox.data();
boxes.push({ boxes.push({
box: { startPoint: [points[0], points[1]],
startPoint: [points[0], points[1]], endPoint: [points[2], points[3]],
endPoint: [points[2], points[3]]
},
landmarks: await b.landmarks.array(), landmarks: await b.landmarks.array(),
confidence confidence
}); });
@ -6040,14 +6038,9 @@ async function predict10(input, config3) {
lastTime10 = now(); lastTime10 = now();
boxCache = []; boxCache = [];
for (const possible of possibleBoxes.boxes) { for (const possible of possibleBoxes.boxes) {
const box4 = { const boxScaled = scaleBoxCoordinates(possible, possibleBoxes.scaleFactor);
startPoint: possible.box.startPoint, const detectedWidth = (boxScaled.endPoint[0] - boxScaled.startPoint[0]) / (input.shape[2] || 1e3);
endPoint: possible.box.endPoint, const calcFactor = (((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6) / (detectedWidth + 0.75) / 1.34;
landmarks: possible.landmarks,
confidence: possible.confidence
};
const boxScaled = scaleBoxCoordinates(box4, possibleBoxes.scaleFactor);
const calcFactor = (((_c = config3.face.detector) == null ? void 0 : _c.cropFactor) || 1.6) * 1400 / (boxScaled.endPoint[0] - boxScaled.startPoint[0] + 1400);
const boxEnlarged = enlargeBox(boxScaled, calcFactor); const boxEnlarged = enlargeBox(boxScaled, calcFactor);
const boxSquared = squarifyBox(boxEnlarged); const boxSquared = squarifyBox(boxEnlarged);
boxCache.push(boxSquared); boxCache.push(boxSquared);
@ -12418,20 +12411,20 @@ function calc2(newResult, config3) {
bufferedResult.body = JSON.parse(JSON.stringify(newResult.body)); bufferedResult.body = JSON.parse(JSON.stringify(newResult.body));
} else { } else {
for (let i = 0; i < newResult.body.length; i++) { for (let i = 0; i < newResult.body.length; i++) {
const box4 = newResult.body[i].box.map((b, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + b) / bufferedFactor); const box4 = newResult.body[i].box.map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor);
const boxRaw = newResult.body[i].boxRaw.map((b, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + b) / 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((keypoint, j) => ({ const keypoints = newResult.body[i].keypoints.map((newKpt, j) => ({
score: keypoint.score, score: newKpt.score,
part: keypoint.part, part: newKpt.part,
position: [ position: [
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].position[0] + keypoint.position[0]) / bufferedFactor : keypoint.position[0], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[0] || 0) + (newKpt.position[0] || 0)) / bufferedFactor : newKpt.position[0],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].position[1] + keypoint.position[1]) / bufferedFactor : keypoint.position[1], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[1] || 0) + (newKpt.position[1] || 0)) / bufferedFactor : newKpt.position[1],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[2] || 0) + (keypoint.position[2] || 0)) / bufferedFactor : keypoint.position[2] bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[2] || 0) + (newKpt.position[2] || 0)) / bufferedFactor : newKpt.position[2]
], ],
positionRaw: [ positionRaw: [
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].positionRaw[0] + keypoint.positionRaw[0]) / bufferedFactor : keypoint.position[0], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[0] || 0) + (newKpt.positionRaw[0] || 0)) / bufferedFactor : newKpt.position[0],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].positionRaw[1] + keypoint.positionRaw[1]) / bufferedFactor : keypoint.position[1], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[1] || 0) + (newKpt.positionRaw[1] || 0)) / bufferedFactor : newKpt.position[1],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[2] || 0) + (keypoint.positionRaw[2] || 0)) / bufferedFactor : keypoint.position[1] bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[2] || 0) + (newKpt.positionRaw[2] || 0)) / bufferedFactor : newKpt.position[2]
] ]
})); }));
const annotations2 = {}; const annotations2 = {};
@ -12447,7 +12440,7 @@ function calc2(newResult, config3) {
for (let j = 0; j < indexes.length - 1; j++) { for (let j = 0; j < indexes.length - 1; j++) {
const pt0 = keypoints.find((kp) => kp.part === indexes[j]); const pt0 = keypoints.find((kp) => kp.part === indexes[j]);
const pt1 = keypoints.find((kp) => kp.part === indexes[j + 1]); const pt1 = keypoints.find((kp) => kp.part === indexes[j + 1]);
if (pt0 && pt1 && pt0.score > (config3.body.minConfidence || 0) && pt1.score > (config3.body.minConfidence || 0)) if (pt0 && pt1)
pt.push([pt0.position, pt1.position]); pt.push([pt0.position, pt1.position]);
} }
annotations2[name] = pt; annotations2[name] = pt;

179
dist/tfjs.esm.js vendored
View File

@ -4,7 +4,7 @@
author: <https://github.com/vladmandic>' author: <https://github.com/vladmandic>'
*/ */
// node_modules/.pnpm/github.com+vladmandic+tfjs@14eabb5e489a9403713f08c3595e04728a838e82/node_modules/@vladmandic/tfjs/dist/tfjs.esm.js // node_modules/.pnpm/github.com+vladmandic+tfjs@23eb80be7626f37f74b23351f804509a335f2a55/node_modules/@vladmandic/tfjs/dist/tfjs.esm.js
var __create = Object.create; var __create = Object.create;
var __defProp = Object.defineProperty; var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@ -1572,7 +1572,7 @@ var require_tfjs_backend_wasm_threaded_simd = __commonJS({
readyPromiseReject = reject; readyPromiseReject = reject;
}); });
var beforeListeners; var beforeListeners;
if (process && process.listeners) { if (typeof process !== "undefined" && process.listeners) {
beforeListeners = { uncaughtException: process.listeners("uncaughtException"), unhandledRejection: process.listeners("unhandledRejection") }; beforeListeners = { uncaughtException: process.listeners("uncaughtException"), unhandledRejection: process.listeners("unhandledRejection") };
} }
var moduleOverrides = {}; var moduleOverrides = {};
@ -2208,9 +2208,9 @@ var require_tfjs_backend_wasm_threaded_simd = __commonJS({
instantiateAsync().catch(readyPromiseReject); instantiateAsync().catch(readyPromiseReject);
return {}; return {};
} }
var ASM_CONSTS = { 10072: function() { var ASM_CONSTS = { 10128: function() {
throw "Canceled!"; throw "Canceled!";
}, 10090: function($0, $1) { }, 10146: function($0, $1) {
setTimeout(function() { setTimeout(function() {
__emscripten_do_dispatch_to_thread($0, $1); __emscripten_do_dispatch_to_thread($0, $1);
}, 0); }, 0);
@ -3721,8 +3721,8 @@ var require_tfjs_backend_wasm_threaded_simd = __commonJS({
var _memalign = Module["_memalign"] = function() { var _memalign = Module["_memalign"] = function() {
return (_memalign = Module["_memalign"] = Module["asm"]["Cb"]).apply(null, arguments); return (_memalign = Module["_memalign"] = Module["asm"]["Cb"]).apply(null, arguments);
}; };
var __emscripten_allow_main_runtime_queued_calls = Module["__emscripten_allow_main_runtime_queued_calls"] = 10064; var __emscripten_allow_main_runtime_queued_calls = Module["__emscripten_allow_main_runtime_queued_calls"] = 10120;
var __emscripten_main_thread_futex = Module["__emscripten_main_thread_futex"] = 10268; var __emscripten_main_thread_futex = Module["__emscripten_main_thread_futex"] = 10332;
Module["cwrap"] = cwrap; Module["cwrap"] = cwrap;
Module["PThread"] = PThread; Module["PThread"] = PThread;
Module["PThread"] = PThread; Module["PThread"] = PThread;
@ -3824,19 +3824,26 @@ var require_tfjs_backend_wasm_threaded_simd = __commonJS({
return !beforeListeners.unhandledRejection.indexOf(listener) > -1; return !beforeListeners.unhandledRejection.indexOf(listener) > -1;
}) }; }) };
} }
var actualModule = WasmBackendModule || WasmBackendModuleThreadedSimd3; var actualModule;
var tmpDispose = actualModule["_dispose"]; if (typeof WasmBackendModule !== "undefined") {
actualModule["_dispose"] = function() { actualModule = WasmBackendModule;
tmpDispose(); } else if (typeof WasmBackendModuleThreadedSimd3 !== "undefined") {
if (listenersAdded) { actualModule = WasmBackendModuleThreadedSimd3;
} else {
throw new Error("Could not find wasm module in post.js");
}
if (listenersAdded) {
var tmpDispose = actualModule["_dispose"];
actualModule["_dispose"] = function() {
tmpDispose();
listenersAdded.uncaughtException.forEach(function(listener) { listenersAdded.uncaughtException.forEach(function(listener) {
process.removeListener("uncaughtException", listener); process.removeListener("uncaughtException", listener);
}); });
listenersAdded.unhandledRejection.forEach(function(listener) { listenersAdded.unhandledRejection.forEach(function(listener) {
process.removeListener("unhandledRejection", listener); process.removeListener("unhandledRejection", listener);
}); });
} };
}; }
return WasmBackendModuleThreadedSimd3.ready; return WasmBackendModuleThreadedSimd3.ready;
}; };
}(); }();
@ -3865,7 +3872,7 @@ var require_tfjs_backend_wasm = __commonJS({
readyPromiseReject = reject; readyPromiseReject = reject;
}); });
var beforeListeners; var beforeListeners;
if (process && process.listeners) { if (typeof process !== "undefined" && process.listeners) {
beforeListeners = { uncaughtException: process.listeners("uncaughtException"), unhandledRejection: process.listeners("unhandledRejection") }; beforeListeners = { uncaughtException: process.listeners("uncaughtException"), unhandledRejection: process.listeners("unhandledRejection") };
} }
var moduleOverrides = {}; var moduleOverrides = {};
@ -4832,19 +4839,26 @@ var require_tfjs_backend_wasm = __commonJS({
return !beforeListeners.unhandledRejection.indexOf(listener) > -1; return !beforeListeners.unhandledRejection.indexOf(listener) > -1;
}) }; }) };
} }
var actualModule = WasmBackendModule3 || WasmBackendModuleThreadedSimd; var actualModule;
var tmpDispose = actualModule["_dispose"]; if (typeof WasmBackendModule3 !== "undefined") {
actualModule["_dispose"] = function() { actualModule = WasmBackendModule3;
tmpDispose(); } else if (typeof WasmBackendModuleThreadedSimd !== "undefined") {
if (listenersAdded) { actualModule = WasmBackendModuleThreadedSimd;
} else {
throw new Error("Could not find wasm module in post.js");
}
if (listenersAdded) {
var tmpDispose = actualModule["_dispose"];
actualModule["_dispose"] = function() {
tmpDispose();
listenersAdded.uncaughtException.forEach(function(listener) { listenersAdded.uncaughtException.forEach(function(listener) {
process.removeListener("uncaughtException", listener); process.removeListener("uncaughtException", listener);
}); });
listenersAdded.unhandledRejection.forEach(function(listener) { listenersAdded.unhandledRejection.forEach(function(listener) {
process.removeListener("unhandledRejection", listener); process.removeListener("unhandledRejection", listener);
}); });
} };
}; }
return WasmBackendModule3.ready; return WasmBackendModule3.ready;
}; };
}(); }();
@ -61899,6 +61913,7 @@ var clipByValueConfig2 = {
}; };
var ConcatProgram2 = class { var ConcatProgram2 = class {
constructor(shapes) { constructor(shapes) {
this.uniforms = "";
this.workPerThread = 4; this.workPerThread = 4;
this.workGroupSize = [64, 1, 1]; this.workGroupSize = [64, 1, 1];
this.size = true; this.size = true;
@ -61906,25 +61921,22 @@ var ConcatProgram2 = class {
this.variableNames = shapes.map((_, i) => `T${i}`); this.variableNames = shapes.map((_, i) => `T${i}`);
this.dispatchLayout = flatDispatchLayout(this.outputShape); this.dispatchLayout = flatDispatchLayout(this.outputShape);
this.dispatch = computeDispatch(this.dispatchLayout, this.outputShape, this.workGroupSize, [this.workPerThread, 1, 1]); this.dispatch = computeDispatch(this.dispatchLayout, this.outputShape, this.workGroupSize, [this.workPerThread, 1, 1]);
this.shapes = shapes; this.offsetLength = shapes.length - 1;
this.shaderKey = `concat${shapes}`; for (let i = 0; i < this.offsetLength; i++) {
this.uniforms += `offset${i} : i32;`;
}
this.shaderKey = "concat";
} }
getUserCode() { getUserCode() {
const offsets = new Array(this.shapes.length - 1);
const snippets = []; const snippets = [];
if (offsets.length > 0) { if (this.offsetLength > 0) {
offsets[0] = this.shapes[0][1]; snippets.push(`if (yC < uniforms.offset0){ setOutput(coords.x, coords.y, getT0(yR, yC)); }`);
for (let i = 1; i < offsets.length; i++) { for (let i = 1; i < this.offsetLength; i++) {
offsets[i] = offsets[i - 1] + this.shapes[i][1]; snippets.push(`elseif (yC < uniforms.offset${[i]}){ setOutput(coords.x, coords.y, getT${i}(yR, yC - uniforms.offset${i - 1})); }`);
} }
snippets.push(`if (yC < ${offsets[0]}){ setOutput(coords.x, coords.y, getT0(yR, yC)); }`); const lastIndex = this.offsetLength;
for (let i = 1; i < offsets.length; i++) { const lastShiftIndex = this.offsetLength - 1;
const shift = offsets[i - 1]; snippets.push(`else { setOutput(coords.x, coords.y, getT${lastIndex}(yR, yC - uniforms.offset${lastShiftIndex})); }`);
snippets.push(`elseif (yC < ${offsets[i]}){ setOutput(coords.x, coords.y, getT${i}(yR, yC - ${shift})); }`);
}
const lastIndex = offsets.length;
const lastShift = offsets[offsets.length - 1];
snippets.push(`else { setOutput(coords.x, coords.y, getT${lastIndex}(yR, yC - ${lastShift})); }`);
} else { } else {
snippets.push(`setOutput(coords.x, coords.y, getT0(yR, yC));`); snippets.push(`setOutput(coords.x, coords.y, getT0(yR, yC));`);
} }
@ -61992,8 +62004,19 @@ function concatImpl3(inputs, axis, backend2) {
return outInfo; return outInfo;
} }
const { tensors2D, outShape } = computeTensors2D2(inputs, axis, backend2); const { tensors2D, outShape } = computeTensors2D2(inputs, axis, backend2);
const program = new ConcatProgram2(tensors2D.map((t) => t.shape)); const shapes = tensors2D.map((t) => t.shape);
const res = backend2.runWebGPUProgram(program, tensors2D, tensors2D[0].dtype); const program = new ConcatProgram2(shapes);
const uniformData = [];
const offsets = new Array(shapes.length - 1);
if (offsets.length > 0) {
offsets[0] = shapes[0][1];
uniformData.push({ type: "int32", data: [offsets[0]] });
for (let i = 1; i < offsets.length; i++) {
offsets[i] = offsets[i - 1] + shapes[i][1];
uniformData.push({ type: "int32", data: [offsets[i]] });
}
}
const res = backend2.runWebGPUProgram(program, tensors2D, tensors2D[0].dtype, uniformData);
tensors2D.forEach((r) => backend2.disposeData(r.dataId)); tensors2D.forEach((r) => backend2.disposeData(r.dataId));
const reshapedResult = reshape5({ inputs: { x: res }, backend: backend2, attrs: { shape: outShape } }); const reshapedResult = reshape5({ inputs: { x: res }, backend: backend2, attrs: { shape: outShape } });
backend2.disposeData(res.dataId); backend2.disposeData(res.dataId);
@ -64546,20 +64569,17 @@ var relu6Config3 = {
kernelFunc: relu64 kernelFunc: relu64
}; };
var ResizeBilinearProgram2 = class { var ResizeBilinearProgram2 = class {
constructor(inputShape, newHeight, newWidth, alignCorners, halfPixelCenters) { constructor(inputShape, newHeight, newWidth) {
this.variableNames = ["x"]; this.variableNames = ["x"];
this.uniforms = "adjustHeightWidth : vec2<f32>; halfPixelCenters : f32;";
this.workGroupSize = [64, 1, 1]; this.workGroupSize = [64, 1, 1];
this.size = true; this.size = true;
this.outputShape = [inputShape[0], newHeight, newWidth, inputShape[3]]; this.outputShape = [inputShape[0], newHeight, newWidth, inputShape[3]];
this.dispatchLayout = flatDispatchLayout(this.outputShape); this.dispatchLayout = flatDispatchLayout(this.outputShape);
this.dispatch = computeDispatch(this.dispatchLayout, this.outputShape, this.workGroupSize); this.dispatch = computeDispatch(this.dispatchLayout, this.outputShape, this.workGroupSize);
this.alignCorners = alignCorners; this.shaderKey = `resizeBilinear`;
this.halfPixelCenters = halfPixelCenters;
this.shaderKey = `resizeBilinear_${alignCorners}_${halfPixelCenters}_${this.outputShape[1] > 1}_${this.outputShape[2] > 1}`;
} }
getUserCode() { getUserCode() {
const adjustHeight = this.alignCorners && this.outputShape[1] > 1;
const adjustWidth = this.alignCorners && this.outputShape[2] > 1;
const userCode = ` const userCode = `
${getMainHeaderAndGlobalIndexString()} ${getMainHeaderAndGlobalIndexString()}
if (index < uniforms.size) { if (index < uniforms.size) {
@ -64569,18 +64589,20 @@ var ResizeBilinearProgram2 = class {
let rc = coords.yz; let rc = coords.yz;
let effectiveInSize = vec2<f32>( let effectiveInSize = vec2<f32>(
${adjustHeight ? `f32(uniforms.xShape.y) - 1.0` : `f32(uniforms.xShape.y)`}, f32(uniforms.xShape.y) - uniforms.adjustHeightWidth[0],
${adjustWidth ? `f32(uniforms.xShape.z) - 1.0` : `f32(uniforms.xShape.z)`}); f32(uniforms.xShape.z) - uniforms.adjustHeightWidth[1]);
let effectiveOutSize = vec2<f32>( let effectiveOutSize = vec2<f32>(
${adjustHeight ? `f32(uniforms.outShape.y) - 1.0` : `f32(uniforms.outShape.y)`}, f32(uniforms.outShape.y) - uniforms.adjustHeightWidth[0],
${adjustWidth ? `f32(uniforms.outShape.z) - 1.0` : `f32(uniforms.outShape.z)`}); f32(uniforms.outShape.z) - uniforms.adjustHeightWidth[1]);
let effectiveInputOverOutputRatioRC = let effectiveInputOverOutputRatioRC =
effectiveInSize / effectiveOutSize; effectiveInSize / effectiveOutSize;
// Fractional source index // Fractional source index
let sourceFracIndexRC = ${this.halfPixelCenters ? "(vec2<f32>(rc) + vec2<f32>(0.5)) * effectiveInputOverOutputRatioRC - vec2<f32>(0.5)" : "vec2<f32>(rc) * effectiveInputOverOutputRatioRC"}; let sourceFracIndexRC =
(vec2<f32>(rc) + vec2<f32>(uniforms.halfPixelCenters)) *
effectiveInputOverOutputRatioRC - vec2<f32>(uniforms.halfPixelCenters);
// Compute the four integer indices. // Compute the four integer indices.
let sourceFloorRC = vec2<i32>(sourceFracIndexRC); let sourceFloorRC = vec2<i32>(sourceFracIndexRC);
@ -64610,8 +64632,15 @@ function resizeBilinear4(args) {
const { images } = inputs; const { images } = inputs;
const { alignCorners, size, halfPixelCenters } = attrs; const { alignCorners, size, halfPixelCenters } = attrs;
const [newHeight, newWidth] = size; const [newHeight, newWidth] = size;
const program = new ResizeBilinearProgram2(images.shape, newHeight, newWidth, alignCorners, halfPixelCenters); const adjustHeight = alignCorners && newHeight > 1 ? 1 : 0;
return backend2.runWebGPUProgram(program, [images], "float32"); const adjustWidth = alignCorners && newWidth > 1 ? 1 : 0;
const halfPixelCentersValue = halfPixelCenters ? 0.5 : 0;
const uniformData = [
{ type: "float32", data: [adjustHeight, adjustWidth] },
{ type: "float32", data: [halfPixelCentersValue] }
];
const program = new ResizeBilinearProgram2(images.shape, newHeight, newWidth);
return backend2.runWebGPUProgram(program, [images], "float32", uniformData);
} }
var resizeBilinearConfig3 = { var resizeBilinearConfig3 = {
kernelName: ResizeBilinear, kernelName: ResizeBilinear,
@ -64619,27 +64648,24 @@ var resizeBilinearConfig3 = {
kernelFunc: resizeBilinear4 kernelFunc: resizeBilinear4
}; };
var ResizeNearestNeighborProgram2 = class { var ResizeNearestNeighborProgram2 = class {
constructor(inputShape, newHeight, newWidth, alignCorners, halfPixelCenters) { constructor(inputShape, newHeight, newWidth, halfPixelCenters) {
this.variableNames = ["x"]; this.variableNames = ["x"];
this.uniforms = "adjustHeightWidth : vec2<f32>; roundBase : f32;";
this.workGroupSize = [64, 1, 1]; this.workGroupSize = [64, 1, 1];
this.size = true; this.size = true;
this.outputShape = [inputShape[0], newHeight, newWidth, inputShape[3]]; this.outputShape = [inputShape[0], newHeight, newWidth, inputShape[3]];
this.dispatchLayout = flatDispatchLayout(this.outputShape); this.dispatchLayout = flatDispatchLayout(this.outputShape);
this.dispatch = computeDispatch(this.dispatchLayout, this.outputShape, this.workGroupSize); this.dispatch = computeDispatch(this.dispatchLayout, this.outputShape, this.workGroupSize);
this.alignCorners = alignCorners;
this.halfPixelCenters = halfPixelCenters; this.halfPixelCenters = halfPixelCenters;
this.shaderKey = `resizeNearest_${alignCorners}_${this.outputShape[1] > 1}_${this.outputShape[2] > 1}_${halfPixelCenters}`; this.shaderKey = `resizeNearest_${halfPixelCenters}`;
} }
getUserCode() { getUserCode() {
const roundBase = this.alignCorners ? "0.5" : "0.0";
let sourceFracIndexRC; let sourceFracIndexRC;
if (this.halfPixelCenters) { if (this.halfPixelCenters) {
sourceFracIndexRC = `max((vec2<f32>(rc) + vec2<f32>(0.5)) * effectiveInputOverOutputRatioRC, vec2<f32>(0.0))`; sourceFracIndexRC = `max((vec2<f32>(rc) + vec2<f32>(0.5)) * effectiveInputOverOutputRatioRC, vec2<f32>(0.0))`;
} else { } else {
sourceFracIndexRC = `vec2<f32>(rc) * effectiveInputOverOutputRatioRC`; sourceFracIndexRC = `vec2<f32>(rc) * effectiveInputOverOutputRatioRC`;
} }
const adjustHeight = this.alignCorners && this.outputShape[1] > 1;
const adjustWidth = this.alignCorners && this.outputShape[2] > 1;
const userCode = ` const userCode = `
${getMainHeaderAndGlobalIndexString()} ${getMainHeaderAndGlobalIndexString()}
if (index < uniforms.size) { if (index < uniforms.size) {
@ -64649,12 +64675,12 @@ var ResizeNearestNeighborProgram2 = class {
let rc = coords.yz; let rc = coords.yz;
let effectiveInSize = vec2<f32>( let effectiveInSize = vec2<f32>(
${adjustHeight ? `f32(uniforms.xShape.y) - 1.0` : `f32(uniforms.xShape.y)`}, f32(uniforms.xShape.y) - uniforms.adjustHeightWidth[0],
${adjustWidth ? `f32(uniforms.xShape.z) - 1.0` : `f32(uniforms.xShape.z)`}); f32(uniforms.xShape.z) - uniforms.adjustHeightWidth[1]);
let effectiveOutSize = vec2<f32>( let effectiveOutSize = vec2<f32>(
${adjustHeight ? `f32(uniforms.outShape.y) - 1.0` : `f32(uniforms.outShape.y)`}, f32(uniforms.outShape.y) - uniforms.adjustHeightWidth[0],
${adjustWidth ? `f32(uniforms.outShape.z) - 1.0` : `f32(uniforms.outShape.z)`}); f32(uniforms.outShape.z) - uniforms.adjustHeightWidth[1]);
let effectiveInputOverOutputRatioRC = let effectiveInputOverOutputRatioRC =
effectiveInSize / effectiveOutSize; effectiveInSize / effectiveOutSize;
@ -64665,7 +64691,7 @@ var ResizeNearestNeighborProgram2 = class {
// Compute the coordinators of nearest neighbor point. // Compute the coordinators of nearest neighbor point.
let inputShapeRC = vec2<f32>(f32(uniforms.xShape.y), f32(uniforms.xShape.z)); let inputShapeRC = vec2<f32>(f32(uniforms.xShape.y), f32(uniforms.xShape.z));
let sourceNearestRC = vec2<i32>( let sourceNearestRC = vec2<i32>(
min(inputShapeRC - 1.0, floor(sourceFracIndexRC + ${roundBase}))); min(inputShapeRC - 1.0, floor(sourceFracIndexRC + uniforms.roundBase)));
let newValue = getX(b, sourceNearestRC.x, sourceNearestRC.y, d); let newValue = getX(b, sourceNearestRC.x, sourceNearestRC.y, d);
setOutputFlat(index, newValue); setOutputFlat(index, newValue);
@ -64680,8 +64706,15 @@ function resizeNearestNeighbor4(args) {
const { images } = inputs; const { images } = inputs;
const { alignCorners, halfPixelCenters, size } = attrs; const { alignCorners, halfPixelCenters, size } = attrs;
const [newHeight, newWidth] = size; const [newHeight, newWidth] = size;
const program = new ResizeNearestNeighborProgram2(images.shape, newHeight, newWidth, alignCorners, halfPixelCenters); const adjustHeight = alignCorners && newHeight > 1 ? 1 : 0;
return backend2.runWebGPUProgram(program, [images], images.dtype); const adjustWidth = alignCorners && newWidth > 1 ? 1 : 0;
const roundBase = alignCorners ? 0.5 : 0;
const uniformData = [
{ type: "float32", data: [adjustHeight, adjustWidth] },
{ type: "float32", data: [roundBase] }
];
const program = new ResizeNearestNeighborProgram2(images.shape, newHeight, newWidth, halfPixelCenters);
return backend2.runWebGPUProgram(program, [images], images.dtype, uniformData);
} }
var resizeNearestNeighborConfig3 = { var resizeNearestNeighborConfig3 = {
kernelName: ResizeNearestNeighbor, kernelName: ResizeNearestNeighbor,
@ -66934,20 +66967,8 @@ function createBinaryKernelConfig(kernelName, supportsFullBroadcast17, dtype) {
const bShapeBytes = new Uint8Array(new Int32Array(b.shape).buffer); const bShapeBytes = new Uint8Array(new Int32Array(b.shape).buffer);
const outId = backend2.dataIdMap.get(out.dataId).id; const outId = backend2.dataIdMap.get(out.dataId).id;
const kernelFunc4 = () => wasmFunc9(aId, aShapeBytes, a.shape.length, bId, bShapeBytes, b.shape.length, CppDType[a.dtype], outId); const kernelFunc4 = () => wasmFunc9(aId, aShapeBytes, a.shape.length, bId, bShapeBytes, b.shape.length, CppDType[a.dtype], outId);
if (supportsFullBroadcast17 && a.dtype === "float32") { kernelFunc4();
kernelFunc4(); return out;
return out;
}
const aBroadcastDims = backend_util_exports.getBroadcastDims(a.shape, newShape);
const bBroadcastDims = backend_util_exports.getBroadcastDims(b.shape, newShape);
const loopsOverAllOfA = aBroadcastDims.every((v, i) => v === i);
const loopsOverAllOfB = bBroadcastDims.every((v, i) => v === i);
if (loopsOverAllOfA && loopsOverAllOfB) {
kernelFunc4();
return out;
} else {
throw new Error(`Broadcasting along outer dims is not yet supported for ${a.dtype} ${kernelName}.`);
}
} }
return { kernelName, backendName: "wasm", setupFunc: setupFunc3, kernelFunc: kernelFunc3 }; return { kernelName, backendName: "wasm", setupFunc: setupFunc3, kernelFunc: kernelFunc3 };
} }
@ -69946,7 +69967,7 @@ registerBackend("wasm", async () => {
const { wasm } = await init(); const { wasm } = await init();
return new BackendWasm(wasm); return new BackendWasm(wasm);
}, WASM_PRIORITY); }, WASM_PRIORITY);
var externalVersion = "3.11.0-20211121"; var externalVersion = "3.11.0-20211123";
var version8 = { var version8 = {
tfjs: externalVersion, tfjs: externalVersion,
"tfjs-core": externalVersion, "tfjs-core": externalVersion,

View File

@ -48,9 +48,9 @@ export const connected: Record<string, string[]> = {
torso: ['leftShoulder', 'rightShoulder', 'rightHip', 'leftHip', 'leftShoulder', 'rightShoulder'], torso: ['leftShoulder', 'rightShoulder', 'rightHip', 'leftHip', 'leftShoulder', 'rightShoulder'],
leftArm: ['leftShoulder', 'leftElbow', 'leftWrist', 'leftPalm'], leftArm: ['leftShoulder', 'leftElbow', 'leftWrist', 'leftPalm'],
rightArm: ['rightShoulder', 'rightElbow', 'rightWrist', 'rightPalm'], rightArm: ['rightShoulder', 'rightElbow', 'rightWrist', 'rightPalm'],
// leftHand: ['leftHand', 'leftPalm', 'leftPinky', 'leftPalm', 'leftIndex', 'leftPalm', 'leftThumb'],
// rightHand: ['rightHand', 'rightPalm', 'rightPinky', 'rightPalm', 'rightIndex', 'rightPalm', 'rightThumb'],
leftEye: ['leftEyeInside', 'leftEye', 'leftEyeOutside'], leftEye: ['leftEyeInside', 'leftEye', 'leftEyeOutside'],
rightEye: ['rightEyeInside', 'rightEye', 'rightEyeOutside'], rightEye: ['rightEyeInside', 'rightEye', 'rightEyeOutside'],
mouth: ['leftMouth', 'rightMouth'], mouth: ['leftMouth', 'rightMouth'],
// leftHand: ['leftHand', 'leftPalm', 'leftPinky', 'leftPalm', 'leftIndex', 'leftPalm', 'leftThumb'],
// rightHand: ['rightHand', 'rightPalm', 'rightPinky', 'rightPalm', 'rightIndex', 'rightPalm', 'rightThumb'],
}; };

View File

@ -18,6 +18,8 @@ let anchors: Tensor | null = null;
let inputSize = 0; let inputSize = 0;
let inputSizeT: Tensor | null = null; let inputSizeT: Tensor | null = null;
type DetectBox = { startPoint: Point, endPoint: Point, landmarks: Array<Point>, confidence: number };
export const size = () => inputSize; export const size = () => inputSize;
export async function load(config: Config): Promise<GraphModel> { export async function load(config: Config): Promise<GraphModel> {
@ -75,7 +77,7 @@ export async function getBoxes(inputImage: Tensor, config: Config) {
t.scores = tf.squeeze(t.sigmoid); t.scores = tf.squeeze(t.sigmoid);
t.nms = await tf.image.nonMaxSuppressionAsync(t.boxes, t.scores, (config.face.detector?.maxDetected || 0), (config.face.detector?.iouThreshold || 0), (config.face.detector?.minConfidence || 0)); t.nms = await tf.image.nonMaxSuppressionAsync(t.boxes, t.scores, (config.face.detector?.maxDetected || 0), (config.face.detector?.iouThreshold || 0), (config.face.detector?.minConfidence || 0));
const nms = await t.nms.array() as number[]; const nms = await t.nms.array() as number[];
const boxes: Array<{ box: { startPoint: Point, endPoint: Point }, landmarks: Point[], confidence: number }> = []; const boxes: Array<DetectBox> = [];
const scores = await t.scores.data(); const scores = await t.scores.data();
for (let i = 0; i < nms.length; i++) { for (let i = 0; i < nms.length; i++) {
const confidence = scores[nms[i]]; const confidence = scores[nms[i]];
@ -87,10 +89,8 @@ export async function getBoxes(inputImage: Tensor, config: Config) {
b.landmarks = tf.reshape(b.squeeze, [keypointsCount, -1]); b.landmarks = tf.reshape(b.squeeze, [keypointsCount, -1]);
const points = await b.bbox.data(); const points = await b.bbox.data();
boxes.push({ boxes.push({
box: { startPoint: [points[0], points[1]] as Point,
startPoint: [points[0], points[1]] as Point, endPoint: [points[2], points[3]] as Point,
endPoint: [points[2], points[3]] as Point,
},
landmarks: (await b.landmarks.array()) as Point[], landmarks: (await b.landmarks.array()) as Point[],
confidence, confidence,
}); });

View File

@ -19,8 +19,8 @@ import type { GraphModel, Tensor } from '../tfjs/types';
import type { FaceResult, Point } from '../result'; import type { FaceResult, Point } from '../result';
import type { Config } from '../config'; import type { Config } from '../config';
type BoxCache = { startPoint: Point, endPoint: Point, landmarks: Array<Point>, confidence: number }; type DetectBox = { startPoint: Point, endPoint: Point, landmarks: Array<Point>, confidence: number };
let boxCache: Array<BoxCache> = []; let boxCache: Array<DetectBox> = [];
let model: GraphModel | null = null; let model: GraphModel | null = null;
let inputSize = 0; let inputSize = 0;
let skipped = Number.MAX_SAFE_INTEGER; let skipped = Number.MAX_SAFE_INTEGER;
@ -35,14 +35,9 @@ export async function predict(input: Tensor, config: Config): Promise<FaceResult
lastTime = now(); lastTime = now();
boxCache = []; // empty cache boxCache = []; // empty cache
for (const possible of possibleBoxes.boxes) { // extract data from detector for (const possible of possibleBoxes.boxes) { // extract data from detector
const box: BoxCache = { const boxScaled = util.scaleBoxCoordinates(possible, possibleBoxes.scaleFactor);
startPoint: possible.box.startPoint, const detectedWidth = (boxScaled.endPoint[0] - boxScaled.startPoint[0]) / (input.shape[2] || 1000);
endPoint: possible.box.endPoint, const calcFactor = (config.face.detector?.cropFactor || 1.6) / (detectedWidth + 0.75) / 1.34; // detected face box is not the same size as calculated face box and scale also depends on detected face size
landmarks: possible.landmarks,
confidence: possible.confidence,
};
const boxScaled = util.scaleBoxCoordinates(box, possibleBoxes.scaleFactor);
const calcFactor = (config.face.detector?.cropFactor || 1.6) * 1400 / (boxScaled.endPoint[0] - boxScaled.startPoint[0] + 1400); // detected face box is not the same size as calculated face box and scale also depends on detected face size
const boxEnlarged = util.enlargeBox(boxScaled, calcFactor); const boxEnlarged = util.enlargeBox(boxScaled, calcFactor);
const boxSquared = util.squarifyBox(boxEnlarged); const boxSquared = util.squarifyBox(boxEnlarged);
boxCache.push(boxSquared); boxCache.push(boxSquared);
@ -52,7 +47,7 @@ export async function predict(input: Tensor, config: Config): Promise<FaceResult
skipped++; skipped++;
} }
const faces: Array<FaceResult> = []; const faces: Array<FaceResult> = [];
const newCache: Array<BoxCache> = []; const newCache: Array<DetectBox> = [];
let id = 0; let id = 0;
for (let i = 0; i < boxCache.length; i++) { for (let i = 0; i < boxCache.length; i++) {
let box = boxCache[i]; let box = boxCache[i];

View File

@ -40,26 +40,26 @@ export function calc(newResult: Result, config: Config): Result {
} else { } else {
for (let i = 0; i < newResult.body.length; i++) { for (let i = 0; i < newResult.body.length; i++) {
const box = newResult.body[i].box // update box const box = newResult.body[i].box // update box
.map((b, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + b) / bufferedFactor) as Box; .map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].box[j] + newBoxCoord) / bufferedFactor) as Box;
const boxRaw = newResult.body[i].boxRaw // update boxRaw const boxRaw = newResult.body[i].boxRaw // update boxRaw
.map((b, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + b) / bufferedFactor) as Box; .map((newBoxCoord, j) => ((bufferedFactor - 1) * bufferedResult.body[i].boxRaw[j] + newBoxCoord) / bufferedFactor) as Box;
const keypoints = (newResult.body[i].keypoints // update keypoints const keypoints = (newResult.body[i].keypoints // update keypoints
.map((keypoint, j) => ({ .map((newKpt, j) => ({
score: keypoint.score, score: newKpt.score,
part: keypoint.part, part: newKpt.part,
position: [ position: [
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].position[0] + keypoint.position[0]) / bufferedFactor : keypoint.position[0], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[0] || 0) + (newKpt.position[0] || 0)) / bufferedFactor : newKpt.position[0],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].position[1] + keypoint.position[1]) / bufferedFactor : keypoint.position[1], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[1] || 0) + (newKpt.position[1] || 0)) / bufferedFactor : newKpt.position[1],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[2] || 0) + (keypoint.position[2] || 0)) / bufferedFactor : keypoint.position[2], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].position[2] || 0) + (newKpt.position[2] || 0)) / bufferedFactor : newKpt.position[2],
], ],
positionRaw: [ positionRaw: [
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].positionRaw[0] + keypoint.positionRaw[0]) / bufferedFactor : keypoint.position[0], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[0] || 0) + (newKpt.positionRaw[0] || 0)) / bufferedFactor : newKpt.position[0],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * bufferedResult.body[i].keypoints[j].positionRaw[1] + keypoint.positionRaw[1]) / bufferedFactor : keypoint.position[1], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[1] || 0) + (newKpt.positionRaw[1] || 0)) / bufferedFactor : newKpt.position[1],
bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[2] || 0) + (keypoint.positionRaw[2] || 0)) / bufferedFactor : keypoint.position[1], bufferedResult.body[i].keypoints[j] ? ((bufferedFactor - 1) * (bufferedResult.body[i].keypoints[j].positionRaw[2] || 0) + (newKpt.positionRaw[2] || 0)) / bufferedFactor : newKpt.position[2],
], ],
}))) as Array<{ score: number, part: string, position: [number, number, number?], positionRaw: [number, number, number?] }>; }))) as Array<{ score: number, part: string, position: [number, number, number?], positionRaw: [number, number, number?] }>;
const annotations: Record<string, Point[][]> = {};
const annotations: Record<string, Point[][]> = {}; // recreate annotations
let coords = { connected: {} }; let coords = { connected: {} };
if (config.body?.modelPath?.includes('efficientpose')) coords = efficientPoseCoords; if (config.body?.modelPath?.includes('efficientpose')) coords = efficientPoseCoords;
else if (config.body?.modelPath?.includes('blazepose')) coords = blazePoseCoords; else if (config.body?.modelPath?.includes('blazepose')) coords = blazePoseCoords;
@ -69,7 +69,8 @@ export function calc(newResult: Result, config: Config): Result {
for (let j = 0; j < indexes.length - 1; j++) { for (let j = 0; j < indexes.length - 1; j++) {
const pt0 = keypoints.find((kp) => kp.part === indexes[j]); const pt0 = keypoints.find((kp) => kp.part === indexes[j]);
const pt1 = keypoints.find((kp) => kp.part === indexes[j + 1]); const pt1 = keypoints.find((kp) => kp.part === indexes[j + 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 && 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; annotations[name] = pt;
} }

File diff suppressed because it is too large Load Diff

View File

@ -106,7 +106,9 @@ async function testAll() {
for (const test of tests) await runTest(test); for (const test of tests) await runTest(test);
log.info('all tests complete'); log.info('all tests complete');
log.info('failed:', { count: failedMessages.length, messages: failedMessages }); log.info('failed:', { count: failedMessages.length, messages: failedMessages });
log.info('status:', status); for (const [test, result] of Object.entries(status)) {
log.info('status:', { test, ...result });
}
} }
testAll(); testAll();

View File

@ -334,7 +334,7 @@ async function test(Human, inputConfig) {
res1 = human.similarity(desc1, desc1); res1 = human.similarity(desc1, desc1);
res2 = human.similarity(desc1, desc2); res2 = human.similarity(desc1, desc2);
res3 = human.similarity(desc1, desc3); res3 = human.similarity(desc1, desc3);
if (res1 < 1 || res2 < 0.50 || res3 < 0.50) log('error', 'failed: face similarity', { similarity: [res1, res2, res3], descriptors: [desc1?.length, desc2?.length, desc3?.length] }); if (res1 < 1 || res2 < 0.50 || res3 < 0.45 || res2 > 0.75 || res3 > 0.75) log('error', 'failed: face similarity', { similarity: [res1, res2, res3], descriptors: [desc1?.length, desc2?.length, desc3?.length] });
else log('state', 'passed: face similarity', { similarity: [res1, res2, res3], descriptors: [desc1?.length, desc2?.length, desc3?.length] }); else log('state', 'passed: face similarity', { similarity: [res1, res2, res3], descriptors: [desc1?.length, desc2?.length, desc3?.length] });
// test face matching // test face matching
@ -373,8 +373,8 @@ async function test(Human, inputConfig) {
if (!face || face?.box?.length !== 4 || face?.mesh?.length !== 478 || face?.embedding?.length !== 1024 || face?.rotation?.matrix?.length !== 9) { if (!face || face?.box?.length !== 4 || face?.mesh?.length !== 478 || face?.embedding?.length !== 1024 || face?.rotation?.matrix?.length !== 9) {
log('error', 'failed: sensitive face result mismatch', res?.face?.length, face?.box?.length, face?.mesh?.length, face?.embedding?.length, face?.rotation?.matrix?.length); log('error', 'failed: sensitive face result mismatch', res?.face?.length, face?.box?.length, face?.mesh?.length, face?.embedding?.length, face?.rotation?.matrix?.length);
} else log('state', 'passed: sensitive face result match'); } else log('state', 'passed: sensitive face result match');
if (!face || face?.emotion?.length < 3) log('error', 'failed: sensitive face emotion result mismatch', face?.emotion.length); if (!face || face?.emotion?.length < 1 || face.emotion[0].score < 0.55 || face.emotion[0].emotion !== 'neutral') log('error', 'failed: sensitive face emotion result mismatch', face?.emotion);
else log('state', 'passed: sensitive face emotion result', face?.emotion.length); else log('state', 'passed: sensitive face emotion result', face?.emotion);
// test sensitive details body // test sensitive details body
const body = res && res.body ? res.body[0] : null; const body = res && res.body ? res.body[0] : null;

File diff suppressed because it is too large Load Diff