face-api.js
Version:
JavaScript API for face detection and face recognition in the browser with tensorflow.js
116 lines • 6.28 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var tf = require("@tensorflow/tfjs-core");
var classes_1 = require("../classes");
var FaceLandmarks68_1 = require("../classes/FaceLandmarks68");
var dom_1 = require("../dom");
var FaceProcessor_1 = require("../faceProcessor/FaceProcessor");
var utils_1 = require("../utils");
var FaceLandmark68NetBase = /** @class */ (function (_super) {
tslib_1.__extends(FaceLandmark68NetBase, _super);
function FaceLandmark68NetBase() {
return _super !== null && _super.apply(this, arguments) || this;
}
FaceLandmark68NetBase.prototype.postProcess = function (output, inputSize, originalDimensions) {
var inputDimensions = originalDimensions.map(function (_a) {
var width = _a.width, height = _a.height;
var scale = inputSize / Math.max(height, width);
return {
width: width * scale,
height: height * scale
};
});
var batchSize = inputDimensions.length;
return tf.tidy(function () {
var createInterleavedTensor = function (fillX, fillY) {
return tf.stack([
tf.fill([68], fillX),
tf.fill([68], fillY)
], 1).as2D(1, 136).as1D();
};
var getPadding = function (batchIdx, cond) {
var _a = inputDimensions[batchIdx], width = _a.width, height = _a.height;
return cond(width, height) ? Math.abs(width - height) / 2 : 0;
};
var getPaddingX = function (batchIdx) { return getPadding(batchIdx, function (w, h) { return w < h; }); };
var getPaddingY = function (batchIdx) { return getPadding(batchIdx, function (w, h) { return h < w; }); };
var landmarkTensors = output
.mul(tf.fill([batchSize, 136], inputSize))
.sub(tf.stack(Array.from(Array(batchSize), function (_, batchIdx) {
return createInterleavedTensor(getPaddingX(batchIdx), getPaddingY(batchIdx));
})))
.div(tf.stack(Array.from(Array(batchSize), function (_, batchIdx) {
return createInterleavedTensor(inputDimensions[batchIdx].width, inputDimensions[batchIdx].height);
})));
return landmarkTensors;
});
};
FaceLandmark68NetBase.prototype.forwardInput = function (input) {
var _this = this;
return tf.tidy(function () {
var out = _this.runNet(input);
return _this.postProcess(out, input.inputSize, input.inputDimensions.map(function (_a) {
var height = _a[0], width = _a[1];
return ({ height: height, width: width });
}));
});
};
FaceLandmark68NetBase.prototype.forward = function (input) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _a;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
_a = this.forwardInput;
return [4 /*yield*/, dom_1.toNetInput(input)];
case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])];
}
});
});
};
FaceLandmark68NetBase.prototype.detectLandmarks = function (input) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var netInput, landmarkTensors, landmarksForBatch;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, dom_1.toNetInput(input)];
case 1:
netInput = _a.sent();
landmarkTensors = tf.tidy(function () { return tf.unstack(_this.forwardInput(netInput)); });
return [4 /*yield*/, Promise.all(landmarkTensors.map(function (landmarkTensor, batchIdx) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var landmarksArray, _a, _b, xCoords, yCoords;
return tslib_1.__generator(this, function (_c) {
switch (_c.label) {
case 0:
_b = (_a = Array).from;
return [4 /*yield*/, landmarkTensor.data()];
case 1:
landmarksArray = _b.apply(_a, [_c.sent()]);
xCoords = landmarksArray.filter(function (_, i) { return utils_1.isEven(i); });
yCoords = landmarksArray.filter(function (_, i) { return !utils_1.isEven(i); });
return [2 /*return*/, new FaceLandmarks68_1.FaceLandmarks68(Array(68).fill(0).map(function (_, i) { return new classes_1.Point(xCoords[i], yCoords[i]); }), {
height: netInput.getInputHeight(batchIdx),
width: netInput.getInputWidth(batchIdx),
})];
}
});
}); }))];
case 2:
landmarksForBatch = _a.sent();
landmarkTensors.forEach(function (t) { return t.dispose(); });
return [2 /*return*/, netInput.isBatchInput
? landmarksForBatch
: landmarksForBatch[0]];
}
});
});
};
FaceLandmark68NetBase.prototype.getClassifierChannelsOut = function () {
return 136;
};
return FaceLandmark68NetBase;
}(FaceProcessor_1.FaceProcessor));
exports.FaceLandmark68NetBase = FaceLandmark68NetBase;
//# sourceMappingURL=FaceLandmark68NetBase.js.map
;