add tfjs types and remove all instances of any

pull/134/head
Vladimir Mandic 2021-05-22 21:47:59 -04:00
parent 36e9c56746
commit a5da0b3b3b
54 changed files with 460 additions and 395 deletions

View File

@ -28,8 +28,6 @@
"rules": {
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-var-requires": "off",
"camelcase": "off",
"dot-notation": "off",

View File

@ -11,6 +11,7 @@ Repository: **<git+https://github.com/vladmandic/human.git>**
### **HEAD -> main** 2021/05/22 mandic00@live.com
- rebuild all for release
### **1.9.2** 2021/05/22 mandic00@live.com

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

70
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

70
dist/human.js vendored

File diff suppressed because one or more lines are too long

View File

@ -3949,7 +3949,7 @@ var Pipeline = class {
this.storedBoxes = [];
this.detectedFaces = 0;
for (const possible of detector.boxes) {
this.storedBoxes.push({ startPoint: possible.box.startPoint.dataSync(), endPoint: possible.box.endPoint.dataSync(), landmarks: possible.landmarks, confidence: possible.confidence });
this.storedBoxes.push({ startPoint: possible.box.startPoint.dataSync(), endPoint: possible.box.endPoint.dataSync(), landmarks: possible.landmarks.arraySync(), confidence: possible.confidence });
}
if (this.storedBoxes.length > 0)
useFreshBox = true;
@ -3964,7 +3964,7 @@ var Pipeline = class {
const scaledBox = scaleBoxCoordinates({ startPoint: this.storedBoxes[i].startPoint, endPoint: this.storedBoxes[i].endPoint }, detector.scaleFactor);
const enlargedBox = enlargeBox(scaledBox);
const squarifiedBox = squarifyBox(enlargedBox);
const landmarks = this.storedBoxes[i].landmarks.arraySync();
const landmarks = this.storedBoxes[i].landmarks;
const confidence = this.storedBoxes[i].confidence;
this.storedBoxes[i] = { ...squarifiedBox, confidence, landmarks };
}
@ -4125,21 +4125,24 @@ async function load2(config3) {
!faceModels[2] && config3.face.iris.enabled ? tf5.loadGraphModel(join(config3.modelBasePath, config3.face.iris.modelPath), { fromTFHub: config3.face.iris.modelPath.includes("tfhub.dev") }) : null
]);
if (config3.face.mesh.enabled) {
if (!faceModels[1] || !faceModels[1].modelUrl)
if (!faceModels[1] || !faceModels[1]["modelUrl"])
log("load model failed:", config3.face.mesh.modelPath);
else if (config3.debug)
log("load model:", faceModels[1].modelUrl);
log("load model:", faceModels[1]["modelUrl"]);
}
if (config3.face.iris.enabled) {
if (!faceModels[2] || !faceModels[1].modelUrl)
if (!faceModels[2] || !faceModels[2]["modelUrl"])
log("load model failed:", config3.face.iris.modelPath);
else if (config3.debug)
log("load model:", faceModels[2].modelUrl);
log("load model:", faceModels[2]["modelUrl"]);
}
} else if (config3.debug) {
log("cached model:", faceModels[0].model.modelUrl);
log("cached model:", faceModels[1].modelUrl);
log("cached model:", faceModels[2].modelUrl);
if (faceModels[0])
log("cached model:", faceModels[0].model["modelUrl"]);
if (faceModels[1])
log("cached model:", faceModels[1]["modelUrl"]);
if (faceModels[2])
log("cached model:", faceModels[2]["modelUrl"]);
}
facePipeline = new Pipeline(faceModels[0], faceModels[1], faceModels[2]);
return faceModels;
@ -4228,14 +4231,15 @@ var last2 = [];
var lastCount2 = 0;
var skipped2 = Number.MAX_SAFE_INTEGER;
async function load4(config3) {
const modelUrl = join(config3.modelBasePath, config3.face.description.modelPath);
if (!model2) {
model2 = await tf7.loadGraphModel(join(config3.modelBasePath, config3.face.description.modelPath));
if (!model2 || !model2.modelUrl)
model2 = await tf7.loadGraphModel(modelUrl);
if (!model2)
log("load model failed:", config3.face.description.modelPath);
else if (config3.debug)
log("load model:", model2.modelUrl);
log("load model:", modelUrl);
} else if (config3.debug)
log("cached model:", model2.modelUrl);
log("cached model:", modelUrl);
return model2;
}
function similarity(embedding1, embedding2, order = 2) {
@ -4268,6 +4272,8 @@ function enhance(input) {
if (!(tensor instanceof tf7.Tensor))
return null;
const box4 = [[0.05, 0.15, 0.85, 0.85]];
if (!model2.inputs[0].shape)
return null;
const crop = tensor.shape.length === 3 ? tf7.image.cropAndResize(tf7.expandDims(tensor, 0), box4, [0], [model2.inputs[0].shape[2], model2.inputs[0].shape[1]]) : tf7.image.cropAndResize(tensor, box4, [0], [model2.inputs[0].shape[2], model2.inputs[0].shape[1]]);
const norm = crop.mul(255);
return norm;
@ -4795,6 +4801,8 @@ var model3;
var poseNetOutputs = ["MobilenetV1/offset_2/BiasAdd", "MobilenetV1/heatmap_2/BiasAdd", "MobilenetV1/displacement_fwd_2/BiasAdd", "MobilenetV1/displacement_bwd_2/BiasAdd"];
async function predict4(input, config3) {
const res = tf8.tidy(() => {
if (!model3.inputs[0].shape)
return [];
const resized = input.resizeBilinear([model3.inputs[0].shape[2], model3.inputs[0].shape[1]]);
const normalized = resized.toFloat().div(127.5).sub(1);
const results = model3.execute(normalized, poseNetOutputs);
@ -4806,18 +4814,20 @@ async function predict4(input, config3) {
for (const t of res)
t.dispose();
const decoded = await decode(buffers[0], buffers[1], buffers[2], buffers[3], config3.body.maxDetected, config3.body.minConfidence);
if (!model3.inputs[0].shape)
return [];
const scaled = scalePoses(decoded, [input.shape[1], input.shape[2]], [model3.inputs[0].shape[2], model3.inputs[0].shape[1]]);
return scaled;
}
async function load5(config3) {
if (!model3) {
model3 = await tf8.loadGraphModel(join(config3.modelBasePath, config3.body.modelPath));
if (!model3 || !model3.modelUrl)
if (!model3 || !model3["modelUrl"])
log("load model failed:", config3.body.modelPath);
else if (config3.debug)
log("load model:", model3.modelUrl);
log("load model:", model3["modelUrl"]);
} else if (config3.debug)
log("cached model:", model3.modelUrl);
log("cached model:", model3["modelUrl"]);
return model3;
}
@ -16973,7 +16983,8 @@ async function predict5(input, config3) {
(predictions[i].box.bottomRight[0] - predictions[i].box.topLeft[0]) / input.shape[2],
(predictions[i].box.bottomRight[1] - predictions[i].box.topLeft[1]) / input.shape[1]
];
hands.push({ id: i, confidence: Math.round(100 * predictions[i].confidence) / 100, box: box4, boxRaw, landmarks: predictions[i].landmarks, annotations: annotations3 });
const landmarks = predictions[i].landmarks;
hands.push({ id: i, confidence: Math.round(100 * predictions[i].confidence) / 100, box: box4, boxRaw, landmarks, annotations: annotations3 });
}
return hands;
}
@ -16984,20 +16995,20 @@ async function load6(config3) {
config3.hand.landmarks ? tf12.loadGraphModel(join(config3.modelBasePath, config3.hand.skeleton.modelPath), { fromTFHub: config3.hand.skeleton.modelPath.includes("tfhub.dev") }) : null
]);
if (config3.hand.enabled) {
if (!handDetectorModel || !handDetectorModel.modelUrl)
if (!handDetectorModel || !handDetectorModel["modelUrl"])
log("load model failed:", config3.hand.detector.modelPath);
else if (config3.debug)
log("load model:", handDetectorModel.modelUrl);
if (!handPoseModel || !handPoseModel.modelUrl)
log("load model:", handDetectorModel["modelUrl"]);
if (!handPoseModel || !handPoseModel["modelUrl"])
log("load model failed:", config3.hand.skeleton.modelPath);
else if (config3.debug)
log("load model:", handPoseModel.modelUrl);
log("load model:", handPoseModel["modelUrl"]);
}
} else {
if (config3.debug)
log("cached model:", handDetectorModel.modelUrl);
log("cached model:", handDetectorModel["modelUrl"]);
if (config3.debug)
log("cached model:", handPoseModel.modelUrl);
log("cached model:", handPoseModel["modelUrl"]);
}
const handDetector = new HandDetector(handDetectorModel);
handPipeline = new HandPipeline(handDetector, handPoseModel);

View File

@ -3950,7 +3950,7 @@ var Pipeline = class {
this.storedBoxes = [];
this.detectedFaces = 0;
for (const possible of detector.boxes) {
this.storedBoxes.push({ startPoint: possible.box.startPoint.dataSync(), endPoint: possible.box.endPoint.dataSync(), landmarks: possible.landmarks, confidence: possible.confidence });
this.storedBoxes.push({ startPoint: possible.box.startPoint.dataSync(), endPoint: possible.box.endPoint.dataSync(), landmarks: possible.landmarks.arraySync(), confidence: possible.confidence });
}
if (this.storedBoxes.length > 0)
useFreshBox = true;
@ -3965,7 +3965,7 @@ var Pipeline = class {
const scaledBox = scaleBoxCoordinates({ startPoint: this.storedBoxes[i].startPoint, endPoint: this.storedBoxes[i].endPoint }, detector.scaleFactor);
const enlargedBox = enlargeBox(scaledBox);
const squarifiedBox = squarifyBox(enlargedBox);
const landmarks = this.storedBoxes[i].landmarks.arraySync();
const landmarks = this.storedBoxes[i].landmarks;
const confidence = this.storedBoxes[i].confidence;
this.storedBoxes[i] = { ...squarifiedBox, confidence, landmarks };
}
@ -4126,21 +4126,24 @@ async function load2(config3) {
!faceModels[2] && config3.face.iris.enabled ? tf5.loadGraphModel(join(config3.modelBasePath, config3.face.iris.modelPath), { fromTFHub: config3.face.iris.modelPath.includes("tfhub.dev") }) : null
]);
if (config3.face.mesh.enabled) {
if (!faceModels[1] || !faceModels[1].modelUrl)
if (!faceModels[1] || !faceModels[1]["modelUrl"])
log("load model failed:", config3.face.mesh.modelPath);
else if (config3.debug)
log("load model:", faceModels[1].modelUrl);
log("load model:", faceModels[1]["modelUrl"]);
}
if (config3.face.iris.enabled) {
if (!faceModels[2] || !faceModels[1].modelUrl)
if (!faceModels[2] || !faceModels[2]["modelUrl"])
log("load model failed:", config3.face.iris.modelPath);
else if (config3.debug)
log("load model:", faceModels[2].modelUrl);
log("load model:", faceModels[2]["modelUrl"]);
}
} else if (config3.debug) {
log("cached model:", faceModels[0].model.modelUrl);
log("cached model:", faceModels[1].modelUrl);
log("cached model:", faceModels[2].modelUrl);
if (faceModels[0])
log("cached model:", faceModels[0].model["modelUrl"]);
if (faceModels[1])
log("cached model:", faceModels[1]["modelUrl"]);
if (faceModels[2])
log("cached model:", faceModels[2]["modelUrl"]);
}
facePipeline = new Pipeline(faceModels[0], faceModels[1], faceModels[2]);
return faceModels;
@ -4229,14 +4232,15 @@ var last2 = [];
var lastCount2 = 0;
var skipped2 = Number.MAX_SAFE_INTEGER;
async function load4(config3) {
const modelUrl = join(config3.modelBasePath, config3.face.description.modelPath);
if (!model2) {
model2 = await tf7.loadGraphModel(join(config3.modelBasePath, config3.face.description.modelPath));
if (!model2 || !model2.modelUrl)
model2 = await tf7.loadGraphModel(modelUrl);
if (!model2)
log("load model failed:", config3.face.description.modelPath);
else if (config3.debug)
log("load model:", model2.modelUrl);
log("load model:", modelUrl);
} else if (config3.debug)
log("cached model:", model2.modelUrl);
log("cached model:", modelUrl);
return model2;
}
function similarity(embedding1, embedding2, order = 2) {
@ -4269,6 +4273,8 @@ function enhance(input) {
if (!(tensor instanceof tf7.Tensor))
return null;
const box4 = [[0.05, 0.15, 0.85, 0.85]];
if (!model2.inputs[0].shape)
return null;
const crop = tensor.shape.length === 3 ? tf7.image.cropAndResize(tf7.expandDims(tensor, 0), box4, [0], [model2.inputs[0].shape[2], model2.inputs[0].shape[1]]) : tf7.image.cropAndResize(tensor, box4, [0], [model2.inputs[0].shape[2], model2.inputs[0].shape[1]]);
const norm = crop.mul(255);
return norm;
@ -4796,6 +4802,8 @@ var model3;
var poseNetOutputs = ["MobilenetV1/offset_2/BiasAdd", "MobilenetV1/heatmap_2/BiasAdd", "MobilenetV1/displacement_fwd_2/BiasAdd", "MobilenetV1/displacement_bwd_2/BiasAdd"];
async function predict4(input, config3) {
const res = tf8.tidy(() => {
if (!model3.inputs[0].shape)
return [];
const resized = input.resizeBilinear([model3.inputs[0].shape[2], model3.inputs[0].shape[1]]);
const normalized = resized.toFloat().div(127.5).sub(1);
const results = model3.execute(normalized, poseNetOutputs);
@ -4807,18 +4815,20 @@ async function predict4(input, config3) {
for (const t of res)
t.dispose();
const decoded = await decode(buffers[0], buffers[1], buffers[2], buffers[3], config3.body.maxDetected, config3.body.minConfidence);
if (!model3.inputs[0].shape)
return [];
const scaled = scalePoses(decoded, [input.shape[1], input.shape[2]], [model3.inputs[0].shape[2], model3.inputs[0].shape[1]]);
return scaled;
}
async function load5(config3) {
if (!model3) {
model3 = await tf8.loadGraphModel(join(config3.modelBasePath, config3.body.modelPath));
if (!model3 || !model3.modelUrl)
if (!model3 || !model3["modelUrl"])
log("load model failed:", config3.body.modelPath);
else if (config3.debug)
log("load model:", model3.modelUrl);
log("load model:", model3["modelUrl"]);
} else if (config3.debug)
log("cached model:", model3.modelUrl);
log("cached model:", model3["modelUrl"]);
return model3;
}
@ -16974,7 +16984,8 @@ async function predict5(input, config3) {
(predictions[i].box.bottomRight[0] - predictions[i].box.topLeft[0]) / input.shape[2],
(predictions[i].box.bottomRight[1] - predictions[i].box.topLeft[1]) / input.shape[1]
];
hands.push({ id: i, confidence: Math.round(100 * predictions[i].confidence) / 100, box: box4, boxRaw, landmarks: predictions[i].landmarks, annotations: annotations3 });
const landmarks = predictions[i].landmarks;
hands.push({ id: i, confidence: Math.round(100 * predictions[i].confidence) / 100, box: box4, boxRaw, landmarks, annotations: annotations3 });
}
return hands;
}
@ -16985,20 +16996,20 @@ async function load6(config3) {
config3.hand.landmarks ? tf12.loadGraphModel(join(config3.modelBasePath, config3.hand.skeleton.modelPath), { fromTFHub: config3.hand.skeleton.modelPath.includes("tfhub.dev") }) : null
]);
if (config3.hand.enabled) {
if (!handDetectorModel || !handDetectorModel.modelUrl)
if (!handDetectorModel || !handDetectorModel["modelUrl"])
log("load model failed:", config3.hand.detector.modelPath);
else if (config3.debug)
log("load model:", handDetectorModel.modelUrl);
if (!handPoseModel || !handPoseModel.modelUrl)
log("load model:", handDetectorModel["modelUrl"]);
if (!handPoseModel || !handPoseModel["modelUrl"])
log("load model failed:", config3.hand.skeleton.modelPath);
else if (config3.debug)
log("load model:", handPoseModel.modelUrl);
log("load model:", handPoseModel["modelUrl"]);
}
} else {
if (config3.debug)
log("cached model:", handDetectorModel.modelUrl);
log("cached model:", handDetectorModel["modelUrl"]);
if (config3.debug)
log("cached model:", handPoseModel.modelUrl);
log("cached model:", handPoseModel["modelUrl"]);
}
const handDetector = new HandDetector(handDetectorModel);
handPipeline = new HandPipeline(handDetector, handPoseModel);

57
dist/human.node.js vendored
View File

@ -3949,7 +3949,7 @@ var Pipeline = class {
this.storedBoxes = [];
this.detectedFaces = 0;
for (const possible of detector.boxes) {
this.storedBoxes.push({ startPoint: possible.box.startPoint.dataSync(), endPoint: possible.box.endPoint.dataSync(), landmarks: possible.landmarks, confidence: possible.confidence });
this.storedBoxes.push({ startPoint: possible.box.startPoint.dataSync(), endPoint: possible.box.endPoint.dataSync(), landmarks: possible.landmarks.arraySync(), confidence: possible.confidence });
}
if (this.storedBoxes.length > 0)
useFreshBox = true;
@ -3964,7 +3964,7 @@ var Pipeline = class {
const scaledBox = scaleBoxCoordinates({ startPoint: this.storedBoxes[i].startPoint, endPoint: this.storedBoxes[i].endPoint }, detector.scaleFactor);
const enlargedBox = enlargeBox(scaledBox);
const squarifiedBox = squarifyBox(enlargedBox);
const landmarks = this.storedBoxes[i].landmarks.arraySync();
const landmarks = this.storedBoxes[i].landmarks;
const confidence = this.storedBoxes[i].confidence;
this.storedBoxes[i] = { ...squarifiedBox, confidence, landmarks };
}
@ -4125,21 +4125,24 @@ async function load2(config3) {
!faceModels[2] && config3.face.iris.enabled ? tf5.loadGraphModel(join(config3.modelBasePath, config3.face.iris.modelPath), { fromTFHub: config3.face.iris.modelPath.includes("tfhub.dev") }) : null
]);
if (config3.face.mesh.enabled) {
if (!faceModels[1] || !faceModels[1].modelUrl)
if (!faceModels[1] || !faceModels[1]["modelUrl"])
log("load model failed:", config3.face.mesh.modelPath);
else if (config3.debug)
log("load model:", faceModels[1].modelUrl);
log("load model:", faceModels[1]["modelUrl"]);
}
if (config3.face.iris.enabled) {
if (!faceModels[2] || !faceModels[1].modelUrl)
if (!faceModels[2] || !faceModels[2]["modelUrl"])
log("load model failed:", config3.face.iris.modelPath);
else if (config3.debug)
log("load model:", faceModels[2].modelUrl);
log("load model:", faceModels[2]["modelUrl"]);
}
} else if (config3.debug) {
log("cached model:", faceModels[0].model.modelUrl);
log("cached model:", faceModels[1].modelUrl);
log("cached model:", faceModels[2].modelUrl);
if (faceModels[0])
log("cached model:", faceModels[0].model["modelUrl"]);
if (faceModels[1])
log("cached model:", faceModels[1]["modelUrl"]);
if (faceModels[2])
log("cached model:", faceModels[2]["modelUrl"]);
}
facePipeline = new Pipeline(faceModels[0], faceModels[1], faceModels[2]);
return faceModels;
@ -4228,14 +4231,15 @@ var last2 = [];
var lastCount2 = 0;
var skipped2 = Number.MAX_SAFE_INTEGER;
async function load4(config3) {
const modelUrl = join(config3.modelBasePath, config3.face.description.modelPath);
if (!model2) {
model2 = await tf7.loadGraphModel(join(config3.modelBasePath, config3.face.description.modelPath));
if (!model2 || !model2.modelUrl)
model2 = await tf7.loadGraphModel(modelUrl);
if (!model2)
log("load model failed:", config3.face.description.modelPath);
else if (config3.debug)
log("load model:", model2.modelUrl);
log("load model:", modelUrl);
} else if (config3.debug)
log("cached model:", model2.modelUrl);
log("cached model:", modelUrl);
return model2;
}
function similarity(embedding1, embedding2, order = 2) {
@ -4268,6 +4272,8 @@ function enhance(input) {
if (!(tensor instanceof tf7.Tensor))
return null;
const box4 = [[0.05, 0.15, 0.85, 0.85]];
if (!model2.inputs[0].shape)
return null;
const crop = tensor.shape.length === 3 ? tf7.image.cropAndResize(tf7.expandDims(tensor, 0), box4, [0], [model2.inputs[0].shape[2], model2.inputs[0].shape[1]]) : tf7.image.cropAndResize(tensor, box4, [0], [model2.inputs[0].shape[2], model2.inputs[0].shape[1]]);
const norm = crop.mul(255);
return norm;
@ -4795,6 +4801,8 @@ var model3;
var poseNetOutputs = ["MobilenetV1/offset_2/BiasAdd", "MobilenetV1/heatmap_2/BiasAdd", "MobilenetV1/displacement_fwd_2/BiasAdd", "MobilenetV1/displacement_bwd_2/BiasAdd"];
async function predict4(input, config3) {
const res = tf8.tidy(() => {
if (!model3.inputs[0].shape)
return [];
const resized = input.resizeBilinear([model3.inputs[0].shape[2], model3.inputs[0].shape[1]]);
const normalized = resized.toFloat().div(127.5).sub(1);
const results = model3.execute(normalized, poseNetOutputs);
@ -4806,18 +4814,20 @@ async function predict4(input, config3) {
for (const t of res)
t.dispose();
const decoded = await decode(buffers[0], buffers[1], buffers[2], buffers[3], config3.body.maxDetected, config3.body.minConfidence);
if (!model3.inputs[0].shape)
return [];
const scaled = scalePoses(decoded, [input.shape[1], input.shape[2]], [model3.inputs[0].shape[2], model3.inputs[0].shape[1]]);
return scaled;
}
async function load5(config3) {
if (!model3) {
model3 = await tf8.loadGraphModel(join(config3.modelBasePath, config3.body.modelPath));
if (!model3 || !model3.modelUrl)
if (!model3 || !model3["modelUrl"])
log("load model failed:", config3.body.modelPath);
else if (config3.debug)
log("load model:", model3.modelUrl);
log("load model:", model3["modelUrl"]);
} else if (config3.debug)
log("cached model:", model3.modelUrl);
log("cached model:", model3["modelUrl"]);
return model3;
}
@ -16973,7 +16983,8 @@ async function predict5(input, config3) {
(predictions[i].box.bottomRight[0] - predictions[i].box.topLeft[0]) / input.shape[2],
(predictions[i].box.bottomRight[1] - predictions[i].box.topLeft[1]) / input.shape[1]
];
hands.push({ id: i, confidence: Math.round(100 * predictions[i].confidence) / 100, box: box4, boxRaw, landmarks: predictions[i].landmarks, annotations: annotations3 });
const landmarks = predictions[i].landmarks;
hands.push({ id: i, confidence: Math.round(100 * predictions[i].confidence) / 100, box: box4, boxRaw, landmarks, annotations: annotations3 });
}
return hands;
}
@ -16984,20 +16995,20 @@ async function load6(config3) {
config3.hand.landmarks ? tf12.loadGraphModel(join(config3.modelBasePath, config3.hand.skeleton.modelPath), { fromTFHub: config3.hand.skeleton.modelPath.includes("tfhub.dev") }) : null
]);
if (config3.hand.enabled) {
if (!handDetectorModel || !handDetectorModel.modelUrl)
if (!handDetectorModel || !handDetectorModel["modelUrl"])
log("load model failed:", config3.hand.detector.modelPath);
else if (config3.debug)
log("load model:", handDetectorModel.modelUrl);
if (!handPoseModel || !handPoseModel.modelUrl)
log("load model:", handDetectorModel["modelUrl"]);
if (!handPoseModel || !handPoseModel["modelUrl"])
log("load model failed:", config3.hand.skeleton.modelPath);
else if (config3.debug)
log("load model:", handPoseModel.modelUrl);
log("load model:", handPoseModel["modelUrl"]);
}
} else {
if (config3.debug)
log("cached model:", handDetectorModel.modelUrl);
log("cached model:", handDetectorModel["modelUrl"]);
if (config3.debug)
log("cached model:", handPoseModel.modelUrl);
log("cached model:", handPoseModel["modelUrl"]);
}
const handDetector = new HandDetector(handDetectorModel);
handPipeline = new HandPipeline(handDetector, handPoseModel);

View File

@ -69,9 +69,9 @@
"chokidar": "^3.5.1",
"dayjs": "^1.10.4",
"esbuild": "^0.12.1",
"eslint": "^7.26.0",
"eslint": "^7.27.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.23.2",
"eslint-plugin-import": "^2.23.3",
"eslint-plugin-json": "^3.0.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",

View File

@ -35,6 +35,8 @@ const tsconfig = {
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'],
},
};

View File

@ -32,3 +32,40 @@
2021-05-22 14:53:18 INFO:  Generate types: ["src/human.ts"]
2021-05-22 14:53:22 INFO:  Update Change log: ["/home/vlado/dev/human/CHANGELOG.md"]
2021-05-22 14:53:22 INFO:  Generate TypeDocs: ["src/human.ts"]
2021-05-22 21:43:32 INFO:  @vladmandic/human version 1.9.2
2021-05-22 21:43:32 INFO:  User: vlado Platform: linux Arch: x64 Node: v16.0.0
2021-05-22 21:43:32 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true}
2021-05-22 21:43:32 STATE: Build for: node type: tfjs: {"imports":1,"importBytes":39,"outputBytes":1292,"outputFiles":"dist/tfjs.esm.js"}
2021-05-22 21:43:32 STATE: Build for: node type: node: {"imports":36,"importBytes":420766,"outputBytes":378274,"outputFiles":"dist/human.node.js"}
2021-05-22 21:43:32 STATE: Build for: nodeGPU type: tfjs: {"imports":1,"importBytes":43,"outputBytes":1300,"outputFiles":"dist/tfjs.esm.js"}
2021-05-22 21:43:32 STATE: Build for: nodeGPU type: node: {"imports":36,"importBytes":420774,"outputBytes":378278,"outputFiles":"dist/human.node-gpu.js"}
2021-05-22 21:43:32 STATE: Build for: nodeWASM type: tfjs: {"imports":1,"importBytes":81,"outputBytes":1367,"outputFiles":"dist/tfjs.esm.js"}
2021-05-22 21:43:32 STATE: Build for: nodeWASM type: node: {"imports":36,"importBytes":420841,"outputBytes":378350,"outputFiles":"dist/human.node-wasm.js"}
2021-05-22 21:43:32 STATE: Build for: browserNoBundle type: tfjs: {"imports":1,"importBytes":2488,"outputBytes":1394,"outputFiles":"dist/tfjs.esm.js"}
2021-05-22 21:43:32 STATE: Build for: browserNoBundle type: esm: {"imports":36,"importBytes":420868,"outputBytes":232338,"outputFiles":"dist/human.esm-nobundle.js"}
2021-05-22 21:43:33 STATE: Build for: browserBundle type: tfjs: {"modules":1274,"moduleBytes":4114813,"imports":7,"importBytes":2488,"outputBytes":1111414,"outputFiles":"dist/tfjs.esm.js"}
2021-05-22 21:43:33 STATE: Build for: browserBundle type: iife: {"imports":36,"importBytes":1530888,"outputBytes":1340202,"outputFiles":"dist/human.js"}
2021-05-22 21:43:34 STATE: Build for: browserBundle type: esm: {"imports":36,"importBytes":1530888,"outputBytes":1340194,"outputFiles":"dist/human.esm.js"}
2021-05-22 21:43:34 INFO:  Generate types: ["src/human.ts"]
2021-05-22 21:43:39 ERROR: TSC: /home/vlado/dev/human/src/posenet/poses.ts [130,50]: Object is of type 'unknown'.
2021-05-22 21:43:39 ERROR: TSC: /home/vlado/dev/human/src/posenet/poses.ts [131,46]: Object is of type 'unknown'.
2021-05-22 21:43:39 ERROR: TSC: /home/vlado/dev/human/src/tfjs/types.ts [2,24]: Cannot find module '@tensorflow/tfjs-core/dist/index.js'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?
2021-05-22 21:43:39 ERROR: TSC: /home/vlado/dev/human/src/tfjs/types.ts [3,28]: Cannot find module '@tensorflow/tfjs-converter/dist/index.js'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?
2021-05-22 21:43:39 INFO:  Update Change log: ["/home/vlado/dev/human/CHANGELOG.md"]
2021-05-22 21:47:04 INFO:  @vladmandic/human version 1.9.2
2021-05-22 21:47:04 INFO:  User: vlado Platform: linux Arch: x64 Node: v16.0.0
2021-05-22 21:47:04 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true}
2021-05-22 21:47:04 STATE: Build for: node type: tfjs: {"imports":1,"importBytes":39,"outputBytes":1292,"outputFiles":"dist/tfjs.esm.js"}
2021-05-22 21:47:04 STATE: Build for: node type: node: {"imports":36,"importBytes":420846,"outputBytes":378274,"outputFiles":"dist/human.node.js"}
2021-05-22 21:47:04 STATE: Build for: nodeGPU type: tfjs: {"imports":1,"importBytes":43,"outputBytes":1300,"outputFiles":"dist/tfjs.esm.js"}
2021-05-22 21:47:04 STATE: Build for: nodeGPU type: node: {"imports":36,"importBytes":420854,"outputBytes":378278,"outputFiles":"dist/human.node-gpu.js"}
2021-05-22 21:47:04 STATE: Build for: nodeWASM type: tfjs: {"imports":1,"importBytes":81,"outputBytes":1367,"outputFiles":"dist/tfjs.esm.js"}
2021-05-22 21:47:04 STATE: Build for: nodeWASM type: node: {"imports":36,"importBytes":420921,"outputBytes":378350,"outputFiles":"dist/human.node-wasm.js"}
2021-05-22 21:47:04 STATE: Build for: browserNoBundle type: tfjs: {"imports":1,"importBytes":2488,"outputBytes":1394,"outputFiles":"dist/tfjs.esm.js"}
2021-05-22 21:47:04 STATE: Build for: browserNoBundle type: esm: {"imports":36,"importBytes":420948,"outputBytes":232338,"outputFiles":"dist/human.esm-nobundle.js"}
2021-05-22 21:47:05 STATE: Build for: browserBundle type: tfjs: {"modules":1274,"moduleBytes":4114813,"imports":7,"importBytes":2488,"outputBytes":1111414,"outputFiles":"dist/tfjs.esm.js"}
2021-05-22 21:47:05 STATE: Build for: browserBundle type: iife: {"imports":36,"importBytes":1530968,"outputBytes":1340202,"outputFiles":"dist/human.js"}
2021-05-22 21:47:06 STATE: Build for: browserBundle type: esm: {"imports":36,"importBytes":1530968,"outputBytes":1340194,"outputFiles":"dist/human.esm.js"}
2021-05-22 21:47:06 INFO:  Generate types: ["src/human.ts"]
2021-05-22 21:47:11 INFO:  Update Change log: ["/home/vlado/dev/human/CHANGELOG.md"]
2021-05-22 21:47:11 INFO:  Generate TypeDocs: ["src/human.ts"]

View File

@ -3,6 +3,7 @@ import * as tf from '../../dist/tfjs.esm.js';
import * as box from './box';
import * as util from './util';
import { Config } from '../config';
import { Tensor, GraphModel } from '../tfjs/types';
const keypointsCount = 6;
@ -22,9 +23,9 @@ function decodeBounds(boxOutputs, anchors, inputSize) {
}
export class BlazeFaceModel {
model: any; // tf.GraphModel
model: GraphModel;
anchorsData: [number, number][];
anchors: typeof tf.Tensor;
anchors: Tensor;
inputSize: number;
config: Config;
@ -61,7 +62,7 @@ export class BlazeFaceModel {
const nmsTensor = await tf.image.nonMaxSuppressionAsync(boxes, scores, this.config.face.detector.maxDetected, this.config.face.detector.iouThreshold, this.config.face.detector.minConfidence);
const nms = nmsTensor.arraySync();
nmsTensor.dispose();
const annotatedBoxes: Array<{ box: { startPoint: typeof tf.Tensor, endPoint: typeof tf.Tensor }, landmarks: typeof tf.Tensor, anchor: number[], confidence: number }> = [];
const annotatedBoxes: Array<{ box: { startPoint: Tensor, endPoint: Tensor }, landmarks: Tensor, anchor: number[], confidence: number }> = [];
for (let i = 0; i < nms.length; i++) {
const confidence = scores[nms[i]];
if (confidence > this.config.face.detector.minConfidence) {

View File

@ -3,8 +3,9 @@ import * as tf from '../../dist/tfjs.esm.js';
import * as blazeface from './blazeface';
import * as facepipeline from './facepipeline';
import * as coords from './coords';
import { GraphModel } from '../tfjs/types';
let faceModels:[any, any, any] = [null, null, null];
let faceModels: [blazeface.BlazeFaceModel | null, GraphModel | null, GraphModel | null] = [null, null, null];
let facePipeline;
export async function predict(input, config): Promise<{ confidence, boxConfidence, faceConfidence, box, mesh, boxRaw, meshRaw, annotations, image }[]> {
@ -49,25 +50,26 @@ export async function predict(input, config): Promise<{ confidence, boxConfidenc
return results;
}
export async function load(config): Promise<[Object, Object, Object]> {
export async function load(config): Promise<[unknown, unknown, unknown]> {
if ((!faceModels[0] && config.face.enabled) || (!faceModels[1] && config.face.mesh.enabled) || (!faceModels[2] && config.face.iris.enabled)) {
// @ts-ignore type mismatch for GraphModel
faceModels = await Promise.all([
(!faceModels[0] && config.face.enabled) ? blazeface.load(config) : null,
(!faceModels[1] && config.face.mesh.enabled) ? tf.loadGraphModel(join(config.modelBasePath, config.face.mesh.modelPath), { fromTFHub: config.face.mesh.modelPath.includes('tfhub.dev') }) : null,
(!faceModels[2] && config.face.iris.enabled) ? tf.loadGraphModel(join(config.modelBasePath, config.face.iris.modelPath), { fromTFHub: config.face.iris.modelPath.includes('tfhub.dev') }) : null,
]);
if (config.face.mesh.enabled) {
if (!faceModels[1] || !faceModels[1].modelUrl) log('load model failed:', config.face.mesh.modelPath);
else if (config.debug) log('load model:', faceModels[1].modelUrl);
if (!faceModels[1] || !faceModels[1]['modelUrl']) log('load model failed:', config.face.mesh.modelPath);
else if (config.debug) log('load model:', faceModels[1]['modelUrl']);
}
if (config.face.iris.enabled) {
if (!faceModels[2] || !faceModels[1].modelUrl) log('load model failed:', config.face.iris.modelPath);
else if (config.debug) log('load model:', faceModels[2].modelUrl);
if (!faceModels[2] || !faceModels[2]['modelUrl']) log('load model failed:', config.face.iris.modelPath);
else if (config.debug) log('load model:', faceModels[2]['modelUrl']);
}
} else if (config.debug) {
log('cached model:', faceModels[0].model.modelUrl);
log('cached model:', faceModels[1].modelUrl);
log('cached model:', faceModels[2].modelUrl);
if (faceModels[0]) log('cached model:', faceModels[0].model['modelUrl']);
if (faceModels[1]) log('cached model:', faceModels[1]['modelUrl']);
if (faceModels[2]) log('cached model:', faceModels[2]['modelUrl']);
}
facePipeline = new facepipeline.Pipeline(faceModels[0], faceModels[1], faceModels[2]);
return faceModels;

View File

@ -2,6 +2,8 @@ import * as tf from '../../dist/tfjs.esm.js';
import * as bounding from './box';
import * as util from './util';
import * as coords from './coords';
import { Tensor, GraphModel } from '../tfjs/types';
import { BlazeFaceModel } from './blazeface';
const leftOutline = coords.MESH_ANNOTATIONS['leftEyeLower0'];
const rightOutline = coords.MESH_ANNOTATIONS['rightEyeLower0'];
@ -53,10 +55,10 @@ function replaceRawCoordinates(rawCoords, newCoords, prefix, keys) {
}
// The Pipeline coordinates between the bounding box and skeleton models.
export class Pipeline {
storedBoxes: Array<{ startPoint: number[], endPoint: number[], landmarks: any, confidence: number, faceConfidence?: number }>; // landmarks is tensor
boundingBoxDetector: any; // tf.GraphModel
meshDetector: any; // tf.GraphModel
irisModel: any; // tf.GraphModel
storedBoxes: Array<{ startPoint: number[], endPoint: number[], landmarks: Array<number>, confidence: number, faceConfidence?: number }>;
boundingBoxDetector: BlazeFaceModel; // tf.GraphModel
meshDetector: GraphModel; // tf.GraphModel
irisModel: GraphModel; // tf.GraphModel
boxSize: number;
meshSize: number;
irisSize: number;
@ -166,7 +168,7 @@ export class Pipeline {
this.storedBoxes = [];
this.detectedFaces = 0;
for (const possible of detector.boxes) {
this.storedBoxes.push({ startPoint: possible.box.startPoint.dataSync(), endPoint: possible.box.endPoint.dataSync(), landmarks: possible.landmarks, confidence: possible.confidence });
this.storedBoxes.push({ startPoint: possible.box.startPoint.dataSync(), endPoint: possible.box.endPoint.dataSync(), landmarks: possible.landmarks.arraySync(), confidence: possible.confidence });
}
if (this.storedBoxes.length > 0) useFreshBox = true;
}
@ -181,7 +183,7 @@ export class Pipeline {
const scaledBox = bounding.scaleBoxCoordinates({ startPoint: this.storedBoxes[i].startPoint, endPoint: this.storedBoxes[i].endPoint }, detector.scaleFactor);
const enlargedBox = bounding.enlargeBox(scaledBox);
const squarifiedBox = bounding.squarifyBox(enlargedBox);
const landmarks = this.storedBoxes[i].landmarks.arraySync();
const landmarks = this.storedBoxes[i].landmarks;
const confidence = this.storedBoxes[i].confidence;
this.storedBoxes[i] = { ...squarifiedBox, confidence, landmarks };
}
@ -228,7 +230,7 @@ export class Pipeline {
return prediction;
}
const [, confidence, contourCoords] = this.meshDetector.execute(face); // The first returned tensor represents facial contours which are already included in the coordinates.
const [, confidence, contourCoords] = this.meshDetector.execute(face) as Array<Tensor>; // The first returned tensor represents facial contours which are already included in the coordinates.
const faceConfidence = confidence.dataSync()[0] as number;
if (faceConfidence < config.face.detector.minConfidence) {
this.storedBoxes[i].confidence = faceConfidence; // reset confidence of cached box
@ -240,7 +242,7 @@ export class Pipeline {
if (config.face.iris.enabled) {
const { box: leftEyeBox, boxSize: leftEyeBoxSize, crop: leftEyeCrop } = this.getEyeBox(rawCoords, face, eyeLandmarks.leftBounds[0], eyeLandmarks.leftBounds[1], true);
const { box: rightEyeBox, boxSize: rightEyeBoxSize, crop: rightEyeCrop } = this.getEyeBox(rawCoords, face, eyeLandmarks.rightBounds[0], eyeLandmarks.rightBounds[1]);
const eyePredictions = this.irisModel.predict(tf.concat([leftEyeCrop, rightEyeCrop]));
const eyePredictions = this.irisModel.predict(tf.concat([leftEyeCrop, rightEyeCrop])) as Tensor;
const eyePredictionsData = eyePredictions.dataSync();
const leftEyeData = eyePredictionsData.slice(0, irisLandmarks.numCoordinates * 3);
const { rawCoords: leftEyeRawCoords, iris: leftIrisRawCoords } = this.getEyeCoords(leftEyeData, leftEyeBox, leftEyeBoxSize, true);

View File

@ -32,16 +32,16 @@ export interface DrawOptions {
lineWidth: number,
pointSize: number,
roundRect: number,
drawPoints: Boolean,
drawLabels: Boolean,
drawBoxes: Boolean,
drawPolygons: Boolean,
fillPolygons: Boolean,
useDepth: Boolean,
useCurves: Boolean,
bufferedOutput: Boolean,
useRawBoxes: Boolean,
calculateHandBox: Boolean,
drawPoints: boolean,
drawLabels: boolean,
drawBoxes: boolean,
drawPolygons: boolean,
fillPolygons: boolean,
useDepth: boolean,
useCurves: boolean,
bufferedOutput: boolean,
useRawBoxes: boolean,
calculateHandBox: boolean,
}
export const options: DrawOptions = {
@ -53,16 +53,16 @@ export const options: DrawOptions = {
lineWidth: <number>6,
pointSize: <number>2,
roundRect: <number>28,
drawPoints: <Boolean>false,
drawLabels: <Boolean>true,
drawBoxes: <Boolean>true,
drawPolygons: <Boolean>true,
fillPolygons: <Boolean>false,
useDepth: <Boolean>true,
useCurves: <Boolean>false,
bufferedOutput: <Boolean>false, // not yet implemented
useRawBoxes: <Boolean>false,
calculateHandBox: <Boolean>true,
drawPoints: <boolean>false,
drawLabels: <boolean>true,
drawBoxes: <boolean>true,
drawPolygons: <boolean>true,
fillPolygons: <boolean>false,
useDepth: <boolean>true,
useCurves: <boolean>false,
bufferedOutput: <boolean>false, // not yet implemented
useRawBoxes: <boolean>false,
calculateHandBox: <boolean>true,
};
let bufferedResult: Result;
@ -143,11 +143,11 @@ export async function gesture(inCanvas: HTMLCanvasElement, result: Array<Gesture
ctx.fillStyle = localOptions.color;
let i = 1;
for (let j = 0; j < result.length; j++) {
let where: any[] = []; // what&where is a record
let what: any[] = []; // what&where is a record
let where: unknown[] = []; // what&where is a record
let what: unknown[] = []; // what&where is a record
[where, what] = Object.entries(result[j]);
if ((what.length > 1) && (what[1].length > 0)) {
const person = where[1] > 0 ? `#${where[1]}` : '';
if ((what.length > 1) && ((what[1] as string).length > 0)) {
const person = where[1] as number > 0 ? `#${where[1]}` : '';
const label = `${where[0]} ${person}: ${what[1]}`;
if (localOptions.shadowColor && localOptions.shadowColor !== '') {
ctx.fillStyle = localOptions.shadowColor;

View File

@ -1,8 +1,9 @@
import { log, join } from '../helpers';
import * as tf from '../../dist/tfjs.esm.js';
import { Body } from '../result';
import { GraphModel } from '../tfjs/types';
let model;
let model: GraphModel;
type Keypoints = { score: number, part: string, position: { x: number, y: number }, positionRaw: { x: number, y: number } };
@ -13,10 +14,11 @@ const bodyParts = ['head', 'neck', 'rightShoulder', 'rightElbow', 'rightWrist',
export async function load(config) {
if (!model) {
// @ts-ignore type mismatch on GraphModel
model = await tf.loadGraphModel(join(config.modelBasePath, config.body.modelPath));
if (!model || !model.modelUrl) log('load model failed:', config.body.modelPath);
else if (config.debug) log('load model:', model.modelUrl);
} else if (config.debug) log('cached model:', model.modelUrl);
if (!model || !model['modelUrl']) log('load model failed:', config.body.modelPath);
else if (config.debug) log('load model:', model['modelUrl']);
} else if (config.debug) log('cached model:', model['modelUrl']);
return model;
}
@ -50,6 +52,7 @@ export async function predict(image, config): Promise<Body[]> {
skipped = 0;
return new Promise(async (resolve) => {
const tensor = tf.tidy(() => {
if (!model.inputs[0].shape) return null;
const resize = tf.image.resizeBilinear(image, [model.inputs[0].shape[2], model.inputs[0].shape[1]], false);
const enhance = tf.mul(resize, 2);
const norm = enhance.sub(1);
@ -75,13 +78,13 @@ export async function predict(image, config): Promise<Body[]> {
parts.push({
score: Math.round(100 * score) / 100,
part: bodyParts[id],
positionRaw: {
x: x / model.inputs[0].shape[2], // x normalized to 0..1
y: y / model.inputs[0].shape[1], // y normalized to 0..1
positionRaw: { // normalized to 0..1
// @ts-ignore model is not undefined here
x: x / model.inputs[0].shape[2], y: y / model.inputs[0].shape[1],
},
position: {
x: Math.round(image.shape[2] * x / model.inputs[0].shape[2]), // x normalized to input image size
y: Math.round(image.shape[1] * y / model.inputs[0].shape[1]), // y normalized to input image size
position: { // normalized to input image size
// @ts-ignore model is not undefined here
x: Math.round(image.shape[2] * x / model.inputs[0].shape[2]), y: Math.round(image.shape[1] * y / model.inputs[0].shape[1]),
},
});
}

View File

@ -1,16 +1,18 @@
import { log, join } from '../helpers';
import * as tf from '../../dist/tfjs.esm.js';
import { Tensor, GraphModel } from '../tfjs/types';
type Tensor = typeof tf.Tensor;
type DB = Array<{ name: string, source: string, embedding: number[] }>;
let model;
let model: GraphModel;
export async function load(config) {
const modelUrl = join(config.modelBasePath, config.face.embedding.modelPath);
if (!model) {
model = await tf.loadGraphModel(join(config.modelBasePath, config.face.embedding.modelPath));
if (!model || !model.modelUrl) log('load model failed:', config.face.embedding.modelPath);
else if (config.debug) log('load model:', model.modelUrl);
} else if (config.debug) log('cached model:', model.modelUrl);
// @ts-ignore type mismatch for GraphModel
model = await tf.loadGraphModel(modelUrl);
if (!model) log('load model failed:', config.face.embedding.modelPath);
else if (config.debug) log('load model:', modelUrl);
} else if (config.debug) log('cached model:', modelUrl);
return model;
}
@ -49,7 +51,9 @@ export function enhance(input): Tensor {
const tensor = input.image || input.tensor;
if (!(tensor instanceof tf.Tensor)) return null;
const crop = (tensor.shape.length === 3)
// @ts-ignore model possibly undefined
? tf.image.cropAndResize(tf.expandDims(tensor, 0), box, [0], [model.inputs[0].shape[2], model.inputs[0].shape[1]]) // add batch dimension if missing
// @ts-ignore model possibly undefined
: tf.image.cropAndResize(tensor, box, [0], [model.inputs[0].shape[2], model.inputs[0].shape[1]]);
// convert to black&white to avoid colorization impact
@ -113,7 +117,7 @@ export async function predict(input, config): Promise<number[]> {
*/
// optional reduce feature vector complexity
const reshape = res.reshape([128, 2]); // split 256 vectors into 128 x 2
const reshape = tf.reshape(res, [128, 2]); // split 256 vectors into 128 x 2
const reduce = reshape.logSumExp(1); // reduce 2nd dimension by calculating logSumExp on it
const output: Array<number> = reduce.dataSync();

View File

@ -1,20 +1,22 @@
import { log, join } from '../helpers';
import * as tf from '../../dist/tfjs.esm.js';
import { Tensor, GraphModel } from '../tfjs/types';
let model;
let model: GraphModel;
const last: Array<{ age: number}> = [];
let lastCount = 0;
let skipped = Number.MAX_SAFE_INTEGER;
type Tensor = typeof tf.Tensor;
type DB = Array<{ name: string, source: string, embedding: number[] }>;
export async function load(config) {
const modelUrl = join(config.modelBasePath, config.face.description.modelPath);
if (!model) {
model = await tf.loadGraphModel(join(config.modelBasePath, config.face.description.modelPath));
if (!model || !model.modelUrl) log('load model failed:', config.face.description.modelPath);
else if (config.debug) log('load model:', model.modelUrl);
} else if (config.debug) log('cached model:', model.modelUrl);
// @ts-ignore type mismatch for GraphModel
model = await tf.loadGraphModel(modelUrl);
if (!model) log('load model failed:', config.face.description.modelPath);
else if (config.debug) log('load model:', modelUrl);
} else if (config.debug) log('cached model:', modelUrl);
return model;
}
@ -52,6 +54,7 @@ export function enhance(input): Tensor {
// do a tight crop of image and resize it to fit the model
const box = [[0.05, 0.15, 0.85, 0.85]]; // empyrical values for top, left, bottom, right
// const box = [[0.0, 0.0, 1.0, 1.0]]; // basically no crop for test
if (!model.inputs[0].shape) return null; // model has no shape so no point continuing
const crop = (tensor.shape.length === 3)
? tf.image.cropAndResize(tf.expandDims(tensor, 0), box, [0], [model.inputs[0].shape[2], model.inputs[0].shape[1]]) // add batch dimension if missing
: tf.image.cropAndResize(tensor, box, [0], [model.inputs[0].shape[2], model.inputs[0].shape[1]]);

View File

@ -1,9 +1,10 @@
import * as tf from '../../dist/tfjs.esm.js';
import * as box from './box';
import * as anchors from './anchors';
import { Tensor, GraphModel } from '../tfjs/types';
export class HandDetector {
model: any; // tf.GraphModel
model: GraphModel;
anchors: number[][];
anchorsTensor: typeof tf.Tensor;
inputSize: number;
@ -14,6 +15,7 @@ export class HandDetector {
this.model = model;
this.anchors = anchors.anchors.map((anchor) => [anchor.x, anchor.y]);
this.anchorsTensor = tf.tensor2d(this.anchors);
// @ts-ignore model is not undefined here
this.inputSize = this.model?.inputs[0].shape[2];
this.inputSizeTensor = tf.tensor1d([this.inputSize, this.inputSize]);
this.doubleInputSizeTensor = tf.tensor1d([this.inputSize * 2, this.inputSize * 2]);
@ -39,7 +41,7 @@ export class HandDetector {
}
async getBoxes(input, config) {
const batched = this.model.predict(input);
const batched = this.model.predict(input) as Tensor;
const predictions = batched.squeeze();
batched.dispose();
const scoresT = tf.tidy(() => tf.sigmoid(tf.slice(predictions, [0, 0], [-1, 1])).squeeze());
@ -52,7 +54,7 @@ export class HandDetector {
scoresT.dispose();
filteredT.dispose();
const hands: Array<{ box: any, palmLandmarks: any, confidence: number }> = []; // box and lardmarks are tensors here
const hands: Array<{ box: Tensor, palmLandmarks: Tensor, confidence: number }> = [];
for (const index of filtered) {
if (scores[index] >= config.hand.minConfidence) {
const matchingBox = tf.slice(boxes, [index, 0], [1, -1]);

View File

@ -2,6 +2,7 @@ import * as tf from '../../dist/tfjs.esm.js';
import * as box from './box';
import * as util from './util';
import * as detector from './handdetector';
import { Tensor, GraphModel } from '../tfjs/types';
const palmBoxEnlargeFactor = 5; // default 3
const handBoxEnlargeFactor = 1.65; // default 1.65
@ -11,7 +12,7 @@ const palmLandmarksMiddleFingerBase = 2;
export class HandPipeline {
handDetector: detector.HandDetector;
handPoseModel: any; // tf.GraphModel
handPoseModel: GraphModel;
inputSize: number;
storedBoxes: Array<{ startPoint: number[]; endPoint: number[]; palmLandmarks: number[]; confidence: number } | null>;
skipped: number;
@ -20,6 +21,7 @@ export class HandPipeline {
constructor(handDetector, handPoseModel) {
this.handDetector = handDetector;
this.handPoseModel = handPoseModel;
// @ts-ignore model is not undefined here
this.inputSize = this.handPoseModel?.inputs[0].shape[2];
this.storedBoxes = [];
this.skipped = 0;
@ -96,7 +98,7 @@ export class HandPipeline {
// for (const possible of boxes) this.storedBoxes.push(possible);
if (this.storedBoxes.length > 0) useFreshBox = true;
}
const hands: Array<{}> = [];
const hands: Array<{ landmarks?: number[], confidence: number, box: { topLeft: number[], bottomRight: number[] } }> = [];
// go through working set of boxes
for (let i = 0; i < this.storedBoxes.length; i++) {
@ -113,7 +115,7 @@ export class HandPipeline {
const handImage = croppedInput.div(255);
croppedInput.dispose();
rotatedImage.dispose();
const [confidenceT, keypoints] = await this.handPoseModel.predict(handImage);
const [confidenceT, keypoints] = await this.handPoseModel.predict(handImage) as Array<Tensor>;
handImage.dispose();
const confidence = confidenceT.dataSync()[0];
confidenceT.dispose();

View File

@ -3,6 +3,7 @@ import * as tf from '../../dist/tfjs.esm.js';
import * as handdetector from './handdetector';
import * as handpipeline from './handpipeline';
import { Hand } from '../result';
import { GraphModel } from '../tfjs/types';
const meshAnnotations = {
thumb: [1, 2, 3, 4],
@ -13,9 +14,9 @@ const meshAnnotations = {
palmBase: [0],
};
let handDetectorModel;
let handPoseModel;
let handPipeline;
let handDetectorModel: GraphModel | null;
let handPoseModel: GraphModel | null;
let handPipeline: handpipeline.HandPipeline;
export async function predict(input, config): Promise<Hand[]> {
const predictions = await handPipeline.estimateHands(input, config);
@ -25,6 +26,7 @@ export async function predict(input, config): Promise<Hand[]> {
const annotations = {};
if (predictions[i].landmarks) {
for (const key of Object.keys(meshAnnotations)) {
// @ts-ignore landmarks are not undefined
annotations[key] = meshAnnotations[key].map((index) => predictions[i].landmarks[index]);
}
}
@ -40,26 +42,28 @@ export async function predict(input, config): Promise<Hand[]> {
(predictions[i].box.bottomRight[0] - predictions[i].box.topLeft[0]) / input.shape[2],
(predictions[i].box.bottomRight[1] - predictions[i].box.topLeft[1]) / input.shape[1],
];
hands.push({ id: i, confidence: Math.round(100 * predictions[i].confidence) / 100, box, boxRaw, landmarks: predictions[i].landmarks, annotations });
const landmarks = predictions[i].landmarks as number[];
hands.push({ id: i, confidence: Math.round(100 * predictions[i].confidence) / 100, box, boxRaw, landmarks, annotations });
}
return hands;
}
export async function load(config): Promise<[Object, Object]> {
export async function load(config): Promise<[unknown, unknown]> {
if (!handDetectorModel || !handPoseModel) {
// @ts-ignore type mismatch on GraphModel
[handDetectorModel, handPoseModel] = await Promise.all([
config.hand.enabled ? tf.loadGraphModel(join(config.modelBasePath, config.hand.detector.modelPath), { fromTFHub: config.hand.detector.modelPath.includes('tfhub.dev') }) : null,
config.hand.landmarks ? tf.loadGraphModel(join(config.modelBasePath, config.hand.skeleton.modelPath), { fromTFHub: config.hand.skeleton.modelPath.includes('tfhub.dev') }) : null,
]);
if (config.hand.enabled) {
if (!handDetectorModel || !handDetectorModel.modelUrl) log('load model failed:', config.hand.detector.modelPath);
else if (config.debug) log('load model:', handDetectorModel.modelUrl);
if (!handPoseModel || !handPoseModel.modelUrl) log('load model failed:', config.hand.skeleton.modelPath);
else if (config.debug) log('load model:', handPoseModel.modelUrl);
if (!handDetectorModel || !handDetectorModel['modelUrl']) log('load model failed:', config.hand.detector.modelPath);
else if (config.debug) log('load model:', handDetectorModel['modelUrl']);
if (!handPoseModel || !handPoseModel['modelUrl']) log('load model failed:', config.hand.skeleton.modelPath);
else if (config.debug) log('load model:', handPoseModel['modelUrl']);
}
} else {
if (config.debug) log('cached model:', handDetectorModel.modelUrl);
if (config.debug) log('cached model:', handPoseModel.modelUrl);
if (config.debug) log('cached model:', handDetectorModel['modelUrl']);
if (config.debug) log('cached model:', handPoseModel['modelUrl']);
}
const handDetector = new handdetector.HandDetector(handDetectorModel);
handPipeline = new handpipeline.HandPipeline(handDetector, handPoseModel);

View File

@ -18,9 +18,7 @@ import * as image from './image/image';
import * as draw from './draw/draw';
import * as sample from './sample';
import * as app from '../package.json';
/** Generic Tensor object type */
export type Tensor = typeof tf.Tensor;
import { Tensor } from './tfjs/types';
export type { Config } from './config';
export type { Result, Face, Hand, Body, Item, Gesture } from './result';
@ -36,7 +34,7 @@ export type Error = { error: string };
export type TensorFlow = typeof tf;
/** Generic Model object type, holds instance of individual models */
type Model = Object;
type Model = unknown;
/**
* **Human** library main class
@ -114,7 +112,7 @@ export class Human {
/** Platform and agent information detected by Human */
sysinfo: { platform: string, agent: string };
/** Performance object that contains values for all recently performed operations */
perf: any; // perf members are dynamically defined as needed
perf: Record<string, unknown>; // perf members are dynamically defined as needed
#numTensors: number;
#analyzeMemoryLeaks: boolean;
#checkSanity: boolean;
@ -128,7 +126,7 @@ export class Human {
* Creates instance of Human library that is futher used for all operations
* - @param userConfig: {@link Config}
*/
constructor(userConfig: Config | Object = {}) {
constructor(userConfig: Config | Record<string, unknown> = {}) {
this.tf = tf;
this.draw = draw;
this.version = app.version;
@ -215,6 +213,7 @@ export class Human {
*/
// eslint-disable-next-line class-methods-use-this
enhance(input: Tensor): Tensor | null {
// @ts-ignore type mismach for Tensor
return faceres.enhance(input);
}
@ -233,7 +232,7 @@ export class Human {
/** Load method preloads all configured models on-demand
* - Not explicitly required as any required model is load implicitly on it's first run
*/
async load(userConfig: Config | Object = {}) {
async load(userConfig: Config | Record<string, unknown> = {}) {
this.state = 'load';
const timeStamp = now();
if (userConfig) this.config = mergeDeep(this.config, userConfig);
@ -287,7 +286,7 @@ export class Human {
}
const current = Math.trunc(now() - timeStamp);
if (current > (this.perf.load || 0)) this.perf.load = current;
if (current > (this.perf.load as number || 0)) this.perf.load = current;
}
// check if backend needs initialization if it changed
@ -385,7 +384,7 @@ export class Human {
* - Run inference for all configured models
* - Process and return result: {@link Result}
*/
async detect(input: Input, userConfig: Config | Object = {}): Promise<Result | Error> {
async detect(input: Input, userConfig: Config | Record<string, unknown> = {}): Promise<Result | Error> {
// detection happens inside a promise
return new Promise(async (resolve) => {
this.state = 'config';
@ -442,7 +441,7 @@ export class Human {
this.config.skipFrame = await this.#skipFrame(process.tensor);
if (!this.perf.frames) this.perf.frames = 0;
if (!this.perf.cached) this.perf.cached = 0;
this.perf.frames++;
(this.perf.frames as number)++;
// @ts-ignore hidden dynamic property that is not part of definitions
if (this.config.skipFrame) this.perf.cached++;
this.perf.changed = Math.trunc(now() - timeStamp);
@ -629,7 +628,7 @@ export class Human {
* - can take significant time on startup
* - only used for `webgl` and `humangl` backends
*/
async warmup(userConfig: Config | Object = {}): Promise<Result | { error }> {
async warmup(userConfig: Config | Record<string, unknown> = {}): Promise<Result | { error }> {
const t0 = now();
if (userConfig) this.config = mergeDeep(this.config, userConfig);
if (!this.config.warmup || this.config.warmup === 'none') return { error: 'null' };

View File

@ -3,15 +3,17 @@ import * as tf from '../../dist/tfjs.esm.js';
import * as poses from './poses';
import * as util from './utils';
import { Body } from '../result';
import { Tensor, GraphModel } from '../tfjs/types';
let model;
let model: GraphModel;
const poseNetOutputs = ['MobilenetV1/offset_2/BiasAdd'/* offsets */, 'MobilenetV1/heatmap_2/BiasAdd'/* heatmapScores */, 'MobilenetV1/displacement_fwd_2/BiasAdd'/* displacementFwd */, 'MobilenetV1/displacement_bwd_2/BiasAdd'/* displacementBwd */];
export async function predict(input, config): Promise<Body[]> {
const res = tf.tidy(() => {
if (!model.inputs[0].shape) return [];
const resized = input.resizeBilinear([model.inputs[0].shape[2], model.inputs[0].shape[1]]);
const normalized = resized.toFloat().div(127.5).sub(1.0);
const results = model.execute(normalized, poseNetOutputs);
const results: Array<Tensor> = model.execute(normalized, poseNetOutputs) as Array<Tensor>;
const results3d = results.map((y) => y.squeeze([0]));
results3d[1] = results3d[1].sigmoid(); // apply sigmoid on scores
return results3d;
@ -21,15 +23,17 @@ export async function predict(input, config): Promise<Body[]> {
for (const t of res) t.dispose();
const decoded = await poses.decode(buffers[0], buffers[1], buffers[2], buffers[3], config.body.maxDetected, config.body.minConfidence);
if (!model.inputs[0].shape) return [];
const scaled = util.scalePoses(decoded, [input.shape[1], input.shape[2]], [model.inputs[0].shape[2], model.inputs[0].shape[1]]) as Body[];
return scaled;
}
export async function load(config) {
if (!model) {
// @ts-ignore type mismatch for GraphModel
model = await tf.loadGraphModel(join(config.modelBasePath, config.body.modelPath));
if (!model || !model.modelUrl) log('load model failed:', config.body.modelPath);
else if (config.debug) log('load model:', model.modelUrl);
} else if (config.debug) log('cached model:', model.modelUrl);
if (!model || !model['modelUrl']) log('load model failed:', config.body.modelPath);
else if (config.debug) log('load model:', model['modelUrl']);
} else if (config.debug) log('cached model:', model['modelUrl']);
return model;
}

View File

@ -127,7 +127,9 @@ export function decode(offsets, scores, displacementsFwd, displacementsBwd, maxD
// The top element in the queue is the next root candidate.
const root = queue.dequeue();
// Part-based non-maximum suppression: We reject a root candidate if it is within a disk of `nmsRadius` pixels from the corresponding part of a previously detected instance.
// @ts-ignore this one is tree walk
const rootImageCoords = utils.getImageCoords(root.part, outputStride, offsets);
// @ts-ignore this one is tree walk
if (withinRadius(poses, rootImageCoords, root.part.id)) continue;
// Else start a new detection instance at the position of the root.
let keypoints = decodePose(root, scores, offsets, displacementsFwd, displacementsBwd);

View File

@ -49,9 +49,9 @@ export function scalePoses(poses, [height, width], [inputResolutionHeight, input
// algorithm based on Coursera Lecture from Algorithms, Part 1: https://www.coursera.org/learn/algorithms-part1/lecture/ZjoSM/heapsort
export class MaxHeap {
priorityQueue: Array<any>; // don't touch
priorityQueue: Array<unknown>; // don't touch
numberOfElements: number;
getElementValue: any; // function call
getElementValue: unknown; // function call
constructor(maxSize, getElementValue) {
this.priorityQueue = new Array(maxSize);
@ -98,6 +98,7 @@ export class MaxHeap {
}
getValueAt(i) {
// @ts-ignore getter is of unknown type
return this.getElementValue(this.priorityQueue[i]);
}

View File

@ -2,16 +2,19 @@ import { log } from './helpers';
export const data = {};
export function run(modelName: string, profileData: any): void { // profileData is tfjs internal type
export function run(modelName: string, profileData: Record<string, unknown>): void { // profileData is tfjs internal type
if (!profileData || !profileData.kernels) return;
const maxDetected = 5;
// @ts-ignore profileData.kernels is tfjs internal type
const time = profileData.kernels
.filter((a) => a.kernelTimeMs > 0)
.reduce((a, b) => a += b.kernelTimeMs, 0);
// @ts-ignore profileData.kernels is tfjs internal type
const slowest = profileData.kernels
.map((a, i) => { a.id = i; return a; })
.filter((a) => a.kernelTimeMs > 0)
.sort((a, b) => b.kernelTimeMs - a.kernelTimeMs);
// @ts-ignore profileData.kernels is tfjs internal type
const largest = profileData.kernels
.map((a, i) => { a.id = i; return a; })
.filter((a) => a.totalBytesSnapshot > 0)
@ -23,7 +26,7 @@ export function run(modelName: string, profileData: any): void { // profileData
newBytes: profileData.newBytes,
newTensors: profileData.newTensors,
peakBytes: profileData.peakBytes,
numKernelOps: profileData.kernels.length,
numKernelOps: (profileData['kernels'] as Array<unknown>).length,
timeKernelOps: time,
slowestKernelOps: slowest,
largestKernelOps: largest,

View File

@ -99,9 +99,7 @@ export interface Hand {
confidence: number,
box: [number, number, number, number],
boxRaw: [number, number, number, number],
landmarks: Array<[number, number, number]>,
// annotations: Array<{ part: string, points: Array<[number, number, number]> }>,
// annotations: Annotations,
landmarks: number[],
annotations: Record<string, Array<{ part: string, points: Array<[number, number, number]> }>>,
}
@ -151,7 +149,7 @@ export interface Result {
gesture: Array<Gesture>,
/** {@link Object}: detection & analysis results */
object: Array<Item>
performance: { any },
performance: Record<string, unknown>,
canvas: OffscreenCanvas | HTMLCanvasElement,
timestamp: number,
}

View File

@ -5,7 +5,7 @@ export const config = {
name: 'humangl',
priority: 99,
canvas: <null | OffscreenCanvas | HTMLCanvasElement>null,
gl: <any>null,
gl: <unknown>null,
width: 1024,
height: 1024,
webGLattr: { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.2

3
src/tfjs/types.ts Normal file
View File

@ -0,0 +1,3 @@
// export common types
export { Tensor } from '@tensorflow/tfjs-core/dist/index';
export { GraphModel } from '@tensorflow/tfjs-converter/dist/index';

File diff suppressed because one or more lines are too long

View File

@ -131,7 +131,7 @@
<a name="constructor" class="tsd-anchor"></a>
<h3>constructor</h3>
<ul class="tsd-signatures tsd-kind-constructor tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon">new <wbr>Human<span class="tsd-signature-symbol">(</span>userConfig<span class="tsd-signature-symbol">?: </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol"> | </span><a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="human.html" class="tsd-signature-type" data-tsd-kind="Class">Human</a></li>
<li class="tsd-signature tsd-kind-icon">new <wbr>Human<span class="tsd-signature-symbol">(</span>userConfig<span class="tsd-signature-symbol">?: </span><a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="human.html" class="tsd-signature-type" data-tsd-kind="Class">Human</a></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
@ -148,7 +148,7 @@
<h4 class="tsd-parameters-title">Parameters</h4>
<ul class="tsd-parameters">
<li>
<h5>userConfig: <span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol"> | </span><a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol"> = {}</span></h5>
<h5>userConfig: <a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol"> = {}</span></h5>
</li>
</ul>
<h4 class="tsd-returns-title">Returns <a href="human.html" class="tsd-signature-type" data-tsd-kind="Class">Human</a></h4>
@ -425,7 +425,7 @@
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class">
<a name="image" class="tsd-anchor"></a>
<h3>image</h3>
<div class="tsd-signature tsd-kind-icon">image<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">{ </span>canvas<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">HTMLCanvasElement</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">OffscreenCanvas</span><span class="tsd-signature-symbol">; </span>tensor<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">typeof </span><span class="tsd-signature-type">__class</span><span class="tsd-signature-symbol"> }</span></div>
<div class="tsd-signature tsd-kind-icon">image<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">{ </span>canvas<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">HTMLCanvasElement</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">OffscreenCanvas</span><span class="tsd-signature-symbol">; </span>tensor<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Tensor</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">Rank</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol"> }</span></div>
<aside class="tsd-sources">
</aside>
<div class="tsd-comment tsd-typography">
@ -440,7 +440,7 @@
<h5>canvas<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">HTMLCanvasElement</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">OffscreenCanvas</span></h5>
</li>
<li class="tsd-parameter">
<h5>tensor<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">typeof </span><span class="tsd-signature-type">__class</span></h5>
<h5>tensor<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Tensor</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">Rank</span><span class="tsd-signature-symbol">&gt;</span></h5>
</li>
</ul>
</div>
@ -448,7 +448,7 @@
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class">
<a name="models" class="tsd-anchor"></a>
<h3>models</h3>
<div class="tsd-signature tsd-kind-icon">models<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">{ </span>age<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>blazepose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>centernet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>efficientpose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>embedding<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>emotion<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>face<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">[</span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">]</span><span class="tsd-signature-symbol">; </span>faceres<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>gender<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>handpose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">[</span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">]</span><span class="tsd-signature-symbol">; </span>iris<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>nanodet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">; </span>posenet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol"> }</span></div>
<div class="tsd-signature tsd-kind-icon">models<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">{ </span>age<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">; </span>blazepose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">; </span>centernet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">; </span>efficientpose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">; </span>embedding<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">; </span>emotion<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">; </span>face<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">[</span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">]</span><span class="tsd-signature-symbol">; </span>faceres<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">; </span>gender<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">; </span>handpose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">[</span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">]</span><span class="tsd-signature-symbol">; </span>iris<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">; </span>nanodet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">; </span>posenet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol"> }</span></div>
<aside class="tsd-sources">
</aside>
<div class="tsd-comment tsd-typography">
@ -460,43 +460,43 @@
<h4>Type declaration</h4>
<ul class="tsd-parameters">
<li class="tsd-parameter">
<h5>age<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5>
<h5>age<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span></h5>
</li>
<li class="tsd-parameter">
<h5>blazepose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5>
<h5>blazepose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span></h5>
</li>
<li class="tsd-parameter">
<h5>centernet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5>
<h5>centernet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span></h5>
</li>
<li class="tsd-parameter">
<h5>efficientpose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5>
<h5>efficientpose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span></h5>
</li>
<li class="tsd-parameter">
<h5>embedding<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5>
<h5>embedding<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span></h5>
</li>
<li class="tsd-parameter">
<h5>emotion<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5>
<h5>emotion<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span></h5>
</li>
<li class="tsd-parameter">
<h5>face<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">[</span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">]</span></h5>
<h5>face<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">[</span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">]</span></h5>
</li>
<li class="tsd-parameter">
<h5>faceres<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5>
<h5>faceres<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span></h5>
</li>
<li class="tsd-parameter">
<h5>gender<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5>
<h5>gender<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span></h5>
</li>
<li class="tsd-parameter">
<h5>handpose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">[</span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol">]</span></h5>
<h5>handpose<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">[</span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">]</span></h5>
</li>
<li class="tsd-parameter">
<h5>iris<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5>
<h5>iris<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span></h5>
</li>
<li class="tsd-parameter">
<h5>nanodet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5>
<h5>nanodet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span></h5>
</li>
<li class="tsd-parameter">
<h5>posenet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Object</span></h5>
<h5>posenet<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">unknown</span></h5>
</li>
</ul>
</div>
@ -504,7 +504,7 @@
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class">
<a name="perf" class="tsd-anchor"></a>
<h3>perf</h3>
<div class="tsd-signature tsd-kind-icon">perf<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span></div>
<div class="tsd-signature tsd-kind-icon">perf<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">&gt;</span></div>
<aside class="tsd-sources">
</aside>
<div class="tsd-comment tsd-typography">
@ -585,7 +585,7 @@
<a name="detect" class="tsd-anchor"></a>
<h3>detect</h3>
<ul class="tsd-signatures tsd-kind-method tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon">detect<span class="tsd-signature-symbol">(</span>input<span class="tsd-signature-symbol">: </span><a href="../index.html#input" class="tsd-signature-type" data-tsd-kind="Type alias">Input</a>, userConfig<span class="tsd-signature-symbol">?: </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol"> | </span><a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol">&lt;</span><a href="../index.html#error" class="tsd-signature-type" data-tsd-kind="Type alias">Error</a><span class="tsd-signature-symbol"> | </span><a href="../interfaces/result.html" class="tsd-signature-type" data-tsd-kind="Interface">Result</a><span class="tsd-signature-symbol">&gt;</span></li>
<li class="tsd-signature tsd-kind-icon">detect<span class="tsd-signature-symbol">(</span>input<span class="tsd-signature-symbol">: </span><a href="../index.html#input" class="tsd-signature-type" data-tsd-kind="Type alias">Input</a>, userConfig<span class="tsd-signature-symbol">?: </span><a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol">&lt;</span><a href="../index.html#error" class="tsd-signature-type" data-tsd-kind="Type alias">Error</a><span class="tsd-signature-symbol"> | </span><a href="../interfaces/result.html" class="tsd-signature-type" data-tsd-kind="Interface">Result</a><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
@ -608,7 +608,7 @@
<h5>input: <a href="../index.html#input" class="tsd-signature-type" data-tsd-kind="Type alias">Input</a></h5>
</li>
<li>
<h5>userConfig: <span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol"> | </span><a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol"> = {}</span></h5>
<h5>userConfig: <a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol"> = {}</span></h5>
</li>
</ul>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol">&lt;</span><a href="../index.html#error" class="tsd-signature-type" data-tsd-kind="Type alias">Error</a><span class="tsd-signature-symbol"> | </span><a href="../interfaces/result.html" class="tsd-signature-type" data-tsd-kind="Interface">Result</a><span class="tsd-signature-symbol">&gt;</span></h4>
@ -619,7 +619,7 @@
<a name="enhance" class="tsd-anchor"></a>
<h3>enhance</h3>
<ul class="tsd-signatures tsd-kind-method tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon">enhance<span class="tsd-signature-symbol">(</span>input<span class="tsd-signature-symbol">: </span><span class="tsd-signature-symbol">typeof </span><span class="tsd-signature-type">__class</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">typeof </span><span class="tsd-signature-type">__class</span></li>
<li class="tsd-signature tsd-kind-icon">enhance<span class="tsd-signature-symbol">(</span>input<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">Tensor</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">Rank</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Tensor</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">Rank</span><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
@ -633,13 +633,13 @@
<h4 class="tsd-parameters-title">Parameters</h4>
<ul class="tsd-parameters">
<li>
<h5>input: <span class="tsd-signature-symbol">typeof </span><span class="tsd-signature-type">__class</span></h5>
<h5>input: <span class="tsd-signature-type">Tensor</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">Rank</span><span class="tsd-signature-symbol">&gt;</span></h5>
<div class="tsd-comment tsd-typography">
<p>Tensor as provided in human.result.face[n].tensor</p>
</div>
</li>
</ul>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">typeof </span><span class="tsd-signature-type">__class</span></h4>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">null</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Tensor</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">Rank</span><span class="tsd-signature-symbol">&gt;</span></h4>
<p>Tensor</p>
</li>
</ul>
@ -648,7 +648,7 @@
<a name="load" class="tsd-anchor"></a>
<h3>load</h3>
<ul class="tsd-signatures tsd-kind-method tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon">load<span class="tsd-signature-symbol">(</span>userConfig<span class="tsd-signature-symbol">?: </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol"> | </span><a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">&gt;</span></li>
<li class="tsd-signature tsd-kind-icon">load<span class="tsd-signature-symbol">(</span>userConfig<span class="tsd-signature-symbol">?: </span><a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
@ -665,7 +665,7 @@
<h4 class="tsd-parameters-title">Parameters</h4>
<ul class="tsd-parameters">
<li>
<h5>userConfig: <span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol"> | </span><a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol"> = {}</span></h5>
<h5>userConfig: <a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol"> = {}</span></h5>
</li>
</ul>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">&gt;</span></h4>
@ -753,7 +753,7 @@
<a name="warmup" class="tsd-anchor"></a>
<h3>warmup</h3>
<ul class="tsd-signatures tsd-kind-method tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon">warmup<span class="tsd-signature-symbol">(</span>userConfig<span class="tsd-signature-symbol">?: </span><span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol"> | </span><a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol">&lt;</span><a href="../interfaces/result.html" class="tsd-signature-type" data-tsd-kind="Interface">Result</a><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">{ </span>error<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">any</span><span class="tsd-signature-symbol"> }</span><span class="tsd-signature-symbol">&gt;</span></li>
<li class="tsd-signature tsd-kind-icon">warmup<span class="tsd-signature-symbol">(</span>userConfig<span class="tsd-signature-symbol">?: </span><a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol">&lt;</span><a href="../interfaces/result.html" class="tsd-signature-type" data-tsd-kind="Interface">Result</a><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">{ </span>error<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">any</span><span class="tsd-signature-symbol"> }</span><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
@ -771,7 +771,7 @@
<h4 class="tsd-parameters-title">Parameters</h4>
<ul class="tsd-parameters">
<li>
<h5>userConfig: <span class="tsd-signature-type">Object</span><span class="tsd-signature-symbol"> | </span><a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol"> = {}</span></h5>
<h5>userConfig: <a href="../interfaces/config.html" class="tsd-signature-type" data-tsd-kind="Interface">Config</a><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol"> = {}</span></h5>
</li>
</ul>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol">&lt;</span><a href="../interfaces/result.html" class="tsd-signature-type" data-tsd-kind="Interface">Result</a><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">{ </span>error<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">any</span><span class="tsd-signature-symbol"> }</span><span class="tsd-signature-symbol">&gt;</span></h4>
@ -889,9 +889,6 @@
<li class=" tsd-kind-type-alias">
<a href="../index.html#input" class="tsd-kind-icon">Input</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensor" class="tsd-kind-icon">Tensor</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensorflow" class="tsd-kind-icon">Tensor<wbr>Flow</a>
</li>

View File

@ -89,7 +89,6 @@
<li class="tsd-kind-type-alias"><a href="index.html#error" class="tsd-kind-icon">Error</a></li>
<li class="tsd-kind-type-alias"><a href="index.html#gesture" class="tsd-kind-icon">Gesture</a></li>
<li class="tsd-kind-type-alias"><a href="index.html#input" class="tsd-kind-icon">Input</a></li>
<li class="tsd-kind-type-alias"><a href="index.html#tensor" class="tsd-kind-icon">Tensor</a></li>
<li class="tsd-kind-type-alias"><a href="index.html#tensorflow" class="tsd-kind-icon">Tensor<wbr>Flow</a></li>
</ul>
</section>
@ -147,7 +146,7 @@
<section class="tsd-panel tsd-member tsd-kind-type-alias">
<a name="input" class="tsd-anchor"></a>
<h3>Input</h3>
<div class="tsd-signature tsd-kind-icon">Input<span class="tsd-signature-symbol">:</span> <a href="index.html#tensor" class="tsd-signature-type" data-tsd-kind="Type alias">Tensor</a><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">typeof </span><span class="tsd-signature-type">Image</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">ImageData</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">ImageBitmap</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">HTMLImageElement</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">HTMLMediaElement</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">HTMLVideoElement</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">HTMLCanvasElement</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">OffscreenCanvas</span></div>
<div class="tsd-signature tsd-kind-icon">Input<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Tensor</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-symbol">typeof </span><span class="tsd-signature-type">Image</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">ImageData</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">ImageBitmap</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">HTMLImageElement</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">HTMLMediaElement</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">HTMLVideoElement</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">HTMLCanvasElement</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">OffscreenCanvas</span></div>
<aside class="tsd-sources">
</aside>
<div class="tsd-comment tsd-typography">
@ -156,18 +155,6 @@
</div>
</div>
</section>
<section class="tsd-panel tsd-member tsd-kind-type-alias">
<a name="tensor" class="tsd-anchor"></a>
<h3>Tensor</h3>
<div class="tsd-signature tsd-kind-icon">Tensor<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">typeof </span><span class="tsd-signature-type">tf.Tensor</span></div>
<aside class="tsd-sources">
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Generic Tensor object type</p>
</div>
</div>
</section>
<section class="tsd-panel tsd-member tsd-kind-type-alias">
<a name="tensorflow" class="tsd-anchor"></a>
<h3>Tensor<wbr>Flow</h3>
@ -228,9 +215,6 @@
<li class=" tsd-kind-type-alias">
<a href="index.html#input" class="tsd-kind-icon">Input</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="index.html#tensor" class="tsd-kind-icon">Tensor</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="index.html#tensorflow" class="tsd-kind-icon">Tensor<wbr>Flow</a>
</li>

View File

@ -214,9 +214,6 @@
<li class=" tsd-kind-type-alias">
<a href="../index.html#input" class="tsd-kind-icon">Input</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensor" class="tsd-kind-icon">Tensor</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensorflow" class="tsd-kind-icon">Tensor<wbr>Flow</a>
</li>

View File

@ -736,9 +736,6 @@
<li class=" tsd-kind-type-alias">
<a href="../index.html#input" class="tsd-kind-icon">Input</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensor" class="tsd-kind-icon">Tensor</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensorflow" class="tsd-kind-icon">Tensor<wbr>Flow</a>
</li>

View File

@ -131,14 +131,14 @@
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface">
<a name="bufferedoutput" class="tsd-anchor"></a>
<h3>buffered<wbr>Output</h3>
<div class="tsd-signature tsd-kind-icon">buffered<wbr>Output<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Boolean</span></div>
<div class="tsd-signature tsd-kind-icon">buffered<wbr>Output<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span></div>
<aside class="tsd-sources">
</aside>
</section>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface">
<a name="calculatehandbox" class="tsd-anchor"></a>
<h3>calculate<wbr>Hand<wbr>Box</h3>
<div class="tsd-signature tsd-kind-icon">calculate<wbr>Hand<wbr>Box<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Boolean</span></div>
<div class="tsd-signature tsd-kind-icon">calculate<wbr>Hand<wbr>Box<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span></div>
<aside class="tsd-sources">
</aside>
</section>
@ -152,35 +152,35 @@
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface">
<a name="drawboxes" class="tsd-anchor"></a>
<h3>draw<wbr>Boxes</h3>
<div class="tsd-signature tsd-kind-icon">draw<wbr>Boxes<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Boolean</span></div>
<div class="tsd-signature tsd-kind-icon">draw<wbr>Boxes<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span></div>
<aside class="tsd-sources">
</aside>
</section>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface">
<a name="drawlabels" class="tsd-anchor"></a>
<h3>draw<wbr>Labels</h3>
<div class="tsd-signature tsd-kind-icon">draw<wbr>Labels<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Boolean</span></div>
<div class="tsd-signature tsd-kind-icon">draw<wbr>Labels<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span></div>
<aside class="tsd-sources">
</aside>
</section>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface">
<a name="drawpoints" class="tsd-anchor"></a>
<h3>draw<wbr>Points</h3>
<div class="tsd-signature tsd-kind-icon">draw<wbr>Points<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Boolean</span></div>
<div class="tsd-signature tsd-kind-icon">draw<wbr>Points<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span></div>
<aside class="tsd-sources">
</aside>
</section>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface">
<a name="drawpolygons" class="tsd-anchor"></a>
<h3>draw<wbr>Polygons</h3>
<div class="tsd-signature tsd-kind-icon">draw<wbr>Polygons<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Boolean</span></div>
<div class="tsd-signature tsd-kind-icon">draw<wbr>Polygons<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span></div>
<aside class="tsd-sources">
</aside>
</section>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface">
<a name="fillpolygons" class="tsd-anchor"></a>
<h3>fill<wbr>Polygons</h3>
<div class="tsd-signature tsd-kind-icon">fill<wbr>Polygons<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Boolean</span></div>
<div class="tsd-signature tsd-kind-icon">fill<wbr>Polygons<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span></div>
<aside class="tsd-sources">
</aside>
</section>
@ -236,21 +236,21 @@
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface">
<a name="usecurves" class="tsd-anchor"></a>
<h3>use<wbr>Curves</h3>
<div class="tsd-signature tsd-kind-icon">use<wbr>Curves<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Boolean</span></div>
<div class="tsd-signature tsd-kind-icon">use<wbr>Curves<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span></div>
<aside class="tsd-sources">
</aside>
</section>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface">
<a name="usedepth" class="tsd-anchor"></a>
<h3>use<wbr>Depth</h3>
<div class="tsd-signature tsd-kind-icon">use<wbr>Depth<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Boolean</span></div>
<div class="tsd-signature tsd-kind-icon">use<wbr>Depth<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span></div>
<aside class="tsd-sources">
</aside>
</section>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface">
<a name="userawboxes" class="tsd-anchor"></a>
<h3>use<wbr>Raw<wbr>Boxes</h3>
<div class="tsd-signature tsd-kind-icon">use<wbr>Raw<wbr>Boxes<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Boolean</span></div>
<div class="tsd-signature tsd-kind-icon">use<wbr>Raw<wbr>Boxes<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span></div>
<aside class="tsd-sources">
</aside>
</section>
@ -362,9 +362,6 @@
<li class=" tsd-kind-type-alias">
<a href="../index.html#input" class="tsd-kind-icon">Input</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensor" class="tsd-kind-icon">Tensor</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensorflow" class="tsd-kind-icon">Tensor<wbr>Flow</a>
</li>

View File

@ -348,9 +348,6 @@
<li class=" tsd-kind-type-alias">
<a href="../index.html#input" class="tsd-kind-icon">Input</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensor" class="tsd-kind-icon">Tensor</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensorflow" class="tsd-kind-icon">Tensor<wbr>Flow</a>
</li>

View File

@ -145,7 +145,7 @@
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface">
<a name="landmarks" class="tsd-anchor"></a>
<h3>landmarks</h3>
<div class="tsd-signature tsd-kind-icon">landmarks<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">[</span><span class="tsd-signature-type">number</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">number</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">number</span><span class="tsd-signature-symbol">]</span><span class="tsd-signature-symbol">[]</span></div>
<div class="tsd-signature tsd-kind-icon">landmarks<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol">[]</span></div>
<aside class="tsd-sources">
</aside>
</section>
@ -221,9 +221,6 @@
<li class=" tsd-kind-type-alias">
<a href="../index.html#input" class="tsd-kind-icon">Input</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensor" class="tsd-kind-icon">Tensor</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensorflow" class="tsd-kind-icon">Tensor<wbr>Flow</a>
</li>

View File

@ -244,9 +244,6 @@
<li class=" tsd-kind-type-alias">
<a href="../index.html#input" class="tsd-kind-icon">Input</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensor" class="tsd-kind-icon">Tensor</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensorflow" class="tsd-kind-icon">Tensor<wbr>Flow</a>
</li>

View File

@ -163,17 +163,9 @@
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface">
<a name="performance" class="tsd-anchor"></a>
<h3>performance</h3>
<div class="tsd-signature tsd-kind-icon">performance<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">{ </span>any<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">any</span><span class="tsd-signature-symbol"> }</span></div>
<div class="tsd-signature tsd-kind-icon">performance<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">&gt;</span></div>
<aside class="tsd-sources">
</aside>
<div class="tsd-type-declaration">
<h4>Type declaration</h4>
<ul class="tsd-parameters">
<li class="tsd-parameter">
<h5>any<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">any</span></h5>
</li>
</ul>
</div>
</section>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface">
<a name="timestamp" class="tsd-anchor"></a>
@ -260,9 +252,6 @@
<li class=" tsd-kind-type-alias">
<a href="../index.html#input" class="tsd-kind-icon">Input</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensor" class="tsd-kind-icon">Tensor</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../index.html#tensorflow" class="tsd-kind-icon">Tensor<wbr>Flow</a>
</li>

View File

@ -1,17 +1,17 @@
import * as tf from '../../dist/tfjs.esm.js';
import { Config } from '../config';
import { Tensor, GraphModel } from '../tfjs/types';
export declare class BlazeFaceModel {
model: any;
model: GraphModel;
anchorsData: [number, number][];
anchors: typeof tf.Tensor;
anchors: Tensor;
inputSize: number;
config: Config;
constructor(model: any, config: any);
getBoundingBoxes(inputImage: any): Promise<{
boxes: {
box: {
startPoint: typeof tf.Tensor;
endPoint: typeof tf.Tensor;
startPoint: Tensor;
endPoint: Tensor;
};
landmarks: any;
anchor: number[];

View File

@ -9,6 +9,6 @@ export declare function predict(input: any, config: any): Promise<{
annotations: any;
image: any;
}[]>;
export declare function load(config: any): Promise<[Object, Object, Object]>;
export declare function load(config: any): Promise<[unknown, unknown, unknown]>;
export declare const triangulation: number[];
export declare const uvmap: number[][];

View File

@ -1,14 +1,16 @@
import { GraphModel } from '../tfjs/types';
import { BlazeFaceModel } from './blazeface';
export declare class Pipeline {
storedBoxes: Array<{
startPoint: number[];
endPoint: number[];
landmarks: any;
landmarks: Array<number>;
confidence: number;
faceConfidence?: number;
}>;
boundingBoxDetector: any;
meshDetector: any;
irisModel: any;
boundingBoxDetector: BlazeFaceModel;
meshDetector: GraphModel;
irisModel: GraphModel;
boxSize: number;
meshSize: number;
irisSize: number;

20
types/draw/draw.d.ts vendored
View File

@ -29,16 +29,16 @@ export interface DrawOptions {
lineWidth: number;
pointSize: number;
roundRect: number;
drawPoints: Boolean;
drawLabels: Boolean;
drawBoxes: Boolean;
drawPolygons: Boolean;
fillPolygons: Boolean;
useDepth: Boolean;
useCurves: Boolean;
bufferedOutput: Boolean;
useRawBoxes: Boolean;
calculateHandBox: Boolean;
drawPoints: boolean;
drawLabels: boolean;
drawBoxes: boolean;
drawPolygons: boolean;
fillPolygons: boolean;
useDepth: boolean;
useCurves: boolean;
bufferedOutput: boolean;
useRawBoxes: boolean;
calculateHandBox: boolean;
}
export declare const options: DrawOptions;
export declare function gesture(inCanvas: HTMLCanvasElement, result: Array<Gesture>, drawOptions?: DrawOptions): Promise<void>;

View File

@ -1,5 +1,4 @@
import * as tf from '../../dist/tfjs.esm.js';
declare type Tensor = typeof tf.Tensor;
import { Tensor } from '../tfjs/types';
declare type DB = Array<{
name: string;
source: string;

View File

@ -1,6 +1,7 @@
import * as tf from '../../dist/tfjs.esm.js';
import { GraphModel } from '../tfjs/types';
export declare class HandDetector {
model: any;
model: GraphModel;
anchors: number[][];
anchorsTensor: typeof tf.Tensor;
inputSize: number;

View File

@ -1,7 +1,8 @@
import * as detector from './handdetector';
import { GraphModel } from '../tfjs/types';
export declare class HandPipeline {
handDetector: detector.HandDetector;
handPoseModel: any;
handPoseModel: GraphModel;
inputSize: number;
storedBoxes: Array<{
startPoint: number[];
@ -27,5 +28,12 @@ export declare class HandPipeline {
palmLandmarks: any;
};
transformRawCoords(rawCoords: any, box2: any, angle: any, rotationMatrix: any): any;
estimateHands(image: any, config: any): Promise<{}[]>;
estimateHands(image: any, config: any): Promise<{
landmarks?: number[] | undefined;
confidence: number;
box: {
topLeft: number[];
bottomRight: number[];
};
}[]>;
}

View File

@ -1,3 +1,3 @@
import { Hand } from '../result';
export declare function predict(input: any, config: any): Promise<Hand[]>;
export declare function load(config: any): Promise<[Object, Object]>;
export declare function load(config: any): Promise<[unknown, unknown]>;

15
types/human.d.ts vendored
View File

@ -10,8 +10,7 @@ import * as blazepose from './blazepose/blazepose';
import * as nanodet from './object/nanodet';
import * as centernet from './object/centernet';
import * as draw from './draw/draw';
/** Generic Tensor object type */
export declare type Tensor = typeof tf.Tensor;
import { Tensor } from './tfjs/types';
export type { Config } from './config';
export type { Result, Face, Hand, Body, Item, Gesture } from './result';
export type { DrawOptions } from './draw/draw';
@ -24,7 +23,7 @@ export declare type Error = {
/** Instance of TensorFlow/JS */
export declare type TensorFlow = typeof tf;
/** Generic Model object type, holds instance of individual models */
declare type Model = Object;
declare type Model = unknown;
/**
* **Human** library main class
*
@ -108,12 +107,12 @@ export declare class Human {
agent: string;
};
/** Performance object that contains values for all recently performed operations */
perf: any;
perf: Record<string, unknown>;
/**
* Creates instance of Human library that is futher used for all operations
* - @param userConfig: {@link Config}
*/
constructor(userConfig?: Config | Object);
constructor(userConfig?: Config | Record<string, unknown>);
/** @hidden */
analyze: (...msg: any[]) => void;
/** Simmilarity method calculates simmilarity between two provided face descriptors (face embeddings)
@ -145,19 +144,19 @@ export declare class Human {
/** Load method preloads all configured models on-demand
* - Not explicitly required as any required model is load implicitly on it's first run
*/
load(userConfig?: Config | Object): Promise<void>;
load(userConfig?: Config | Record<string, unknown>): Promise<void>;
/** Main detection method
* - Analyze configuration: {@link Config}
* - Pre-process input: {@link Input}
* - Run inference for all configured models
* - Process and return result: {@link Result}
*/
detect(input: Input, userConfig?: Config | Object): Promise<Result | Error>;
detect(input: Input, userConfig?: Config | Record<string, unknown>): Promise<Result | Error>;
/** Warmup metho pre-initializes all models for faster inference
* - can take significant time on startup
* - only used for `webgl` and `humangl` backends
*/
warmup(userConfig?: Config | Object): Promise<Result | {
warmup(userConfig?: Config | Record<string, unknown>): Promise<Result | {
error: any;
}>;
}

View File

@ -3,16 +3,16 @@ export declare function getAdjacentKeyPoints(keypoints: any, minConfidence: any)
export declare function getBoundingBox(keypoints: any): [number, number, number, number];
export declare function scalePoses(poses: any, [height, width]: [any, any], [inputResolutionHeight, inputResolutionWidth]: [any, any]): any;
export declare class MaxHeap {
priorityQueue: Array<any>;
priorityQueue: Array<unknown>;
numberOfElements: number;
getElementValue: any;
getElementValue: unknown;
constructor(maxSize: any, getElementValue: any);
enqueue(x: any): void;
dequeue(): any;
dequeue(): unknown;
empty(): boolean;
size(): number;
all(): any[];
max(): any;
all(): unknown[];
max(): unknown;
swim(k: any): void;
sink(k: any): void;
getValueAt(i: any): any;

6
types/result.d.ts vendored
View File

@ -112,7 +112,7 @@ export interface Hand {
confidence: number;
box: [number, number, number, number];
boxRaw: [number, number, number, number];
landmarks: Array<[number, number, number]>;
landmarks: number[];
annotations: Record<string, Array<{
part: string;
points: Array<[number, number, number]>;
@ -170,9 +170,7 @@ export interface Result {
gesture: Array<Gesture>;
/** {@link Object}: detection & analysis results */
object: Array<Item>;
performance: {
any: any;
};
performance: Record<string, unknown>;
canvas: OffscreenCanvas | HTMLCanvasElement;
timestamp: number;
}

View File

@ -2,7 +2,7 @@ export declare const config: {
name: string;
priority: number;
canvas: OffscreenCanvas | HTMLCanvasElement | null;
gl: any;
gl: unknown;
width: number;
height: number;
webGLattr: {

2
types/tfjs/types.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
export { Tensor } from '@tensorflow/tfjs-core/dist/index';
export { GraphModel } from '@tensorflow/tfjs-converter/dist/index';