unified build

pull/134/head
Vladimir Mandic 2021-06-05 12:59:11 -04:00
parent fdf60830e3
commit b6b1e63749
62 changed files with 209217 additions and 4757 deletions

View File

@ -9,7 +9,10 @@ Repository: **<git+https://github.com/vladmandic/human.git>**
## Changelog ## Changelog
### **HEAD -> main** 2021/06/04 mandic00@live.com ### **HEAD -> main** 2021/06/05 mandic00@live.com
### **origin/main** 2021/06/04 mandic00@live.com
- added experimental body segmentation module - added experimental body segmentation module
- add meet and selfie models - add meet and selfie models

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

69407
dist/human.esm.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

69413
dist/human.js vendored

File diff suppressed because one or more lines are too long

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

@ -71,7 +71,8 @@ var require_tfjs_esm = __commonJS({
return __reExport2(__markAsModule2(__defProp2(module22 != null ? __create2(__getProtoOf2(module22)) : {}, "default", module22 && module22.__esModule && "default" in module22 ? { get: () => module22.default, enumerable: true } : { value: module22, enumerable: true })), module22); return __reExport2(__markAsModule2(__defProp2(module22 != null ? __create2(__getProtoOf2(module22)) : {}, "default", module22 && module22.__esModule && "default" in module22 ? { get: () => module22.default, enumerable: true } : { value: module22, enumerable: true })), module22);
}; };
__markAsModule2(exports); __markAsModule2(exports);
__reExport2(exports, __toModule2(require("@tensorflow/tfjs-node-gpu"))); __reExport2(exports, __toModule2(require("@tensorflow/tfjs")));
__reExport2(exports, __toModule2(require("@tensorflow/tfjs-backend-wasm")));
} }
}); });
@ -340,16 +341,16 @@ function getBoxCenter(box6) {
box6.startPoint[1] + (box6.endPoint[1] - box6.startPoint[1]) / 2 box6.startPoint[1] + (box6.endPoint[1] - box6.startPoint[1]) / 2
]; ];
} }
function cutBoxFromImageAndResize(box6, image17, cropSize) { function cutBoxFromImageAndResize(box6, image18, cropSize) {
const h = image17.shape[1]; const h = image18.shape[1];
const w = image17.shape[2]; const w = image18.shape[2];
const boxes = [[ const boxes = [[
box6.startPoint[1] / h, box6.startPoint[1] / h,
box6.startPoint[0] / w, box6.startPoint[0] / w,
box6.endPoint[1] / h, box6.endPoint[1] / h,
box6.endPoint[0] / w box6.endPoint[0] / w
]]; ]];
return tf2.image.cropAndResize(image17, boxes, [0], cropSize); return tf2.image.cropAndResize(image18, boxes, [0], cropSize);
} }
function enlargeBox(box6, factor = 1.5) { function enlargeBox(box6, factor = 1.5) {
const center = getBoxCenter(box6); const center = getBoxCenter(box6);
@ -494,7 +495,7 @@ var BlazeFaceModel = class {
if (!inputImage || inputImage.isDisposedInternal || inputImage.shape.length !== 4 || inputImage.shape[1] < 1 || inputImage.shape[2] < 1) if (!inputImage || inputImage.isDisposedInternal || inputImage.shape.length !== 4 || inputImage.shape[1] < 1 || inputImage.shape[2] < 1)
return null; return null;
const [batch, boxes, scores] = tf3.tidy(() => { const [batch, boxes, scores] = tf3.tidy(() => {
const resizedImage = inputImage.resizeBilinear([this.inputSize, this.inputSize]); const resizedImage = tf3.image.resizeBilinear(inputImage, [this.inputSize, this.inputSize]);
const normalizedImage = resizedImage.div(127.5).sub(0.5); const normalizedImage = resizedImage.div(127.5).sub(0.5);
const res = this.model.execute(normalizedImage); const res = this.model.execute(normalizedImage);
let batchOut; let batchOut;
@ -505,7 +506,7 @@ var BlazeFaceModel = class {
const concat3 = tf3.concat([concat512, concat384], 1); const concat3 = tf3.concat([concat512, concat384], 1);
batchOut = concat3.squeeze(0); batchOut = concat3.squeeze(0);
} else { } else {
batchOut = res.squeeze(); batchOut = tf3.squeeze(res);
} }
const boxesOut = decodeBounds(batchOut, this.anchors, [this.inputSize, this.inputSize]); const boxesOut = decodeBounds(batchOut, this.anchors, [this.inputSize, this.inputSize]);
const logits = tf3.slice(batchOut, [0, 0], [-1, 1]); const logits = tf3.slice(batchOut, [0, 0], [-1, 1]);
@ -4174,7 +4175,7 @@ async function load3(config3) {
log("cached model:", model.modelUrl); log("cached model:", model.modelUrl);
return model; return model;
} }
async function predict2(image17, config3, idx, count2) { async function predict2(image18, config3, idx, count2) {
if (!model) if (!model)
return null; return null;
if (skipped < config3.face.emotion.skipFrames && config3.skipFrame && lastCount === count2 && last[idx] && last[idx].length > 0) { if (skipped < config3.face.emotion.skipFrames && config3.skipFrame && lastCount === count2 && last[idx] && last[idx].length > 0) {
@ -4183,7 +4184,7 @@ async function predict2(image17, config3, idx, count2) {
} }
skipped = 0; skipped = 0;
return new Promise(async (resolve) => { return new Promise(async (resolve) => {
const resize = tf6.image.resizeBilinear(image17, [model.inputs[0].shape[2], model.inputs[0].shape[1]], false); const resize = tf6.image.resizeBilinear(image18, [model.inputs[0].shape[2], model.inputs[0].shape[1]], false);
const [red, green, blue] = tf6.split(resize, 3, 3); const [red, green, blue] = tf6.split(resize, 3, 3);
resize.dispose(); resize.dispose();
const redNorm = tf6.mul(red, rgb[0]); const redNorm = tf6.mul(red, rgb[0]);
@ -4259,7 +4260,7 @@ function match(embedding, db, threshold = 0) {
return best; return best;
} }
function enhance(input) { function enhance(input) {
const image17 = tf7.tidy(() => { const image18 = tf7.tidy(() => {
const tensor2 = input.image || input.tensor || input; const tensor2 = input.image || input.tensor || input;
if (!(tensor2 instanceof tf7.Tensor)) if (!(tensor2 instanceof tf7.Tensor))
return null; return null;
@ -4270,9 +4271,9 @@ function enhance(input) {
const norm = crop.mul(255); const norm = crop.mul(255);
return norm; return norm;
}); });
return image17; return image18;
} }
async function predict3(image17, config3, idx, count2) { async function predict3(image18, config3, idx, count2) {
var _a, _b; var _a, _b;
if (!model2) if (!model2)
return null; return null;
@ -4282,7 +4283,7 @@ async function predict3(image17, config3, idx, count2) {
} }
skipped2 = 0; skipped2 = 0;
return new Promise(async (resolve) => { return new Promise(async (resolve) => {
const enhanced = enhance(image17); const enhanced = enhance(image18);
let resT; let resT;
const obj = { const obj = {
age: 0, age: 0,
@ -4812,10 +4813,10 @@ async function predict4(input, config3) {
const res = tf9.tidy(() => { const res = tf9.tidy(() => {
if (!model3.inputs[0].shape) if (!model3.inputs[0].shape)
return []; return [];
const resized = input.resizeBilinear([model3.inputs[0].shape[2], model3.inputs[0].shape[1]]); const resized = tf9.image.resizeBilinear(input, [model3.inputs[0].shape[2], model3.inputs[0].shape[1]]);
const normalized = resized.toFloat().div(127.5).sub(1); const normalized = resized.toFloat().div(127.5).sub(1);
const results = model3.execute(normalized, poseNetOutputs); const results = model3.execute(normalized, poseNetOutputs);
const results3d = results.map((y) => y.squeeze([0])); const results3d = results.map((y) => tf9.squeeze(y, [0]));
results3d[1] = results3d[1].sigmoid(); results3d[1] = results3d[1].sigmoid();
return results3d; return results3d;
}); });
@ -4860,16 +4861,16 @@ function getBoxCenter2(box6) {
box6.startPoint[1] + (box6.endPoint[1] - box6.startPoint[1]) / 2 box6.startPoint[1] + (box6.endPoint[1] - box6.startPoint[1]) / 2
]; ];
} }
function cutBoxFromImageAndResize2(box6, image17, cropSize) { function cutBoxFromImageAndResize2(box6, image18, cropSize) {
const h = image17.shape[1]; const h = image18.shape[1];
const w = image17.shape[2]; const w = image18.shape[2];
const boxes = [[ const boxes = [[
box6.startPoint[1] / h, box6.startPoint[1] / h,
box6.startPoint[0] / w, box6.startPoint[0] / w,
box6.endPoint[1] / h, box6.endPoint[1] / h,
box6.endPoint[0] / w box6.endPoint[0] / w
]]; ]];
return tf10.image.cropAndResize(image17, boxes, [0], cropSize); return tf10.image.cropAndResize(image18, boxes, [0], cropSize);
} }
function scaleBoxCoordinates2(box6, factor) { function scaleBoxCoordinates2(box6, factor) {
const startPoint = [box6.startPoint[0] * factor[0], box6.startPoint[1] * factor[1]]; const startPoint = [box6.startPoint[0] * factor[0], box6.startPoint[1] * factor[1]];
@ -7876,7 +7877,7 @@ var HandDetector = class {
} }
async getBoxes(input, config3) { async getBoxes(input, config3) {
const batched = this.model.predict(input); const batched = this.model.predict(input);
const predictions = batched.squeeze(); const predictions = tf11.squeeze(batched);
batched.dispose(); batched.dispose();
const scoresT = tf11.tidy(() => tf11.sigmoid(tf11.slice(predictions, [0, 0], [-1, 1])).squeeze()); const scoresT = tf11.tidy(() => tf11.sigmoid(tf11.slice(predictions, [0, 0], [-1, 1])).squeeze());
const scores = scoresT.dataSync(); const scores = scoresT.dataSync();
@ -7904,9 +7905,9 @@ var HandDetector = class {
async estimateHandBounds(input, config3) { async estimateHandBounds(input, config3) {
const inputHeight = input.shape[1]; const inputHeight = input.shape[1];
const inputWidth = input.shape[2]; const inputWidth = input.shape[2];
const image17 = tf11.tidy(() => input.resizeBilinear([this.inputSize, this.inputSize]).div(127.5).sub(1)); const image18 = tf11.tidy(() => input.resizeBilinear([this.inputSize, this.inputSize]).div(127.5).sub(1));
const predictions = await this.getBoxes(image17, config3); const predictions = await this.getBoxes(image18, config3);
image17.dispose(); image18.dispose();
const hands = []; const hands = [];
if (!predictions || predictions.length === 0) if (!predictions || predictions.length === 0)
return hands; return hands;
@ -8051,11 +8052,11 @@ var HandPipeline = class {
Math.trunc(coord[2]) Math.trunc(coord[2])
]); ]);
} }
async estimateHands(image17, config3) { async estimateHands(image18, config3) {
let useFreshBox = false; let useFreshBox = false;
let boxes; let boxes;
if (this.skipped === 0 || this.skipped > config3.hand.skipFrames || !config3.hand.landmarks || !config3.skipFrame) { if (this.skipped === 0 || this.skipped > config3.hand.skipFrames || !config3.hand.landmarks || !config3.skipFrame) {
boxes = await this.handDetector.estimateHandBounds(image17, config3); boxes = await this.handDetector.estimateHandBounds(image18, config3);
this.skipped = 0; this.skipped = 0;
} }
if (config3.skipFrame) if (config3.skipFrame)
@ -8074,8 +8075,8 @@ var HandPipeline = class {
if (config3.hand.landmarks) { if (config3.hand.landmarks) {
const angle = config3.hand.rotation ? computeRotation2(currentBox.palmLandmarks[palmLandmarksPalmBase], currentBox.palmLandmarks[palmLandmarksMiddleFingerBase]) : 0; const angle = config3.hand.rotation ? computeRotation2(currentBox.palmLandmarks[palmLandmarksPalmBase], currentBox.palmLandmarks[palmLandmarksMiddleFingerBase]) : 0;
const palmCenter = getBoxCenter2(currentBox); const palmCenter = getBoxCenter2(currentBox);
const palmCenterNormalized = [palmCenter[0] / image17.shape[2], palmCenter[1] / image17.shape[1]]; const palmCenterNormalized = [palmCenter[0] / image18.shape[2], palmCenter[1] / image18.shape[1]];
const rotatedImage = config3.hand.rotation && tf12.ENV.flags.IS_BROWSER ? tf12.image.rotateWithOffset(image17, angle, 0, palmCenterNormalized) : image17.clone(); const rotatedImage = config3.hand.rotation && tf12.ENV.flags.IS_BROWSER ? tf12.image.rotateWithOffset(image18, angle, 0, palmCenterNormalized) : image18.clone();
const rotationMatrix = buildRotationMatrix2(-angle, palmCenter); const rotationMatrix = buildRotationMatrix2(-angle, palmCenter);
const newBox = useFreshBox ? this.getBoxForPalmLandmarks(currentBox.palmLandmarks, rotationMatrix) : currentBox; const newBox = useFreshBox ? this.getBoxForPalmLandmarks(currentBox.palmLandmarks, rotationMatrix) : currentBox;
const croppedInput = cutBoxFromImageAndResize2(newBox, rotatedImage, [this.inputSize, this.inputSize]); const croppedInput = cutBoxFromImageAndResize2(newBox, rotatedImage, [this.inputSize, this.inputSize]);
@ -8299,14 +8300,14 @@ async function load7(config3) {
log("cached model:", model4["modelUrl"]); log("cached model:", model4["modelUrl"]);
return model4; return model4;
} }
async function predict6(image17, config3) { async function predict6(image18, config3) {
var _a; var _a;
if (!model4) if (!model4)
return []; return [];
if (!config3.body.enabled) if (!config3.body.enabled)
return []; return [];
const imgSize = { width: image17.shape[2] || 0, height: image17.shape[1] || 0 }; const imgSize = { width: image18.shape[2] || 0, height: image18.shape[1] || 0 };
const resize = tf14.image.resizeBilinear(image17, [model4["width"], model4["height"]], false); const resize = tf14.image.resizeBilinear(image18, [model4["width"], model4["height"]], false);
const normalize = tf14.div(resize, [255]); const normalize = tf14.div(resize, [255]);
resize.dispose(); resize.dispose();
const resT = await model4.predict(normalize); const resT = await model4.predict(normalize);
@ -8382,7 +8383,7 @@ function max2d(inputs, minScore) {
return [0, 0, newScore]; return [0, 0, newScore];
}); });
} }
async function predict7(image17, config3) { async function predict7(image18, config3) {
if (skipped3 < config3.body.skipFrames && config3.skipFrame && Object.keys(keypoints).length > 0) { if (skipped3 < config3.body.skipFrames && config3.skipFrame && Object.keys(keypoints).length > 0) {
skipped3++; skipped3++;
return [{ id: 0, score, box: box4, boxRaw, keypoints }]; return [{ id: 0, score, box: box4, boxRaw, keypoints }];
@ -8392,7 +8393,7 @@ async function predict7(image17, config3) {
const tensor2 = tf15.tidy(() => { const tensor2 = tf15.tidy(() => {
if (!model5.inputs[0].shape) if (!model5.inputs[0].shape)
return null; return null;
const resize = tf15.image.resizeBilinear(image17, [model5.inputs[0].shape[2], model5.inputs[0].shape[1]], false); const resize = tf15.image.resizeBilinear(image18, [model5.inputs[0].shape[2], model5.inputs[0].shape[1]], false);
const enhance2 = tf15.mul(resize, 2); const enhance2 = tf15.mul(resize, 2);
const norm = enhance2.sub(1); const norm = enhance2.sub(1);
return norm; return norm;
@ -8403,10 +8404,10 @@ async function predict7(image17, config3) {
tensor2.dispose(); tensor2.dispose();
if (resT) { if (resT) {
keypoints.length = 0; keypoints.length = 0;
const squeeze4 = resT.squeeze(); const squeeze7 = resT.squeeze();
tf15.dispose(resT); tf15.dispose(resT);
const stack2 = squeeze4.unstack(2); const stack2 = squeeze7.unstack(2);
tf15.dispose(squeeze4); tf15.dispose(squeeze7);
for (let id = 0; id < stack2.length; id++) { for (let id = 0; id < stack2.length; id++) {
const [x2, y2, partScore] = max2d(stack2[id], config3.body.minConfidence); const [x2, y2, partScore] = max2d(stack2[id], config3.body.minConfidence);
if (score > config3.body.minConfidence) { if (score > config3.body.minConfidence) {
@ -8418,8 +8419,8 @@ async function predict7(image17, config3) {
y2 / model5.inputs[0].shape[1] y2 / model5.inputs[0].shape[1]
], ],
position: [ position: [
Math.round(image17.shape[2] * x2 / model5.inputs[0].shape[2]), Math.round(image18.shape[2] * x2 / model5.inputs[0].shape[2]),
Math.round(image17.shape[1] * y2 / model5.inputs[0].shape[1]) Math.round(image18.shape[1] * y2 / model5.inputs[0].shape[1])
] ]
}); });
} }
@ -8467,7 +8468,7 @@ async function load9(config3) {
log("cached model:", model6["modelUrl"]); log("cached model:", model6["modelUrl"]);
return model6; return model6;
} }
async function predict8(image17, config3) { async function predict8(image18, config3) {
if (skipped4 < config3.body.skipFrames && config3.skipFrame && Object.keys(keypoints2).length > 0) { if (skipped4 < config3.body.skipFrames && config3.skipFrame && Object.keys(keypoints2).length > 0) {
skipped4++; skipped4++;
return [{ id: 0, score: score2, box: box5, boxRaw: boxRaw2, keypoints: keypoints2 }]; return [{ id: 0, score: score2, box: box5, boxRaw: boxRaw2, keypoints: keypoints2 }];
@ -8477,7 +8478,7 @@ async function predict8(image17, config3) {
const tensor2 = tf16.tidy(() => { const tensor2 = tf16.tidy(() => {
if (!model6.inputs[0].shape) if (!model6.inputs[0].shape)
return null; return null;
const resize = tf16.image.resizeBilinear(image17, [model6.inputs[0].shape[2], model6.inputs[0].shape[1]], false); const resize = tf16.image.resizeBilinear(image18, [model6.inputs[0].shape[2], model6.inputs[0].shape[1]], false);
const cast2 = tf16.cast(resize, "int32"); const cast2 = tf16.cast(resize, "int32");
return cast2; return cast2;
}); });
@ -8501,8 +8502,8 @@ async function predict8(image17, config3) {
kpt3[id][0] kpt3[id][0]
], ],
position: [ position: [
Math.round((image17.shape[2] || 0) * kpt3[id][1]), Math.round((image18.shape[2] || 0) * kpt3[id][1]),
Math.round((image17.shape[1] || 0) * kpt3[id][0]) Math.round((image18.shape[1] || 0) * kpt3[id][0])
] ]
}); });
} }
@ -8697,15 +8698,15 @@ async function process2(res, inputSize, outputShape, config3) {
results = results.filter((a, idx) => nmsIdx.includes(idx)).sort((a, b) => b.score - a.score); results = results.filter((a, idx) => nmsIdx.includes(idx)).sort((a, b) => b.score - a.score);
return results; return results;
} }
async function predict9(image17, config3) { async function predict9(image18, config3) {
if (skipped5 < config3.object.skipFrames && config3.skipFrame && last3.length > 0) { if (skipped5 < config3.object.skipFrames && config3.skipFrame && last3.length > 0) {
skipped5++; skipped5++;
return last3; return last3;
} }
skipped5 = 0; skipped5 = 0;
return new Promise(async (resolve) => { return new Promise(async (resolve) => {
const outputSize = [image17.shape[2], image17.shape[1]]; const outputSize = [image18.shape[2], image18.shape[1]];
const resize = tf17.image.resizeBilinear(image17, [model7.inputSize, model7.inputSize], false); const resize = tf17.image.resizeBilinear(image18, [model7.inputSize, model7.inputSize], false);
const norm = resize.div(255); const norm = resize.div(255);
const transpose = norm.transpose([0, 3, 1, 2]); const transpose = norm.transpose([0, 3, 1, 2]);
norm.dispose(); norm.dispose();
@ -9059,8 +9060,8 @@ function GLImageFilter(params) {
gl.uniform1f(_currentProgram.uniform.flipY, flipY ? -1 : 1); gl.uniform1f(_currentProgram.uniform.flipY, flipY ? -1 : 1);
gl.drawArrays(gl.TRIANGLES, 0, 6); gl.drawArrays(gl.TRIANGLES, 0, 6);
}; };
this.apply = function(image17) { this.apply = function(image18) {
_resize(image17.width, image17.height); _resize(image18.width, image18.height);
_drawCount = 0; _drawCount = 0;
if (!_sourceTexture) if (!_sourceTexture)
_sourceTexture = gl.createTexture(); _sourceTexture = gl.createTexture();
@ -9069,7 +9070,7 @@ function GLImageFilter(params) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image17); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image18);
if (_filterChain.length === 0) { if (_filterChain.length === 0) {
_draw(); _draw();
return _canvas; return _canvas;
@ -10444,10 +10445,10 @@ async function predict11(input, config3) {
const overlay = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(input.canvas.width, input.canvas.height) : document.createElement("canvas"); const overlay = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(input.canvas.width, input.canvas.height) : document.createElement("canvas");
overlay.width = input.canvas.width; overlay.width = input.canvas.width;
overlay.height = input.canvas.height; overlay.height = input.canvas.height;
const squeeze4 = tf20.squeeze(res, 0); const squeeze7 = tf20.squeeze(res, 0);
let resizeOutput; let resizeOutput;
if (squeeze4.shape[2] === 2) { if (squeeze7.shape[2] === 2) {
const softmax = squeeze4.softmax(); const softmax = squeeze7.softmax();
const [bg, fg] = tf20.unstack(softmax, 2); const [bg, fg] = tf20.unstack(softmax, 2);
const expand = fg.expandDims(2); const expand = fg.expandDims(2);
const pad = expand.expandDims(0); const pad = expand.expandDims(0);
@ -10460,12 +10461,12 @@ async function predict11(input, config3) {
tf20.dispose(expand); tf20.dispose(expand);
tf20.dispose(pad); tf20.dispose(pad);
} else { } else {
resizeOutput = tf20.image.resizeBilinear(squeeze4, [(_c = input.tensor) == null ? void 0 : _c.shape[1], (_d = input.tensor) == null ? void 0 : _d.shape[2]]); resizeOutput = tf20.image.resizeBilinear(squeeze7, [(_c = input.tensor) == null ? void 0 : _c.shape[1], (_d = input.tensor) == null ? void 0 : _d.shape[2]]);
} }
if (tf20.browser) if (tf20.browser)
await tf20.browser.toPixels(resizeOutput, overlay); await tf20.browser.toPixels(resizeOutput, overlay);
tf20.dispose(resizeOutput); tf20.dispose(resizeOutput);
tf20.dispose(squeeze4); tf20.dispose(squeeze7);
tf20.dispose(res); tf20.dispose(res);
const alphaCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(input.canvas.width, input.canvas.height) : document.createElement("canvas"); const alphaCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(input.canvas.width, input.canvas.height) : document.createElement("canvas");
alphaCanvas.width = input.canvas.width; alphaCanvas.width = input.canvas.width;

View File

@ -341,16 +341,16 @@ function getBoxCenter(box6) {
box6.startPoint[1] + (box6.endPoint[1] - box6.startPoint[1]) / 2 box6.startPoint[1] + (box6.endPoint[1] - box6.startPoint[1]) / 2
]; ];
} }
function cutBoxFromImageAndResize(box6, image17, cropSize) { function cutBoxFromImageAndResize(box6, image18, cropSize) {
const h = image17.shape[1]; const h = image18.shape[1];
const w = image17.shape[2]; const w = image18.shape[2];
const boxes = [[ const boxes = [[
box6.startPoint[1] / h, box6.startPoint[1] / h,
box6.startPoint[0] / w, box6.startPoint[0] / w,
box6.endPoint[1] / h, box6.endPoint[1] / h,
box6.endPoint[0] / w box6.endPoint[0] / w
]]; ]];
return tf2.image.cropAndResize(image17, boxes, [0], cropSize); return tf2.image.cropAndResize(image18, boxes, [0], cropSize);
} }
function enlargeBox(box6, factor = 1.5) { function enlargeBox(box6, factor = 1.5) {
const center = getBoxCenter(box6); const center = getBoxCenter(box6);
@ -495,7 +495,7 @@ var BlazeFaceModel = class {
if (!inputImage || inputImage.isDisposedInternal || inputImage.shape.length !== 4 || inputImage.shape[1] < 1 || inputImage.shape[2] < 1) if (!inputImage || inputImage.isDisposedInternal || inputImage.shape.length !== 4 || inputImage.shape[1] < 1 || inputImage.shape[2] < 1)
return null; return null;
const [batch, boxes, scores] = tf3.tidy(() => { const [batch, boxes, scores] = tf3.tidy(() => {
const resizedImage = inputImage.resizeBilinear([this.inputSize, this.inputSize]); const resizedImage = tf3.image.resizeBilinear(inputImage, [this.inputSize, this.inputSize]);
const normalizedImage = resizedImage.div(127.5).sub(0.5); const normalizedImage = resizedImage.div(127.5).sub(0.5);
const res = this.model.execute(normalizedImage); const res = this.model.execute(normalizedImage);
let batchOut; let batchOut;
@ -506,7 +506,7 @@ var BlazeFaceModel = class {
const concat3 = tf3.concat([concat512, concat384], 1); const concat3 = tf3.concat([concat512, concat384], 1);
batchOut = concat3.squeeze(0); batchOut = concat3.squeeze(0);
} else { } else {
batchOut = res.squeeze(); batchOut = tf3.squeeze(res);
} }
const boxesOut = decodeBounds(batchOut, this.anchors, [this.inputSize, this.inputSize]); const boxesOut = decodeBounds(batchOut, this.anchors, [this.inputSize, this.inputSize]);
const logits = tf3.slice(batchOut, [0, 0], [-1, 1]); const logits = tf3.slice(batchOut, [0, 0], [-1, 1]);
@ -4175,7 +4175,7 @@ async function load3(config3) {
log("cached model:", model.modelUrl); log("cached model:", model.modelUrl);
return model; return model;
} }
async function predict2(image17, config3, idx, count2) { async function predict2(image18, config3, idx, count2) {
if (!model) if (!model)
return null; return null;
if (skipped < config3.face.emotion.skipFrames && config3.skipFrame && lastCount === count2 && last[idx] && last[idx].length > 0) { if (skipped < config3.face.emotion.skipFrames && config3.skipFrame && lastCount === count2 && last[idx] && last[idx].length > 0) {
@ -4184,7 +4184,7 @@ async function predict2(image17, config3, idx, count2) {
} }
skipped = 0; skipped = 0;
return new Promise(async (resolve) => { return new Promise(async (resolve) => {
const resize = tf6.image.resizeBilinear(image17, [model.inputs[0].shape[2], model.inputs[0].shape[1]], false); const resize = tf6.image.resizeBilinear(image18, [model.inputs[0].shape[2], model.inputs[0].shape[1]], false);
const [red, green, blue] = tf6.split(resize, 3, 3); const [red, green, blue] = tf6.split(resize, 3, 3);
resize.dispose(); resize.dispose();
const redNorm = tf6.mul(red, rgb[0]); const redNorm = tf6.mul(red, rgb[0]);
@ -4260,7 +4260,7 @@ function match(embedding, db, threshold = 0) {
return best; return best;
} }
function enhance(input) { function enhance(input) {
const image17 = tf7.tidy(() => { const image18 = tf7.tidy(() => {
const tensor2 = input.image || input.tensor || input; const tensor2 = input.image || input.tensor || input;
if (!(tensor2 instanceof tf7.Tensor)) if (!(tensor2 instanceof tf7.Tensor))
return null; return null;
@ -4271,9 +4271,9 @@ function enhance(input) {
const norm = crop.mul(255); const norm = crop.mul(255);
return norm; return norm;
}); });
return image17; return image18;
} }
async function predict3(image17, config3, idx, count2) { async function predict3(image18, config3, idx, count2) {
var _a, _b; var _a, _b;
if (!model2) if (!model2)
return null; return null;
@ -4283,7 +4283,7 @@ async function predict3(image17, config3, idx, count2) {
} }
skipped2 = 0; skipped2 = 0;
return new Promise(async (resolve) => { return new Promise(async (resolve) => {
const enhanced = enhance(image17); const enhanced = enhance(image18);
let resT; let resT;
const obj = { const obj = {
age: 0, age: 0,
@ -4813,10 +4813,10 @@ async function predict4(input, config3) {
const res = tf9.tidy(() => { const res = tf9.tidy(() => {
if (!model3.inputs[0].shape) if (!model3.inputs[0].shape)
return []; return [];
const resized = input.resizeBilinear([model3.inputs[0].shape[2], model3.inputs[0].shape[1]]); const resized = tf9.image.resizeBilinear(input, [model3.inputs[0].shape[2], model3.inputs[0].shape[1]]);
const normalized = resized.toFloat().div(127.5).sub(1); const normalized = resized.toFloat().div(127.5).sub(1);
const results = model3.execute(normalized, poseNetOutputs); const results = model3.execute(normalized, poseNetOutputs);
const results3d = results.map((y) => y.squeeze([0])); const results3d = results.map((y) => tf9.squeeze(y, [0]));
results3d[1] = results3d[1].sigmoid(); results3d[1] = results3d[1].sigmoid();
return results3d; return results3d;
}); });
@ -4861,16 +4861,16 @@ function getBoxCenter2(box6) {
box6.startPoint[1] + (box6.endPoint[1] - box6.startPoint[1]) / 2 box6.startPoint[1] + (box6.endPoint[1] - box6.startPoint[1]) / 2
]; ];
} }
function cutBoxFromImageAndResize2(box6, image17, cropSize) { function cutBoxFromImageAndResize2(box6, image18, cropSize) {
const h = image17.shape[1]; const h = image18.shape[1];
const w = image17.shape[2]; const w = image18.shape[2];
const boxes = [[ const boxes = [[
box6.startPoint[1] / h, box6.startPoint[1] / h,
box6.startPoint[0] / w, box6.startPoint[0] / w,
box6.endPoint[1] / h, box6.endPoint[1] / h,
box6.endPoint[0] / w box6.endPoint[0] / w
]]; ]];
return tf10.image.cropAndResize(image17, boxes, [0], cropSize); return tf10.image.cropAndResize(image18, boxes, [0], cropSize);
} }
function scaleBoxCoordinates2(box6, factor) { function scaleBoxCoordinates2(box6, factor) {
const startPoint = [box6.startPoint[0] * factor[0], box6.startPoint[1] * factor[1]]; const startPoint = [box6.startPoint[0] * factor[0], box6.startPoint[1] * factor[1]];
@ -7877,7 +7877,7 @@ var HandDetector = class {
} }
async getBoxes(input, config3) { async getBoxes(input, config3) {
const batched = this.model.predict(input); const batched = this.model.predict(input);
const predictions = batched.squeeze(); const predictions = tf11.squeeze(batched);
batched.dispose(); batched.dispose();
const scoresT = tf11.tidy(() => tf11.sigmoid(tf11.slice(predictions, [0, 0], [-1, 1])).squeeze()); const scoresT = tf11.tidy(() => tf11.sigmoid(tf11.slice(predictions, [0, 0], [-1, 1])).squeeze());
const scores = scoresT.dataSync(); const scores = scoresT.dataSync();
@ -7905,9 +7905,9 @@ var HandDetector = class {
async estimateHandBounds(input, config3) { async estimateHandBounds(input, config3) {
const inputHeight = input.shape[1]; const inputHeight = input.shape[1];
const inputWidth = input.shape[2]; const inputWidth = input.shape[2];
const image17 = tf11.tidy(() => input.resizeBilinear([this.inputSize, this.inputSize]).div(127.5).sub(1)); const image18 = tf11.tidy(() => input.resizeBilinear([this.inputSize, this.inputSize]).div(127.5).sub(1));
const predictions = await this.getBoxes(image17, config3); const predictions = await this.getBoxes(image18, config3);
image17.dispose(); image18.dispose();
const hands = []; const hands = [];
if (!predictions || predictions.length === 0) if (!predictions || predictions.length === 0)
return hands; return hands;
@ -8052,11 +8052,11 @@ var HandPipeline = class {
Math.trunc(coord[2]) Math.trunc(coord[2])
]); ]);
} }
async estimateHands(image17, config3) { async estimateHands(image18, config3) {
let useFreshBox = false; let useFreshBox = false;
let boxes; let boxes;
if (this.skipped === 0 || this.skipped > config3.hand.skipFrames || !config3.hand.landmarks || !config3.skipFrame) { if (this.skipped === 0 || this.skipped > config3.hand.skipFrames || !config3.hand.landmarks || !config3.skipFrame) {
boxes = await this.handDetector.estimateHandBounds(image17, config3); boxes = await this.handDetector.estimateHandBounds(image18, config3);
this.skipped = 0; this.skipped = 0;
} }
if (config3.skipFrame) if (config3.skipFrame)
@ -8075,8 +8075,8 @@ var HandPipeline = class {
if (config3.hand.landmarks) { if (config3.hand.landmarks) {
const angle = config3.hand.rotation ? computeRotation2(currentBox.palmLandmarks[palmLandmarksPalmBase], currentBox.palmLandmarks[palmLandmarksMiddleFingerBase]) : 0; const angle = config3.hand.rotation ? computeRotation2(currentBox.palmLandmarks[palmLandmarksPalmBase], currentBox.palmLandmarks[palmLandmarksMiddleFingerBase]) : 0;
const palmCenter = getBoxCenter2(currentBox); const palmCenter = getBoxCenter2(currentBox);
const palmCenterNormalized = [palmCenter[0] / image17.shape[2], palmCenter[1] / image17.shape[1]]; const palmCenterNormalized = [palmCenter[0] / image18.shape[2], palmCenter[1] / image18.shape[1]];
const rotatedImage = config3.hand.rotation && tf12.ENV.flags.IS_BROWSER ? tf12.image.rotateWithOffset(image17, angle, 0, palmCenterNormalized) : image17.clone(); const rotatedImage = config3.hand.rotation && tf12.ENV.flags.IS_BROWSER ? tf12.image.rotateWithOffset(image18, angle, 0, palmCenterNormalized) : image18.clone();
const rotationMatrix = buildRotationMatrix2(-angle, palmCenter); const rotationMatrix = buildRotationMatrix2(-angle, palmCenter);
const newBox = useFreshBox ? this.getBoxForPalmLandmarks(currentBox.palmLandmarks, rotationMatrix) : currentBox; const newBox = useFreshBox ? this.getBoxForPalmLandmarks(currentBox.palmLandmarks, rotationMatrix) : currentBox;
const croppedInput = cutBoxFromImageAndResize2(newBox, rotatedImage, [this.inputSize, this.inputSize]); const croppedInput = cutBoxFromImageAndResize2(newBox, rotatedImage, [this.inputSize, this.inputSize]);
@ -8300,14 +8300,14 @@ async function load7(config3) {
log("cached model:", model4["modelUrl"]); log("cached model:", model4["modelUrl"]);
return model4; return model4;
} }
async function predict6(image17, config3) { async function predict6(image18, config3) {
var _a; var _a;
if (!model4) if (!model4)
return []; return [];
if (!config3.body.enabled) if (!config3.body.enabled)
return []; return [];
const imgSize = { width: image17.shape[2] || 0, height: image17.shape[1] || 0 }; const imgSize = { width: image18.shape[2] || 0, height: image18.shape[1] || 0 };
const resize = tf14.image.resizeBilinear(image17, [model4["width"], model4["height"]], false); const resize = tf14.image.resizeBilinear(image18, [model4["width"], model4["height"]], false);
const normalize = tf14.div(resize, [255]); const normalize = tf14.div(resize, [255]);
resize.dispose(); resize.dispose();
const resT = await model4.predict(normalize); const resT = await model4.predict(normalize);
@ -8383,7 +8383,7 @@ function max2d(inputs, minScore) {
return [0, 0, newScore]; return [0, 0, newScore];
}); });
} }
async function predict7(image17, config3) { async function predict7(image18, config3) {
if (skipped3 < config3.body.skipFrames && config3.skipFrame && Object.keys(keypoints).length > 0) { if (skipped3 < config3.body.skipFrames && config3.skipFrame && Object.keys(keypoints).length > 0) {
skipped3++; skipped3++;
return [{ id: 0, score, box: box4, boxRaw, keypoints }]; return [{ id: 0, score, box: box4, boxRaw, keypoints }];
@ -8393,7 +8393,7 @@ async function predict7(image17, config3) {
const tensor2 = tf15.tidy(() => { const tensor2 = tf15.tidy(() => {
if (!model5.inputs[0].shape) if (!model5.inputs[0].shape)
return null; return null;
const resize = tf15.image.resizeBilinear(image17, [model5.inputs[0].shape[2], model5.inputs[0].shape[1]], false); const resize = tf15.image.resizeBilinear(image18, [model5.inputs[0].shape[2], model5.inputs[0].shape[1]], false);
const enhance2 = tf15.mul(resize, 2); const enhance2 = tf15.mul(resize, 2);
const norm = enhance2.sub(1); const norm = enhance2.sub(1);
return norm; return norm;
@ -8404,10 +8404,10 @@ async function predict7(image17, config3) {
tensor2.dispose(); tensor2.dispose();
if (resT) { if (resT) {
keypoints.length = 0; keypoints.length = 0;
const squeeze4 = resT.squeeze(); const squeeze7 = resT.squeeze();
tf15.dispose(resT); tf15.dispose(resT);
const stack2 = squeeze4.unstack(2); const stack2 = squeeze7.unstack(2);
tf15.dispose(squeeze4); tf15.dispose(squeeze7);
for (let id = 0; id < stack2.length; id++) { for (let id = 0; id < stack2.length; id++) {
const [x2, y2, partScore] = max2d(stack2[id], config3.body.minConfidence); const [x2, y2, partScore] = max2d(stack2[id], config3.body.minConfidence);
if (score > config3.body.minConfidence) { if (score > config3.body.minConfidence) {
@ -8419,8 +8419,8 @@ async function predict7(image17, config3) {
y2 / model5.inputs[0].shape[1] y2 / model5.inputs[0].shape[1]
], ],
position: [ position: [
Math.round(image17.shape[2] * x2 / model5.inputs[0].shape[2]), Math.round(image18.shape[2] * x2 / model5.inputs[0].shape[2]),
Math.round(image17.shape[1] * y2 / model5.inputs[0].shape[1]) Math.round(image18.shape[1] * y2 / model5.inputs[0].shape[1])
] ]
}); });
} }
@ -8468,7 +8468,7 @@ async function load9(config3) {
log("cached model:", model6["modelUrl"]); log("cached model:", model6["modelUrl"]);
return model6; return model6;
} }
async function predict8(image17, config3) { async function predict8(image18, config3) {
if (skipped4 < config3.body.skipFrames && config3.skipFrame && Object.keys(keypoints2).length > 0) { if (skipped4 < config3.body.skipFrames && config3.skipFrame && Object.keys(keypoints2).length > 0) {
skipped4++; skipped4++;
return [{ id: 0, score: score2, box: box5, boxRaw: boxRaw2, keypoints: keypoints2 }]; return [{ id: 0, score: score2, box: box5, boxRaw: boxRaw2, keypoints: keypoints2 }];
@ -8478,7 +8478,7 @@ async function predict8(image17, config3) {
const tensor2 = tf16.tidy(() => { const tensor2 = tf16.tidy(() => {
if (!model6.inputs[0].shape) if (!model6.inputs[0].shape)
return null; return null;
const resize = tf16.image.resizeBilinear(image17, [model6.inputs[0].shape[2], model6.inputs[0].shape[1]], false); const resize = tf16.image.resizeBilinear(image18, [model6.inputs[0].shape[2], model6.inputs[0].shape[1]], false);
const cast2 = tf16.cast(resize, "int32"); const cast2 = tf16.cast(resize, "int32");
return cast2; return cast2;
}); });
@ -8502,8 +8502,8 @@ async function predict8(image17, config3) {
kpt3[id][0] kpt3[id][0]
], ],
position: [ position: [
Math.round((image17.shape[2] || 0) * kpt3[id][1]), Math.round((image18.shape[2] || 0) * kpt3[id][1]),
Math.round((image17.shape[1] || 0) * kpt3[id][0]) Math.round((image18.shape[1] || 0) * kpt3[id][0])
] ]
}); });
} }
@ -8698,15 +8698,15 @@ async function process2(res, inputSize, outputShape, config3) {
results = results.filter((a, idx) => nmsIdx.includes(idx)).sort((a, b) => b.score - a.score); results = results.filter((a, idx) => nmsIdx.includes(idx)).sort((a, b) => b.score - a.score);
return results; return results;
} }
async function predict9(image17, config3) { async function predict9(image18, config3) {
if (skipped5 < config3.object.skipFrames && config3.skipFrame && last3.length > 0) { if (skipped5 < config3.object.skipFrames && config3.skipFrame && last3.length > 0) {
skipped5++; skipped5++;
return last3; return last3;
} }
skipped5 = 0; skipped5 = 0;
return new Promise(async (resolve) => { return new Promise(async (resolve) => {
const outputSize = [image17.shape[2], image17.shape[1]]; const outputSize = [image18.shape[2], image18.shape[1]];
const resize = tf17.image.resizeBilinear(image17, [model7.inputSize, model7.inputSize], false); const resize = tf17.image.resizeBilinear(image18, [model7.inputSize, model7.inputSize], false);
const norm = resize.div(255); const norm = resize.div(255);
const transpose = norm.transpose([0, 3, 1, 2]); const transpose = norm.transpose([0, 3, 1, 2]);
norm.dispose(); norm.dispose();
@ -9060,8 +9060,8 @@ function GLImageFilter(params) {
gl.uniform1f(_currentProgram.uniform.flipY, flipY ? -1 : 1); gl.uniform1f(_currentProgram.uniform.flipY, flipY ? -1 : 1);
gl.drawArrays(gl.TRIANGLES, 0, 6); gl.drawArrays(gl.TRIANGLES, 0, 6);
}; };
this.apply = function(image17) { this.apply = function(image18) {
_resize(image17.width, image17.height); _resize(image18.width, image18.height);
_drawCount = 0; _drawCount = 0;
if (!_sourceTexture) if (!_sourceTexture)
_sourceTexture = gl.createTexture(); _sourceTexture = gl.createTexture();
@ -9070,7 +9070,7 @@ function GLImageFilter(params) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image17); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image18);
if (_filterChain.length === 0) { if (_filterChain.length === 0) {
_draw(); _draw();
return _canvas; return _canvas;
@ -10445,10 +10445,10 @@ async function predict11(input, config3) {
const overlay = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(input.canvas.width, input.canvas.height) : document.createElement("canvas"); const overlay = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(input.canvas.width, input.canvas.height) : document.createElement("canvas");
overlay.width = input.canvas.width; overlay.width = input.canvas.width;
overlay.height = input.canvas.height; overlay.height = input.canvas.height;
const squeeze4 = tf20.squeeze(res, 0); const squeeze7 = tf20.squeeze(res, 0);
let resizeOutput; let resizeOutput;
if (squeeze4.shape[2] === 2) { if (squeeze7.shape[2] === 2) {
const softmax = squeeze4.softmax(); const softmax = squeeze7.softmax();
const [bg, fg] = tf20.unstack(softmax, 2); const [bg, fg] = tf20.unstack(softmax, 2);
const expand = fg.expandDims(2); const expand = fg.expandDims(2);
const pad = expand.expandDims(0); const pad = expand.expandDims(0);
@ -10461,12 +10461,12 @@ async function predict11(input, config3) {
tf20.dispose(expand); tf20.dispose(expand);
tf20.dispose(pad); tf20.dispose(pad);
} else { } else {
resizeOutput = tf20.image.resizeBilinear(squeeze4, [(_c = input.tensor) == null ? void 0 : _c.shape[1], (_d = input.tensor) == null ? void 0 : _d.shape[2]]); resizeOutput = tf20.image.resizeBilinear(squeeze7, [(_c = input.tensor) == null ? void 0 : _c.shape[1], (_d = input.tensor) == null ? void 0 : _d.shape[2]]);
} }
if (tf20.browser) if (tf20.browser)
await tf20.browser.toPixels(resizeOutput, overlay); await tf20.browser.toPixels(resizeOutput, overlay);
tf20.dispose(resizeOutput); tf20.dispose(resizeOutput);
tf20.dispose(squeeze4); tf20.dispose(squeeze7);
tf20.dispose(res); tf20.dispose(res);
const alphaCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(input.canvas.width, input.canvas.height) : document.createElement("canvas"); const alphaCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(input.canvas.width, input.canvas.height) : document.createElement("canvas");
alphaCanvas.width = input.canvas.width; alphaCanvas.width = input.canvas.width;

102
dist/human.node.js vendored
View File

@ -340,16 +340,16 @@ function getBoxCenter(box6) {
box6.startPoint[1] + (box6.endPoint[1] - box6.startPoint[1]) / 2 box6.startPoint[1] + (box6.endPoint[1] - box6.startPoint[1]) / 2
]; ];
} }
function cutBoxFromImageAndResize(box6, image17, cropSize) { function cutBoxFromImageAndResize(box6, image18, cropSize) {
const h = image17.shape[1]; const h = image18.shape[1];
const w = image17.shape[2]; const w = image18.shape[2];
const boxes = [[ const boxes = [[
box6.startPoint[1] / h, box6.startPoint[1] / h,
box6.startPoint[0] / w, box6.startPoint[0] / w,
box6.endPoint[1] / h, box6.endPoint[1] / h,
box6.endPoint[0] / w box6.endPoint[0] / w
]]; ]];
return tf2.image.cropAndResize(image17, boxes, [0], cropSize); return tf2.image.cropAndResize(image18, boxes, [0], cropSize);
} }
function enlargeBox(box6, factor = 1.5) { function enlargeBox(box6, factor = 1.5) {
const center = getBoxCenter(box6); const center = getBoxCenter(box6);
@ -494,7 +494,7 @@ var BlazeFaceModel = class {
if (!inputImage || inputImage.isDisposedInternal || inputImage.shape.length !== 4 || inputImage.shape[1] < 1 || inputImage.shape[2] < 1) if (!inputImage || inputImage.isDisposedInternal || inputImage.shape.length !== 4 || inputImage.shape[1] < 1 || inputImage.shape[2] < 1)
return null; return null;
const [batch, boxes, scores] = tf3.tidy(() => { const [batch, boxes, scores] = tf3.tidy(() => {
const resizedImage = inputImage.resizeBilinear([this.inputSize, this.inputSize]); const resizedImage = tf3.image.resizeBilinear(inputImage, [this.inputSize, this.inputSize]);
const normalizedImage = resizedImage.div(127.5).sub(0.5); const normalizedImage = resizedImage.div(127.5).sub(0.5);
const res = this.model.execute(normalizedImage); const res = this.model.execute(normalizedImage);
let batchOut; let batchOut;
@ -505,7 +505,7 @@ var BlazeFaceModel = class {
const concat3 = tf3.concat([concat512, concat384], 1); const concat3 = tf3.concat([concat512, concat384], 1);
batchOut = concat3.squeeze(0); batchOut = concat3.squeeze(0);
} else { } else {
batchOut = res.squeeze(); batchOut = tf3.squeeze(res);
} }
const boxesOut = decodeBounds(batchOut, this.anchors, [this.inputSize, this.inputSize]); const boxesOut = decodeBounds(batchOut, this.anchors, [this.inputSize, this.inputSize]);
const logits = tf3.slice(batchOut, [0, 0], [-1, 1]); const logits = tf3.slice(batchOut, [0, 0], [-1, 1]);
@ -4174,7 +4174,7 @@ async function load3(config3) {
log("cached model:", model.modelUrl); log("cached model:", model.modelUrl);
return model; return model;
} }
async function predict2(image17, config3, idx, count2) { async function predict2(image18, config3, idx, count2) {
if (!model) if (!model)
return null; return null;
if (skipped < config3.face.emotion.skipFrames && config3.skipFrame && lastCount === count2 && last[idx] && last[idx].length > 0) { if (skipped < config3.face.emotion.skipFrames && config3.skipFrame && lastCount === count2 && last[idx] && last[idx].length > 0) {
@ -4183,7 +4183,7 @@ async function predict2(image17, config3, idx, count2) {
} }
skipped = 0; skipped = 0;
return new Promise(async (resolve) => { return new Promise(async (resolve) => {
const resize = tf6.image.resizeBilinear(image17, [model.inputs[0].shape[2], model.inputs[0].shape[1]], false); const resize = tf6.image.resizeBilinear(image18, [model.inputs[0].shape[2], model.inputs[0].shape[1]], false);
const [red, green, blue] = tf6.split(resize, 3, 3); const [red, green, blue] = tf6.split(resize, 3, 3);
resize.dispose(); resize.dispose();
const redNorm = tf6.mul(red, rgb[0]); const redNorm = tf6.mul(red, rgb[0]);
@ -4259,7 +4259,7 @@ function match(embedding, db, threshold = 0) {
return best; return best;
} }
function enhance(input) { function enhance(input) {
const image17 = tf7.tidy(() => { const image18 = tf7.tidy(() => {
const tensor2 = input.image || input.tensor || input; const tensor2 = input.image || input.tensor || input;
if (!(tensor2 instanceof tf7.Tensor)) if (!(tensor2 instanceof tf7.Tensor))
return null; return null;
@ -4270,9 +4270,9 @@ function enhance(input) {
const norm = crop.mul(255); const norm = crop.mul(255);
return norm; return norm;
}); });
return image17; return image18;
} }
async function predict3(image17, config3, idx, count2) { async function predict3(image18, config3, idx, count2) {
var _a, _b; var _a, _b;
if (!model2) if (!model2)
return null; return null;
@ -4282,7 +4282,7 @@ async function predict3(image17, config3, idx, count2) {
} }
skipped2 = 0; skipped2 = 0;
return new Promise(async (resolve) => { return new Promise(async (resolve) => {
const enhanced = enhance(image17); const enhanced = enhance(image18);
let resT; let resT;
const obj = { const obj = {
age: 0, age: 0,
@ -4812,10 +4812,10 @@ async function predict4(input, config3) {
const res = tf9.tidy(() => { const res = tf9.tidy(() => {
if (!model3.inputs[0].shape) if (!model3.inputs[0].shape)
return []; return [];
const resized = input.resizeBilinear([model3.inputs[0].shape[2], model3.inputs[0].shape[1]]); const resized = tf9.image.resizeBilinear(input, [model3.inputs[0].shape[2], model3.inputs[0].shape[1]]);
const normalized = resized.toFloat().div(127.5).sub(1); const normalized = resized.toFloat().div(127.5).sub(1);
const results = model3.execute(normalized, poseNetOutputs); const results = model3.execute(normalized, poseNetOutputs);
const results3d = results.map((y) => y.squeeze([0])); const results3d = results.map((y) => tf9.squeeze(y, [0]));
results3d[1] = results3d[1].sigmoid(); results3d[1] = results3d[1].sigmoid();
return results3d; return results3d;
}); });
@ -4860,16 +4860,16 @@ function getBoxCenter2(box6) {
box6.startPoint[1] + (box6.endPoint[1] - box6.startPoint[1]) / 2 box6.startPoint[1] + (box6.endPoint[1] - box6.startPoint[1]) / 2
]; ];
} }
function cutBoxFromImageAndResize2(box6, image17, cropSize) { function cutBoxFromImageAndResize2(box6, image18, cropSize) {
const h = image17.shape[1]; const h = image18.shape[1];
const w = image17.shape[2]; const w = image18.shape[2];
const boxes = [[ const boxes = [[
box6.startPoint[1] / h, box6.startPoint[1] / h,
box6.startPoint[0] / w, box6.startPoint[0] / w,
box6.endPoint[1] / h, box6.endPoint[1] / h,
box6.endPoint[0] / w box6.endPoint[0] / w
]]; ]];
return tf10.image.cropAndResize(image17, boxes, [0], cropSize); return tf10.image.cropAndResize(image18, boxes, [0], cropSize);
} }
function scaleBoxCoordinates2(box6, factor) { function scaleBoxCoordinates2(box6, factor) {
const startPoint = [box6.startPoint[0] * factor[0], box6.startPoint[1] * factor[1]]; const startPoint = [box6.startPoint[0] * factor[0], box6.startPoint[1] * factor[1]];
@ -7876,7 +7876,7 @@ var HandDetector = class {
} }
async getBoxes(input, config3) { async getBoxes(input, config3) {
const batched = this.model.predict(input); const batched = this.model.predict(input);
const predictions = batched.squeeze(); const predictions = tf11.squeeze(batched);
batched.dispose(); batched.dispose();
const scoresT = tf11.tidy(() => tf11.sigmoid(tf11.slice(predictions, [0, 0], [-1, 1])).squeeze()); const scoresT = tf11.tidy(() => tf11.sigmoid(tf11.slice(predictions, [0, 0], [-1, 1])).squeeze());
const scores = scoresT.dataSync(); const scores = scoresT.dataSync();
@ -7904,9 +7904,9 @@ var HandDetector = class {
async estimateHandBounds(input, config3) { async estimateHandBounds(input, config3) {
const inputHeight = input.shape[1]; const inputHeight = input.shape[1];
const inputWidth = input.shape[2]; const inputWidth = input.shape[2];
const image17 = tf11.tidy(() => input.resizeBilinear([this.inputSize, this.inputSize]).div(127.5).sub(1)); const image18 = tf11.tidy(() => input.resizeBilinear([this.inputSize, this.inputSize]).div(127.5).sub(1));
const predictions = await this.getBoxes(image17, config3); const predictions = await this.getBoxes(image18, config3);
image17.dispose(); image18.dispose();
const hands = []; const hands = [];
if (!predictions || predictions.length === 0) if (!predictions || predictions.length === 0)
return hands; return hands;
@ -8051,11 +8051,11 @@ var HandPipeline = class {
Math.trunc(coord[2]) Math.trunc(coord[2])
]); ]);
} }
async estimateHands(image17, config3) { async estimateHands(image18, config3) {
let useFreshBox = false; let useFreshBox = false;
let boxes; let boxes;
if (this.skipped === 0 || this.skipped > config3.hand.skipFrames || !config3.hand.landmarks || !config3.skipFrame) { if (this.skipped === 0 || this.skipped > config3.hand.skipFrames || !config3.hand.landmarks || !config3.skipFrame) {
boxes = await this.handDetector.estimateHandBounds(image17, config3); boxes = await this.handDetector.estimateHandBounds(image18, config3);
this.skipped = 0; this.skipped = 0;
} }
if (config3.skipFrame) if (config3.skipFrame)
@ -8074,8 +8074,8 @@ var HandPipeline = class {
if (config3.hand.landmarks) { if (config3.hand.landmarks) {
const angle = config3.hand.rotation ? computeRotation2(currentBox.palmLandmarks[palmLandmarksPalmBase], currentBox.palmLandmarks[palmLandmarksMiddleFingerBase]) : 0; const angle = config3.hand.rotation ? computeRotation2(currentBox.palmLandmarks[palmLandmarksPalmBase], currentBox.palmLandmarks[palmLandmarksMiddleFingerBase]) : 0;
const palmCenter = getBoxCenter2(currentBox); const palmCenter = getBoxCenter2(currentBox);
const palmCenterNormalized = [palmCenter[0] / image17.shape[2], palmCenter[1] / image17.shape[1]]; const palmCenterNormalized = [palmCenter[0] / image18.shape[2], palmCenter[1] / image18.shape[1]];
const rotatedImage = config3.hand.rotation && tf12.ENV.flags.IS_BROWSER ? tf12.image.rotateWithOffset(image17, angle, 0, palmCenterNormalized) : image17.clone(); const rotatedImage = config3.hand.rotation && tf12.ENV.flags.IS_BROWSER ? tf12.image.rotateWithOffset(image18, angle, 0, palmCenterNormalized) : image18.clone();
const rotationMatrix = buildRotationMatrix2(-angle, palmCenter); const rotationMatrix = buildRotationMatrix2(-angle, palmCenter);
const newBox = useFreshBox ? this.getBoxForPalmLandmarks(currentBox.palmLandmarks, rotationMatrix) : currentBox; const newBox = useFreshBox ? this.getBoxForPalmLandmarks(currentBox.palmLandmarks, rotationMatrix) : currentBox;
const croppedInput = cutBoxFromImageAndResize2(newBox, rotatedImage, [this.inputSize, this.inputSize]); const croppedInput = cutBoxFromImageAndResize2(newBox, rotatedImage, [this.inputSize, this.inputSize]);
@ -8299,14 +8299,14 @@ async function load7(config3) {
log("cached model:", model4["modelUrl"]); log("cached model:", model4["modelUrl"]);
return model4; return model4;
} }
async function predict6(image17, config3) { async function predict6(image18, config3) {
var _a; var _a;
if (!model4) if (!model4)
return []; return [];
if (!config3.body.enabled) if (!config3.body.enabled)
return []; return [];
const imgSize = { width: image17.shape[2] || 0, height: image17.shape[1] || 0 }; const imgSize = { width: image18.shape[2] || 0, height: image18.shape[1] || 0 };
const resize = tf14.image.resizeBilinear(image17, [model4["width"], model4["height"]], false); const resize = tf14.image.resizeBilinear(image18, [model4["width"], model4["height"]], false);
const normalize = tf14.div(resize, [255]); const normalize = tf14.div(resize, [255]);
resize.dispose(); resize.dispose();
const resT = await model4.predict(normalize); const resT = await model4.predict(normalize);
@ -8382,7 +8382,7 @@ function max2d(inputs, minScore) {
return [0, 0, newScore]; return [0, 0, newScore];
}); });
} }
async function predict7(image17, config3) { async function predict7(image18, config3) {
if (skipped3 < config3.body.skipFrames && config3.skipFrame && Object.keys(keypoints).length > 0) { if (skipped3 < config3.body.skipFrames && config3.skipFrame && Object.keys(keypoints).length > 0) {
skipped3++; skipped3++;
return [{ id: 0, score, box: box4, boxRaw, keypoints }]; return [{ id: 0, score, box: box4, boxRaw, keypoints }];
@ -8392,7 +8392,7 @@ async function predict7(image17, config3) {
const tensor2 = tf15.tidy(() => { const tensor2 = tf15.tidy(() => {
if (!model5.inputs[0].shape) if (!model5.inputs[0].shape)
return null; return null;
const resize = tf15.image.resizeBilinear(image17, [model5.inputs[0].shape[2], model5.inputs[0].shape[1]], false); const resize = tf15.image.resizeBilinear(image18, [model5.inputs[0].shape[2], model5.inputs[0].shape[1]], false);
const enhance2 = tf15.mul(resize, 2); const enhance2 = tf15.mul(resize, 2);
const norm = enhance2.sub(1); const norm = enhance2.sub(1);
return norm; return norm;
@ -8403,10 +8403,10 @@ async function predict7(image17, config3) {
tensor2.dispose(); tensor2.dispose();
if (resT) { if (resT) {
keypoints.length = 0; keypoints.length = 0;
const squeeze4 = resT.squeeze(); const squeeze7 = resT.squeeze();
tf15.dispose(resT); tf15.dispose(resT);
const stack2 = squeeze4.unstack(2); const stack2 = squeeze7.unstack(2);
tf15.dispose(squeeze4); tf15.dispose(squeeze7);
for (let id = 0; id < stack2.length; id++) { for (let id = 0; id < stack2.length; id++) {
const [x2, y2, partScore] = max2d(stack2[id], config3.body.minConfidence); const [x2, y2, partScore] = max2d(stack2[id], config3.body.minConfidence);
if (score > config3.body.minConfidence) { if (score > config3.body.minConfidence) {
@ -8418,8 +8418,8 @@ async function predict7(image17, config3) {
y2 / model5.inputs[0].shape[1] y2 / model5.inputs[0].shape[1]
], ],
position: [ position: [
Math.round(image17.shape[2] * x2 / model5.inputs[0].shape[2]), Math.round(image18.shape[2] * x2 / model5.inputs[0].shape[2]),
Math.round(image17.shape[1] * y2 / model5.inputs[0].shape[1]) Math.round(image18.shape[1] * y2 / model5.inputs[0].shape[1])
] ]
}); });
} }
@ -8467,7 +8467,7 @@ async function load9(config3) {
log("cached model:", model6["modelUrl"]); log("cached model:", model6["modelUrl"]);
return model6; return model6;
} }
async function predict8(image17, config3) { async function predict8(image18, config3) {
if (skipped4 < config3.body.skipFrames && config3.skipFrame && Object.keys(keypoints2).length > 0) { if (skipped4 < config3.body.skipFrames && config3.skipFrame && Object.keys(keypoints2).length > 0) {
skipped4++; skipped4++;
return [{ id: 0, score: score2, box: box5, boxRaw: boxRaw2, keypoints: keypoints2 }]; return [{ id: 0, score: score2, box: box5, boxRaw: boxRaw2, keypoints: keypoints2 }];
@ -8477,7 +8477,7 @@ async function predict8(image17, config3) {
const tensor2 = tf16.tidy(() => { const tensor2 = tf16.tidy(() => {
if (!model6.inputs[0].shape) if (!model6.inputs[0].shape)
return null; return null;
const resize = tf16.image.resizeBilinear(image17, [model6.inputs[0].shape[2], model6.inputs[0].shape[1]], false); const resize = tf16.image.resizeBilinear(image18, [model6.inputs[0].shape[2], model6.inputs[0].shape[1]], false);
const cast2 = tf16.cast(resize, "int32"); const cast2 = tf16.cast(resize, "int32");
return cast2; return cast2;
}); });
@ -8501,8 +8501,8 @@ async function predict8(image17, config3) {
kpt3[id][0] kpt3[id][0]
], ],
position: [ position: [
Math.round((image17.shape[2] || 0) * kpt3[id][1]), Math.round((image18.shape[2] || 0) * kpt3[id][1]),
Math.round((image17.shape[1] || 0) * kpt3[id][0]) Math.round((image18.shape[1] || 0) * kpt3[id][0])
] ]
}); });
} }
@ -8697,15 +8697,15 @@ async function process2(res, inputSize, outputShape, config3) {
results = results.filter((a, idx) => nmsIdx.includes(idx)).sort((a, b) => b.score - a.score); results = results.filter((a, idx) => nmsIdx.includes(idx)).sort((a, b) => b.score - a.score);
return results; return results;
} }
async function predict9(image17, config3) { async function predict9(image18, config3) {
if (skipped5 < config3.object.skipFrames && config3.skipFrame && last3.length > 0) { if (skipped5 < config3.object.skipFrames && config3.skipFrame && last3.length > 0) {
skipped5++; skipped5++;
return last3; return last3;
} }
skipped5 = 0; skipped5 = 0;
return new Promise(async (resolve) => { return new Promise(async (resolve) => {
const outputSize = [image17.shape[2], image17.shape[1]]; const outputSize = [image18.shape[2], image18.shape[1]];
const resize = tf17.image.resizeBilinear(image17, [model7.inputSize, model7.inputSize], false); const resize = tf17.image.resizeBilinear(image18, [model7.inputSize, model7.inputSize], false);
const norm = resize.div(255); const norm = resize.div(255);
const transpose = norm.transpose([0, 3, 1, 2]); const transpose = norm.transpose([0, 3, 1, 2]);
norm.dispose(); norm.dispose();
@ -9059,8 +9059,8 @@ function GLImageFilter(params) {
gl.uniform1f(_currentProgram.uniform.flipY, flipY ? -1 : 1); gl.uniform1f(_currentProgram.uniform.flipY, flipY ? -1 : 1);
gl.drawArrays(gl.TRIANGLES, 0, 6); gl.drawArrays(gl.TRIANGLES, 0, 6);
}; };
this.apply = function(image17) { this.apply = function(image18) {
_resize(image17.width, image17.height); _resize(image18.width, image18.height);
_drawCount = 0; _drawCount = 0;
if (!_sourceTexture) if (!_sourceTexture)
_sourceTexture = gl.createTexture(); _sourceTexture = gl.createTexture();
@ -9069,7 +9069,7 @@ function GLImageFilter(params) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image17); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image18);
if (_filterChain.length === 0) { if (_filterChain.length === 0) {
_draw(); _draw();
return _canvas; return _canvas;
@ -10444,10 +10444,10 @@ async function predict11(input, config3) {
const overlay = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(input.canvas.width, input.canvas.height) : document.createElement("canvas"); const overlay = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(input.canvas.width, input.canvas.height) : document.createElement("canvas");
overlay.width = input.canvas.width; overlay.width = input.canvas.width;
overlay.height = input.canvas.height; overlay.height = input.canvas.height;
const squeeze4 = tf20.squeeze(res, 0); const squeeze7 = tf20.squeeze(res, 0);
let resizeOutput; let resizeOutput;
if (squeeze4.shape[2] === 2) { if (squeeze7.shape[2] === 2) {
const softmax = squeeze4.softmax(); const softmax = squeeze7.softmax();
const [bg, fg] = tf20.unstack(softmax, 2); const [bg, fg] = tf20.unstack(softmax, 2);
const expand = fg.expandDims(2); const expand = fg.expandDims(2);
const pad = expand.expandDims(0); const pad = expand.expandDims(0);
@ -10460,12 +10460,12 @@ async function predict11(input, config3) {
tf20.dispose(expand); tf20.dispose(expand);
tf20.dispose(pad); tf20.dispose(pad);
} else { } else {
resizeOutput = tf20.image.resizeBilinear(squeeze4, [(_c = input.tensor) == null ? void 0 : _c.shape[1], (_d = input.tensor) == null ? void 0 : _d.shape[2]]); resizeOutput = tf20.image.resizeBilinear(squeeze7, [(_c = input.tensor) == null ? void 0 : _c.shape[1], (_d = input.tensor) == null ? void 0 : _d.shape[2]]);
} }
if (tf20.browser) if (tf20.browser)
await tf20.browser.toPixels(resizeOutput, overlay); await tf20.browser.toPixels(resizeOutput, overlay);
tf20.dispose(resizeOutput); tf20.dispose(resizeOutput);
tf20.dispose(squeeze4); tf20.dispose(squeeze7);
tf20.dispose(res); tf20.dispose(res);
const alphaCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(input.canvas.width, input.canvas.height) : document.createElement("canvas"); const alphaCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(input.canvas.width, input.canvas.height) : document.createElement("canvas");
alphaCanvas.width = input.canvas.width; alphaCanvas.width = input.canvas.width;

61102
dist/tfjs.esm.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,7 @@
"main": "dist/human.node.js", "main": "dist/human.node.js",
"module": "dist/human.esm.js", "module": "dist/human.esm.js",
"browser": "dist/human.esm.js", "browser": "dist/human.esm.js",
"types": "types/human.d.ts", "types": "types/src/human.d.ts",
"author": "Vladimir Mandic <mandic00@live.com>", "author": "Vladimir Mandic <mandic00@live.com>",
"bugs": { "bugs": {
"url": "https://github.com/vladmandic/human/issues" "url": "https://github.com/vladmandic/human/issues"

View File

@ -11,7 +11,8 @@ const esbuild = require('esbuild');
const TypeDoc = require('typedoc'); const TypeDoc = require('typedoc');
const { ESLint } = require('eslint'); const { ESLint } = require('eslint');
const tfjs = require('@tensorflow/tfjs/package.json'); const tfjs = require('@tensorflow/tfjs/package.json');
const changelog = require('./changelog'); const changelog = require('./changelog.js');
const tsconfig = require('../tsconfig.json');
let logFile = 'build.log'; let logFile = 'build.log';
@ -26,36 +27,11 @@ const banner = { js: `
*/ */
` }; ` };
// tsc configuration for building types only
const tsconfig = {
noEmitOnError: false,
target: ts.ScriptTarget.ES2018,
module: ts.ModuleKind.ES2020,
outDir: 'types',
declaration: true,
emitDeclarationOnly: true,
emitDecoratorMetadata: true,
experimentalDecorators: true,
skipLibCheck: true,
importHelpers: true,
noImplicitAny: false,
preserveConstEnums: true,
strictNullChecks: true,
baseUrl: './',
typeRoots: ['node_modules/@types'],
paths: {
tslib: ['node_modules/tslib/tslib.d.ts'],
'@tensorflow/tfjs-node/dist/io/file_system': ['node_modules/@tensorflow/tfjs-node/dist/io/file_system.js'],
'@tensorflow/tfjs-core/dist/index': ['node_modules/@tensorflow/tfjs-core/dist/index.js'],
'@tensorflow/tfjs-converter/dist/index': ['node_modules/@tensorflow/tfjs-converter/dist/index.js'],
},
};
// common configuration // common configuration
const lintLocations = ['server/', 'demo/', 'src/', 'test/']; const lintLocations = ['server/', 'demo/', 'src/', 'test/'];
const config = { const config = {
common: { build: {
banner, banner,
tsconfig: 'server/tfjs-tsconfig.json', tsconfig: 'server/tfjs-tsconfig.json',
logLevel: 'error', logLevel: 'error',
@ -73,6 +49,7 @@ const config = {
minifyIdentifiers: true, minifyIdentifiers: true,
minifySyntax: true, minifySyntax: true,
}, },
changelog: '../CHANGELOG.md',
}; };
const targets = { const targets = {
@ -230,9 +207,15 @@ async function getStats(json) {
} }
// rebuild typings // rebuild typings
async function typings(entryPoint, options) { async function typings(entryPoint) {
log.info('Generate types:', entryPoint); log.info('Generate Typings:', entryPoint, 'outDir:', [tsconfig.compilerOptions.outDir]);
const program = ts.createProgram(entryPoint, options); const tsoptions = { ...tsconfig.compilerOptions,
target: ts.ScriptTarget.ES2018,
module: ts.ModuleKind.ES2020,
moduleResolution: ts.ModuleResolutionKind.NodeJs,
};
const compilerHost = ts.createCompilerHost(tsoptions);
const program = ts.createProgram(entryPoint, tsoptions, compilerHost);
const emit = program.emit(); const emit = program.emit();
const diag = ts const diag = ts
.getPreEmitDiagnostics(program) .getPreEmitDiagnostics(program)
@ -250,7 +233,6 @@ async function typings(entryPoint, options) {
} }
async function typedoc(entryPoint) { async function typedoc(entryPoint) {
log.info('Generate TypeDocs:', entryPoint);
if (!td) { if (!td) {
td = new TypeDoc.Application(); td = new TypeDoc.Application();
td.options.addReader(new TypeDoc.TSConfigReader()); td.options.addReader(new TypeDoc.TSConfigReader());
@ -260,6 +242,7 @@ async function typedoc(entryPoint) {
td.logger.verbose = () => { /***/ }; td.logger.verbose = () => { /***/ };
td.logger.log = log.info; td.logger.log = log.info;
} }
log.info('Generate TypeDocs:', entryPoint, 'outDir:', [tsconfig.typedocOptions.out]);
const project = td.convert(); const project = td.convert();
if (!project) log.warn('TypeDoc: convert returned empty project'); if (!project) log.warn('TypeDoc: convert returned empty project');
if (td.logger.hasErrors() || td.logger.hasWarnings()) log.warn('TypeDoc:', 'errors:', td.logger.errorCount, 'warnings:', td.logger.warningCount); if (td.logger.hasErrors() || td.logger.hasWarnings()) log.warn('TypeDoc:', 'errors:', td.logger.errorCount, 'warnings:', td.logger.warningCount);
@ -299,19 +282,17 @@ async function build(f, msg, dev = false) {
for (const [targetName, targetOptions] of Object.entries(targetGroup)) { for (const [targetName, targetOptions] of Object.entries(targetGroup)) {
// if triggered from watch mode, rebuild only browser bundle // if triggered from watch mode, rebuild only browser bundle
// if ((require.main !== module) && ((targetGroupName === 'browserNoBundle') || (targetGroupName === 'nodeGPU'))) continue; // if ((require.main !== module) && ((targetGroupName === 'browserNoBundle') || (targetGroupName === 'nodeGPU'))) continue;
const meta = dev const opt = dev ? config.debug : config.production;
// @ts-ignore // eslint-typescript complains about string enums used in js code // @ts-ignore // eslint-typescript complains about string enums used in js code
? await esbuild.build({ ...config.common, ...config.debug, ...targetOptions }) const meta = await esbuild.build({ ...config.build, ...opt, ...targetOptions });
// @ts-ignore // eslint-typescript complains about string enums used in js code
: await esbuild.build({ ...config.common, ...config.production, ...targetOptions });
const stats = await getStats(meta); const stats = await getStats(meta);
log.state(`Build for: ${targetGroupName} type: ${targetName}:`, stats); log.state(` target: ${targetGroupName} type: ${targetName}:`, stats);
} }
} }
if (!dev) { // only for prod builds, skipped for dev build if (!dev) { // only for prod builds, skipped for dev build
await lint(); // run linter await lint(); // run linter
await typings(targets.browserBundle.esm.entryPoints, tsconfig); // generate typings await typings(targets.browserBundle.esm.entryPoints); // generate typings
await changelog.update('../CHANGELOG.md'); // generate changelog await changelog.update(config.changelog); // generate changelog
await typedoc(targets.browserBundle.esm.entryPoints); // generate typedoc await typedoc(targets.browserBundle.esm.entryPoints); // generate typedoc
} }
if (require.main === module) process.exit(0); if (require.main === module) process.exit(0);

View File

@ -1,21 +1,21 @@
2021-06-05 11:51:39 INFO:  @vladmandic/human version 2.0.0 2021-06-05 12:47:18 INFO:  @vladmandic/human version 2.0.0
2021-06-05 11:51:39 INFO:  User: vlado Platform: linux Arch: x64 Node: v16.0.0 2021-06-05 12:47:18 INFO:  User: vlado Platform: linux Arch: x64 Node: v16.0.0
2021-06-05 11:51:39 INFO:  Toolchain: tfjs: 3.7.0 esbuild 0.12.6; typescript 4.2.4; typedoc: 0.20.36 eslint: 7.27.0 2021-06-05 12:47:18 INFO:  Toolchain: tfjs: 3.7.0 esbuild 0.12.6; typescript 4.2.4; typedoc: 0.20.36 eslint: 7.27.0
2021-06-05 11:51:39 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true} 2021-06-05 12:47:18 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true}
2021-06-05 11:51:39 STATE: Build for: node type: tfjs: {"imports":1,"importBytes":102,"outputBytes":1292,"outputFiles":"dist/tfjs.esm.js"} 2021-06-05 12:47:18 STATE: target: node type: tfjs: {"imports":1,"importBytes":102,"outputBytes":1298,"outputFiles":"dist/tfjs.esm.js"}
2021-06-05 11:51:39 STATE: Build for: node type: node: {"imports":41,"importBytes":429821,"outputBytes":375853,"outputFiles":"dist/human.node.js"} 2021-06-05 12:47:18 STATE: target: node type: node: {"imports":41,"importBytes":429855,"outputBytes":375893,"outputFiles":"dist/human.node.js"}
2021-06-05 11:51:39 STATE: Build for: nodeGPU type: tfjs: {"imports":1,"importBytes":110,"outputBytes":1300,"outputFiles":"dist/tfjs.esm.js"} 2021-06-05 12:47:18 STATE: target: nodeGPU type: tfjs: {"imports":1,"importBytes":110,"outputBytes":1306,"outputFiles":"dist/tfjs.esm.js"}
2021-06-05 11:51:39 STATE: Build for: nodeGPU type: node: {"imports":41,"importBytes":429829,"outputBytes":375857,"outputFiles":"dist/human.node-gpu.js"} 2021-06-05 12:47:18 STATE: target: nodeGPU type: node: {"imports":41,"importBytes":429863,"outputBytes":375897,"outputFiles":"dist/human.node-gpu.js"}
2021-06-05 11:51:39 STATE: Build for: nodeWASM type: tfjs: {"imports":1,"importBytes":149,"outputBytes":1367,"outputFiles":"dist/tfjs.esm.js"} 2021-06-05 12:47:18 STATE: target: nodeWASM type: tfjs: {"imports":1,"importBytes":149,"outputBytes":1373,"outputFiles":"dist/tfjs.esm.js"}
2021-06-05 11:51:39 STATE: Build for: nodeWASM type: node: {"imports":41,"importBytes":429896,"outputBytes":375929,"outputFiles":"dist/human.node-wasm.js"} 2021-06-05 12:47:18 STATE: target: nodeWASM type: node: {"imports":41,"importBytes":429930,"outputBytes":375969,"outputFiles":"dist/human.node-wasm.js"}
2021-06-05 11:51:39 STATE: Build for: browserNoBundle type: tfjs: {"imports":1,"importBytes":2478,"outputBytes":1394,"outputFiles":"dist/tfjs.esm.js"} 2021-06-05 12:47:18 STATE: target: browserNoBundle type: tfjs: {"imports":1,"importBytes":2478,"outputBytes":1400,"outputFiles":"dist/tfjs.esm.js"}
2021-06-05 11:51:39 STATE: Build for: browserNoBundle type: esm: {"imports":41,"importBytes":429923,"outputBytes":247724,"outputFiles":"dist/human.esm-nobundle.js"} 2021-06-05 12:47:18 STATE: target: browserNoBundle type: esm: {"imports":41,"importBytes":429957,"outputBytes":247750,"outputFiles":"dist/human.esm-nobundle.js"}
2021-06-05 11:51:40 STATE: Build for: browserBundle type: tfjs: {"modules":1299,"moduleBytes":4230827,"imports":7,"importBytes":2478,"outputBytes":1140320,"outputFiles":"dist/tfjs.esm.js"} 2021-06-05 12:47:19 STATE: target: browserBundle type: tfjs: {"modules":1299,"moduleBytes":4230827,"imports":7,"importBytes":2478,"outputBytes":1140326,"outputFiles":"dist/tfjs.esm.js"}
2021-06-05 11:51:40 STATE: Build for: browserBundle type: iife: {"imports":41,"importBytes":1568849,"outputBytes":1383941,"outputFiles":"dist/human.js"} 2021-06-05 12:47:19 STATE: target: browserBundle type: iife: {"imports":41,"importBytes":1568883,"outputBytes":1383936,"outputFiles":"dist/human.js"}
2021-06-05 11:51:41 STATE: Build for: browserBundle type: esm: {"imports":41,"importBytes":1568849,"outputBytes":1383933,"outputFiles":"dist/human.esm.js"} 2021-06-05 12:47:20 STATE: target: browserBundle type: esm: {"imports":41,"importBytes":1568883,"outputBytes":1383928,"outputFiles":"dist/human.esm.js"}
2021-06-05 11:51:41 INFO:  Running Linter: ["server/","demo/","src/","test/"] 2021-06-05 12:47:20 INFO:  Running Linter: ["server/","demo/","src/","test/"]
2021-06-05 11:52:09 INFO:  Linter complete: files: 69 errors: 0 warnings: 0 2021-06-05 12:47:47 INFO:  Linter complete: files: 69 errors: 0 warnings: 0
2021-06-05 11:52:09 INFO:  Generate types: ["src/human.ts"] 2021-06-05 12:47:47 INFO:  Generate Typings: ["src/human.ts"] outDir: ["types"]
2021-06-05 11:52:13 INFO:  Update Change log: ["/home/vlado/dev/human/CHANGELOG.md"] 2021-06-05 12:48:06 INFO:  Generate ChangeLog: ["/home/vlado/dev/human/CHANGELOG.md"]
2021-06-05 11:52:13 INFO:  Generate TypeDocs: ["src/human.ts"] 2021-06-05 12:48:06 INFO:  Generate TypeDocs: ["src/human.ts"] outDir: ["typedoc"]
2021-06-05 11:52:32 INFO:  Documentation generated at /home/vlado/dev/human/typedoc 1 2021-06-05 12:48:22 INFO:  Documentation generated at /home/vlado/dev/human/typedoc 1

View File

@ -49,7 +49,7 @@ async function update(f) {
const name = path.join(__dirname, f); const name = path.join(__dirname, f);
fs.writeFileSync(name, text); fs.writeFileSync(name, text);
logger.info('Update Change log:', [name]); logger.info('Generate ChangeLog:', [name]);
} }
if (require.main === module) { if (require.main === module) {

View File

@ -42,7 +42,7 @@ export class BlazeFaceModel {
// @ts-ignore isDisposed is internal property // @ts-ignore isDisposed is internal property
if ((!inputImage) || (inputImage.isDisposedInternal) || (inputImage.shape.length !== 4) || (inputImage.shape[1] < 1) || (inputImage.shape[2] < 1)) return null; if ((!inputImage) || (inputImage.isDisposedInternal) || (inputImage.shape.length !== 4) || (inputImage.shape[1] < 1) || (inputImage.shape[2] < 1)) return null;
const [batch, boxes, scores] = tf.tidy(() => { const [batch, boxes, scores] = tf.tidy(() => {
const resizedImage = inputImage.resizeBilinear([this.inputSize, this.inputSize]); const resizedImage = tf.image.resizeBilinear(inputImage, [this.inputSize, this.inputSize]);
const normalizedImage = resizedImage.div(127.5).sub(0.5); const normalizedImage = resizedImage.div(127.5).sub(0.5);
const res = this.model.execute(normalizedImage); const res = this.model.execute(normalizedImage);
let batchOut; let batchOut;
@ -53,7 +53,7 @@ export class BlazeFaceModel {
const concat = tf.concat([concat512, concat384], 1); const concat = tf.concat([concat512, concat384], 1);
batchOut = concat.squeeze(0); batchOut = concat.squeeze(0);
} else { } else {
batchOut = res.squeeze(); // when using tfhub model batchOut = tf.squeeze(res); // when using tfhub model
} }
const boxesOut = decodeBounds(batchOut, this.anchors, [this.inputSize, this.inputSize]); const boxesOut = decodeBounds(batchOut, this.anchors, [this.inputSize, this.inputSize]);
const logits = tf.slice(batchOut, [0, 0], [-1, 1]); const logits = tf.slice(batchOut, [0, 0], [-1, 1]);

View File

@ -42,7 +42,7 @@ export class HandDetector {
async getBoxes(input, config) { async getBoxes(input, config) {
const batched = this.model.predict(input) as Tensor; const batched = this.model.predict(input) as Tensor;
const predictions = batched.squeeze(); const predictions = tf.squeeze(batched);
batched.dispose(); batched.dispose();
const scoresT = tf.tidy(() => tf.sigmoid(tf.slice(predictions, [0, 0], [-1, 1])).squeeze()); const scoresT = tf.tidy(() => tf.sigmoid(tf.slice(predictions, [0, 0], [-1, 1])).squeeze());
const scores = scoresT.dataSync(); const scores = scoresT.dataSync();

View File

@ -16,10 +16,10 @@ const poseNetOutputs = ['MobilenetV1/offset_2/BiasAdd'/* offsets */, 'MobilenetV
export async function predict(input: Tensor, config: Config): Promise<Body[]> { export async function predict(input: Tensor, config: Config): Promise<Body[]> {
const res = tf.tidy(() => { const res = tf.tidy(() => {
if (!model.inputs[0].shape) return []; if (!model.inputs[0].shape) return [];
const resized = input.resizeBilinear([model.inputs[0].shape[2], model.inputs[0].shape[1]]); const resized = tf.image.resizeBilinear(input, [model.inputs[0].shape[2], model.inputs[0].shape[1]]);
const normalized = resized.toFloat().div(127.5).sub(1.0); const normalized = resized.toFloat().div(127.5).sub(1.0);
const results: Array<Tensor> = model.execute(normalized, poseNetOutputs) as Array<Tensor>; const results: Array<Tensor> = model.execute(normalized, poseNetOutputs) as Array<Tensor>;
const results3d = results.map((y) => y.squeeze([0])); const results3d = results.map((y) => tf.squeeze(y, [0]));
results3d[1] = results3d[1].sigmoid(); // apply sigmoid on scores results3d[1] = results3d[1].sigmoid(); // apply sigmoid on scores
return results3d; return results3d;
}); });

View File

@ -4,7 +4,6 @@
"module": "es2020", "module": "es2020",
"target": "es2018", "target": "es2018",
"moduleResolution": "node", "moduleResolution": "node",
"lib": ["es2018", "dom"],
"typeRoots": ["node_modules/@types"], "typeRoots": ["node_modules/@types"],
"outDir": "types", "outDir": "types",
"declaration": true, "declaration": true,

2525
types/dist/tfjs.esm.d.ts vendored Normal file

File diff suppressed because one or more lines are too long

6
types/face.d.ts vendored
View File

@ -1,6 +0,0 @@
/**
* Module that analyzes person age
* Obsolete
*/
import { Face } from './result';
export declare const detectFace: (parent: any, input: any) => Promise<Face[]>;

View File

@ -13,7 +13,7 @@ export declare class BlazeFaceModel {
startPoint: Tensor; startPoint: Tensor;
endPoint: Tensor; endPoint: Tensor;
}; };
landmarks: any; landmarks: Tensor;
anchor: number[]; anchor: number[];
confidence: number; confidence: number;
}[]; }[];

7
types/src/face.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
/**
* Module that analyzes person age
* Obsolete
*/
import { Face } from './result';
import { Tensor } from './tfjs/types';
export declare const detectFace: (parent: any, input: Tensor) => Promise<Face[]>;

View File

@ -10,8 +10,8 @@ export declare class HandDetector {
normalizeBoxes(boxes: any): any; normalizeBoxes(boxes: any): any;
normalizeLandmarks(rawPalmLandmarks: any, index: any): any; normalizeLandmarks(rawPalmLandmarks: any, index: any): any;
getBoxes(input: any, config: any): Promise<{ getBoxes(input: any, config: any): Promise<{
box: any; box: Tensor;
palmLandmarks: any; palmLandmarks: Tensor;
confidence: number; confidence: number;
}[]>; }[]>;
estimateHandBounds(input: any, config: any): Promise<{ estimateHandBounds(input: any, config: any): Promise<{

7
types/src/image/imagefx.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
export function GLImageFilter(params: any): void;
export class GLImageFilter {
constructor(params: any);
addFilter: (name: any, ...args: any[]) => void;
reset: () => void;
apply: (image: any) => any;
}