Commit 7d04da10 by vincent

check in latest build

parent 7152e12d
...@@ -3,4 +3,4 @@ import { FaceLandmarkNet } from './faceLandmarkNet/FaceLandmarkNet'; ...@@ -3,4 +3,4 @@ import { FaceLandmarkNet } from './faceLandmarkNet/FaceLandmarkNet';
import { FaceRecognitionNet } from './faceRecognitionNet/FaceRecognitionNet'; import { FaceRecognitionNet } from './faceRecognitionNet/FaceRecognitionNet';
import { FullFaceDescription } from './FullFaceDescription'; import { FullFaceDescription } from './FullFaceDescription';
import { TNetInput } from './types'; import { TNetInput } from './types';
export declare function allFacesFactory(detectionNet: FaceDetectionNet, landmarkNet: FaceLandmarkNet, recognitionNet: FaceRecognitionNet): (input: TNetInput, minConfidence: number) => Promise<FullFaceDescription[]>; export declare function allFacesFactory(detectionNet: FaceDetectionNet, landmarkNet: FaceLandmarkNet, recognitionNet: FaceRecognitionNet): (input: TNetInput, minConfidence: number, useBatchProcessing?: boolean) => Promise<FullFaceDescription[]>;
...@@ -4,34 +4,45 @@ var tslib_1 = require("tslib"); ...@@ -4,34 +4,45 @@ var tslib_1 = require("tslib");
var extractFaceTensors_1 = require("./extractFaceTensors"); var extractFaceTensors_1 = require("./extractFaceTensors");
var FullFaceDescription_1 = require("./FullFaceDescription"); var FullFaceDescription_1 = require("./FullFaceDescription");
function allFacesFactory(detectionNet, landmarkNet, recognitionNet) { function allFacesFactory(detectionNet, landmarkNet, recognitionNet) {
return function (input, minConfidence) { return function (input, minConfidence, useBatchProcessing) {
if (useBatchProcessing === void 0) { useBatchProcessing = false; }
return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__awaiter(this, void 0, void 0, function () {
var detections, faceTensors, faceLandmarksByFace, alignedFaceBoxes, alignedFaceTensors, descriptors; var detections, faceTensors, faceLandmarksByFace, _a, alignedFaceBoxes, alignedFaceTensors, descriptors, _b;
return tslib_1.__generator(this, function (_a) { return tslib_1.__generator(this, function (_c) {
switch (_a.label) { switch (_c.label) {
case 0: return [4 /*yield*/, detectionNet.locateFaces(input, minConfidence)]; case 0: return [4 /*yield*/, detectionNet.locateFaces(input, minConfidence)];
case 1: case 1:
detections = _a.sent(); detections = _c.sent();
return [4 /*yield*/, extractFaceTensors_1.extractFaceTensors(input, detections) return [4 /*yield*/, extractFaceTensors_1.extractFaceTensors(input, detections)];
/**
const faceLandmarksByFace = await Promise.all(faceTensors.map(
faceTensor => landmarkNet.detectLandmarks(faceTensor)
)) as FaceLandmarks[]
*/
];
case 2: case 2:
faceTensors = _a.sent(); faceTensors = _c.sent();
if (!useBatchProcessing) return [3 /*break*/, 4];
return [4 /*yield*/, landmarkNet.detectLandmarks(faceTensors)]; return [4 /*yield*/, landmarkNet.detectLandmarks(faceTensors)];
case 3: case 3:
faceLandmarksByFace = _a.sent(); _a = _c.sent();
return [3 /*break*/, 6];
case 4: return [4 /*yield*/, Promise.all(faceTensors.map(function (faceTensor) { return landmarkNet.detectLandmarks(faceTensor); }))];
case 5:
_a = _c.sent();
_c.label = 6;
case 6:
faceLandmarksByFace = _a;
faceTensors.forEach(function (t) { return t.dispose(); }); faceTensors.forEach(function (t) { return t.dispose(); });
alignedFaceBoxes = faceLandmarksByFace.map(function (landmarks, i) { return landmarks.align(detections[i].getBox()); }); alignedFaceBoxes = faceLandmarksByFace.map(function (landmarks, i) { return landmarks.align(detections[i].getBox()); });
return [4 /*yield*/, extractFaceTensors_1.extractFaceTensors(input, alignedFaceBoxes)]; return [4 /*yield*/, extractFaceTensors_1.extractFaceTensors(input, alignedFaceBoxes)];
case 4: case 7:
alignedFaceTensors = _a.sent(); alignedFaceTensors = _c.sent();
return [4 /*yield*/, Promise.all(alignedFaceTensors.map(function (faceTensor) { return recognitionNet.computeFaceDescriptor(faceTensor); }))]; if (!useBatchProcessing) return [3 /*break*/, 9];
case 5: return [4 /*yield*/, recognitionNet.computeFaceDescriptor(alignedFaceTensors)];
descriptors = _a.sent(); case 8:
_b = _c.sent();
return [3 /*break*/, 11];
case 9: return [4 /*yield*/, Promise.all(alignedFaceTensors.map(function (faceTensor) { return recognitionNet.computeFaceDescriptor(faceTensor); }))];
case 10:
_b = _c.sent();
_c.label = 11;
case 11:
descriptors = _b;
alignedFaceTensors.forEach(function (t) { return t.dispose(); }); alignedFaceTensors.forEach(function (t) { return t.dispose(); });
return [2 /*return*/, detections.map(function (detection, i) { return [2 /*return*/, detections.map(function (detection, i) {
return new FullFaceDescription_1.FullFaceDescription(detection, faceLandmarksByFace[i].shiftByPoint(detection.getBox()), descriptors[i]); return new FullFaceDescription_1.FullFaceDescription(detection, faceLandmarksByFace[i].shiftByPoint(detection.getBox()), descriptors[i]);
......
{"version":3,"file":"allFacesFactory.js","sourceRoot":"","sources":["../src/allFacesFactory.ts"],"names":[],"mappings":";;;AAAA,2DAA0D;AAK1D,6DAA4D;AAG5D,yBACE,YAA8B,EAC9B,WAA4B,EAC5B,cAAkC;IAElC,OAAO,UACL,KAAgB,EAChB,aAAqB;;;;;4BAGF,qBAAM,YAAY,CAAC,WAAW,CAAC,KAAK,EAAE,aAAa,CAAC,EAAA;;wBAAjE,UAAU,GAAG,SAAoD;wBAEnD,qBAAM,uCAAkB,CAAC,KAAK,EAAE,UAAU,CAAC;4BAC/D;;;;+BAIG;0BAL4D;;wBAAzD,WAAW,GAAG,SAA2C;wBAMnC,qBAAM,WAAW,CAAC,eAAe,CAAC,WAAW,CAAC,EAAA;;wBAApE,mBAAmB,GAAG,SAAiE;wBAE7F,WAAW,CAAC,OAAO,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,OAAO,EAAE,EAAX,CAAW,CAAC,CAAA;wBAE/B,gBAAgB,GAAG,mBAAmB,CAAC,GAAG,CAC9C,UAAC,SAAS,EAAE,CAAC,IAAK,OAAA,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAvC,CAAuC,CAC1D,CAAA;wBAC0B,qBAAM,uCAAkB,CAAC,KAAK,EAAE,gBAAgB,CAAC,EAAA;;wBAAtE,kBAAkB,GAAG,SAAiD;wBAExD,qBAAM,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,GAAG,CAC1D,UAAA,UAAU,IAAI,OAAA,cAAc,CAAC,qBAAqB,CAAC,UAAU,CAAC,EAAhD,CAAgD,CAC/D,CAAC,EAAA;;wBAFI,WAAW,GAAG,SAElB;wBACF,kBAAkB,CAAC,OAAO,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,OAAO,EAAE,EAAX,CAAW,CAAC,CAAA;wBAE5C,sBAAO,UAAU,CAAC,GAAG,CAAC,UAAC,SAAS,EAAE,CAAC;gCACjC,OAAA,IAAI,yCAAmB,CACrB,SAAS,EACT,mBAAmB,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EACvD,WAAW,CAAC,CAAC,CAAC,CACf;4BAJD,CAIC,CACF,EAAA;;;;KAEF,CAAA;AACH,CAAC;AAzCD,0CAyCC"} {"version":3,"file":"allFacesFactory.js","sourceRoot":"","sources":["../src/allFacesFactory.ts"],"names":[],"mappings":";;;AAAA,2DAA0D;AAK1D,6DAA4D;AAG5D,yBACE,YAA8B,EAC9B,WAA4B,EAC5B,cAAkC;IAElC,OAAO,UACL,KAAgB,EAChB,aAAqB,EACrB,kBAAmC;QAAnC,mCAAA,EAAA,0BAAmC;;;;;4BAGhB,qBAAM,YAAY,CAAC,WAAW,CAAC,KAAK,EAAE,aAAa,CAAC,EAAA;;wBAAjE,UAAU,GAAG,SAAoD;wBAEnD,qBAAM,uCAAkB,CAAC,KAAK,EAAE,UAAU,CAAC,EAAA;;wBAAzD,WAAW,GAAG,SAA2C;6BAEnC,kBAAkB,EAAlB,wBAAkB;wBAC1C,qBAAM,WAAW,CAAC,eAAe,CAAC,WAAW,CAAC,EAAA;;wBAA9C,KAAA,SAAiE,CAAA;;4BACjE,qBAAM,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CACjC,UAAA,UAAU,IAAI,OAAA,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,EAAvC,CAAuC,CACtD,CAAC,EAAA;;wBAFA,KAAA,SAEmB,CAAA;;;wBAJjB,mBAAmB,KAIF;wBAEvB,WAAW,CAAC,OAAO,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,OAAO,EAAE,EAAX,CAAW,CAAC,CAAA;wBAE/B,gBAAgB,GAAG,mBAAmB,CAAC,GAAG,CAC9C,UAAC,SAAS,EAAE,CAAC,IAAK,OAAA,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAvC,CAAuC,CAC1D,CAAA;wBAC0B,qBAAM,uCAAkB,CAAC,KAAK,EAAE,gBAAgB,CAAC,EAAA;;wBAAtE,kBAAkB,GAAG,SAAiD;6BAExD,kBAAkB,EAAlB,wBAAkB;wBAClC,qBAAM,cAAc,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,EAAA;;wBAA9D,KAAA,SAAgF,CAAA;;4BAChF,qBAAM,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,GAAG,CACxC,UAAA,UAAU,IAAI,OAAA,cAAc,CAAC,qBAAqB,CAAC,UAAU,CAAC,EAAhD,CAAgD,CAC/D,CAAC,EAAA;;wBAFA,KAAA,SAEkB,CAAA;;;wBAJhB,WAAW,KAIK;wBAEtB,kBAAkB,CAAC,OAAO,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,OAAO,EAAE,EAAX,CAAW,CAAC,CAAA;wBAE5C,sBAAO,UAAU,CAAC,GAAG,CAAC,UAAC,SAAS,EAAE,CAAC;gCACjC,OAAA,IAAI,yCAAmB,CACrB,SAAS,EACT,mBAAmB,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EACvD,WAAW,CAAC,CAAC,CAAC,CACf;4BAJD,CAIC,CACF,EAAA;;;;KAEF,CAAA;AACH,CAAC;AA7CD,0CA6CC"}
\ No newline at end of file \ No newline at end of file
...@@ -5,7 +5,7 @@ export declare class FaceRecognitionNet { ...@@ -5,7 +5,7 @@ export declare class FaceRecognitionNet {
private _params; private _params;
load(weightsOrUrl: Float32Array | string | undefined): Promise<void>; load(weightsOrUrl: Float32Array | string | undefined): Promise<void>;
extractWeights(weights: Float32Array): void; extractWeights(weights: Float32Array): void;
forwardInput(input: NetInput): Promise<tf.Tensor2D>; forwardInput(input: NetInput): tf.Tensor2D;
forward(input: TNetInput): Promise<tf.Tensor2D>; forward(input: TNetInput): Promise<tf.Tensor2D>;
computeFaceDescriptor(input: TNetInput): Promise<Float32Array>; computeFaceDescriptor(input: TNetInput): Promise<Float32Array | Float32Array[]>;
} }
...@@ -37,13 +37,11 @@ var FaceRecognitionNet = /** @class */ (function () { ...@@ -37,13 +37,11 @@ var FaceRecognitionNet = /** @class */ (function () {
this._params = extractParams_1.extractParams(weights); this._params = extractParams_1.extractParams(weights);
}; };
FaceRecognitionNet.prototype.forwardInput = function (input) { FaceRecognitionNet.prototype.forwardInput = function (input) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _this = this; var _this = this;
return tslib_1.__generator(this, function (_a) {
if (!this._params) { if (!this._params) {
throw new Error('FaceRecognitionNet - load model before inference'); throw new Error('FaceRecognitionNet - load model before inference');
} }
return [2 /*return*/, tf.tidy(function () { return tf.tidy(function () {
var batchTensor = input.toBatchTensor(150, true); var batchTensor = input.toBatchTensor(150, true);
var normalized = normalize_1.normalize(batchTensor); var normalized = normalize_1.normalize(batchTensor);
var out = convLayer_1.convDown(normalized, _this._params.conv32_down); var out = convLayer_1.convDown(normalized, _this._params.conv32_down);
...@@ -65,8 +63,6 @@ var FaceRecognitionNet = /** @class */ (function () { ...@@ -65,8 +63,6 @@ var FaceRecognitionNet = /** @class */ (function () {
var globalAvg = out.mean([1, 2]); var globalAvg = out.mean([1, 2]);
var fullyConnected = tf.matMul(globalAvg, _this._params.fc); var fullyConnected = tf.matMul(globalAvg, _this._params.fc);
return fullyConnected; return fullyConnected;
})];
});
}); });
}; };
FaceRecognitionNet.prototype.forward = function (input) { FaceRecognitionNet.prototype.forward = function (input) {
...@@ -84,20 +80,21 @@ var FaceRecognitionNet = /** @class */ (function () { ...@@ -84,20 +80,21 @@ var FaceRecognitionNet = /** @class */ (function () {
}; };
FaceRecognitionNet.prototype.computeFaceDescriptor = function (input) { FaceRecognitionNet.prototype.computeFaceDescriptor = function (input) {
return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__awaiter(this, void 0, void 0, function () {
var result, _a, data; var _this = this;
return tslib_1.__generator(this, function (_b) { var netInput, faceDescriptorTensors, faceDescriptorsForBatch;
switch (_b.label) { return tslib_1.__generator(this, function (_a) {
case 0: switch (_a.label) {
_a = this.forward; case 0: return [4 /*yield*/, toNetInput_1.toNetInput(input, true)];
return [4 /*yield*/, toNetInput_1.toNetInput(input, true)]; case 1:
case 1: return [4 /*yield*/, _a.apply(this, [_b.sent()])]; netInput = _a.sent();
faceDescriptorTensors = tf.tidy(function () { return tf.unstack(_this.forwardInput(netInput)); });
return [4 /*yield*/, Promise.all(faceDescriptorTensors.map(function (t) { return t.data(); }))];
case 2: case 2:
result = _b.sent(); faceDescriptorsForBatch = _a.sent();
return [4 /*yield*/, result.data()]; faceDescriptorTensors.forEach(function (t) { return t.dispose(); });
case 3: return [2 /*return*/, netInput.isBatchInput
data = _b.sent(); ? faceDescriptorsForBatch
result.dispose(); : faceDescriptorsForBatch[0]];
return [2 /*return*/, data];
} }
}); });
}); });
......
{"version":3,"file":"FaceRecognitionNet.js","sourceRoot":"","sources":["../../src/faceRecognitionNet/FaceRecognitionNet.ts"],"names":[],"mappings":"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"} {"version":3,"file":"FaceRecognitionNet.js","sourceRoot":"","sources":["../../src/faceRecognitionNet/FaceRecognitionNet.ts"],"names":[],"mappings":"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"}
\ No newline at end of file \ No newline at end of file
...@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true }); ...@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
var tf = require("@tensorflow/tfjs-core"); var tf = require("@tensorflow/tfjs-core");
function normalize(x) { function normalize(x) {
return tf.tidy(function () { return tf.tidy(function () {
var avg_r = tf.fill([1, 150, 150, 1], 122.782); var avg_r = tf.fill(x.shape.slice(0, 3).concat([1]), 122.782);
var avg_g = tf.fill([1, 150, 150, 1], 117.001); var avg_g = tf.fill(x.shape.slice(0, 3).concat([1]), 117.001);
var avg_b = tf.fill([1, 150, 150, 1], 104.298); var avg_b = tf.fill(x.shape.slice(0, 3).concat([1]), 104.298);
var avg_rgb = tf.concat([avg_r, avg_g, avg_b], 3); var avg_rgb = tf.concat([avg_r, avg_g, avg_b], 3);
return tf.div(tf.sub(x, avg_rgb), tf.scalar(256)); return tf.div(tf.sub(x, avg_rgb), tf.scalar(256));
}); });
......
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/faceRecognitionNet/normalize.ts"],"names":[],"mappings":";;AAAA,0CAA4C;AAE5C,mBAA0B,CAAc;IACtC,OAAO,EAAE,CAAC,IAAI,CAAC;QACb,IAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACjD,IAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACjD,IAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACjD,IAAM,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;QAEnD,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;AACJ,CAAC;AATD,8BASC"} {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/faceRecognitionNet/normalize.ts"],"names":[],"mappings":";;AAAA,0CAA4C;AAE5C,mBAA0B,CAAc;IACtC,OAAO,EAAE,CAAC,IAAI,CAAC;QACb,IAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,SAAE,CAAC,IAAG,OAAO,CAAC,CAAC;QAC5D,IAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,SAAE,CAAC,IAAG,OAAO,CAAC,CAAC;QAC5D,IAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,SAAE,CAAC,IAAG,OAAO,CAAC,CAAC;QAC5D,IAAM,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;QAEnD,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;AACJ,CAAC;AATD,8BASC"}
\ No newline at end of file \ No newline at end of file
...@@ -16,5 +16,5 @@ export declare function loadFaceRecognitionModel(url: string): Promise<void>; ...@@ -16,5 +16,5 @@ export declare function loadFaceRecognitionModel(url: string): Promise<void>;
export declare function loadModels(url: string): Promise<[void, void, void]>; export declare function loadModels(url: string): Promise<[void, void, void]>;
export declare function locateFaces(input: TNetInput, minConfidence?: number, maxResults?: number): Promise<FaceDetection[]>; export declare function locateFaces(input: TNetInput, minConfidence?: number, maxResults?: number): Promise<FaceDetection[]>;
export declare function detectLandmarks(input: TNetInput): Promise<FaceLandmarks | FaceLandmarks[]>; export declare function detectLandmarks(input: TNetInput): Promise<FaceLandmarks | FaceLandmarks[]>;
export declare function computeFaceDescriptor(input: TNetInput): Promise<Float32Array>; export declare function computeFaceDescriptor(input: TNetInput): Promise<Float32Array | Float32Array[]>;
export declare const allFaces: (input: tf.Tensor | NetInput | TNetInput, minConfidence: number) => Promise<FullFaceDescription[]>; export declare const allFaces: (input: tf.Tensor | NetInput | TNetInput, minConfidence: number, useBatchProcessing?: boolean) => Promise<FullFaceDescription[]>;
{"version":3,"file":"globalApi.js","sourceRoot":"","sources":["../src/globalApi.ts"],"names":[],"mappings":";;AAEA,qDAAoD;AAEpD,wEAAuE;AACvE,qEAAoE;AAEpE,8EAA6E;AAKhE,QAAA,YAAY,GAAG,IAAI,mCAAgB,EAAE,CAAA;AACrC,QAAA,WAAW,GAAG,IAAI,iCAAe,EAAE,CAAA;AACnC,QAAA,cAAc,GAAG,IAAI,uCAAkB,EAAE,CAAA;AAEtD,gCAAuC,GAAW;IAChD,OAAO,oBAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC/B,CAAC;AAFD,wDAEC;AAED,+BAAsC,GAAW;IAC/C,OAAO,mBAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC9B,CAAC;AAFD,sDAEC;AAED,kCAAyC,GAAW;IAClD,OAAO,sBAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACjC,CAAC;AAFD,4DAEC;AAED,oBAA2B,GAAW;IACpC,OAAO,OAAO,CAAC,GAAG,CAAC;QACjB,sBAAsB,CAAC,GAAG,CAAC;QAC3B,qBAAqB,CAAC,GAAG,CAAC;QAC1B,wBAAwB,CAAC,GAAG,CAAC;KAC9B,CAAC,CAAA;AACJ,CAAC;AAND,gCAMC;AAED,qBACE,KAAgB,EAChB,aAAsB,EACtB,UAAmB;IAEnB,OAAO,oBAAY,CAAC,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,CAAC,CAAA;AACnE,CAAC;AAND,kCAMC;AAED,yBACE,KAAgB;IAEhB,OAAO,mBAAW,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;AAC3C,CAAC;AAJD,0CAIC;AAED,+BACE,KAAgB;IAEhB,OAAO,sBAAc,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAA;AACpD,CAAC;AAJD,sDAIC;AAEY,QAAA,QAAQ,GAGiB,iCAAe,CACnD,oBAAY,EACZ,mBAAW,EACX,sBAAc,CACf,CAAA"} {"version":3,"file":"globalApi.js","sourceRoot":"","sources":["../src/globalApi.ts"],"names":[],"mappings":";;AAEA,qDAAoD;AAEpD,wEAAuE;AACvE,qEAAoE;AAEpE,8EAA6E;AAKhE,QAAA,YAAY,GAAG,IAAI,mCAAgB,EAAE,CAAA;AACrC,QAAA,WAAW,GAAG,IAAI,iCAAe,EAAE,CAAA;AACnC,QAAA,cAAc,GAAG,IAAI,uCAAkB,EAAE,CAAA;AAEtD,gCAAuC,GAAW;IAChD,OAAO,oBAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC/B,CAAC;AAFD,wDAEC;AAED,+BAAsC,GAAW;IAC/C,OAAO,mBAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC9B,CAAC;AAFD,sDAEC;AAED,kCAAyC,GAAW;IAClD,OAAO,sBAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACjC,CAAC;AAFD,4DAEC;AAED,oBAA2B,GAAW;IACpC,OAAO,OAAO,CAAC,GAAG,CAAC;QACjB,sBAAsB,CAAC,GAAG,CAAC;QAC3B,qBAAqB,CAAC,GAAG,CAAC;QAC1B,wBAAwB,CAAC,GAAG,CAAC;KAC9B,CAAC,CAAA;AACJ,CAAC;AAND,gCAMC;AAED,qBACE,KAAgB,EAChB,aAAsB,EACtB,UAAmB;IAEnB,OAAO,oBAAY,CAAC,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,CAAC,CAAA;AACnE,CAAC;AAND,kCAMC;AAED,yBACE,KAAgB;IAEhB,OAAO,mBAAW,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;AAC3C,CAAC;AAJD,0CAIC;AAED,+BACE,KAAgB;IAEhB,OAAO,sBAAc,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAA;AACpD,CAAC;AAJD,sDAIC;AAEY,QAAA,QAAQ,GAIiB,iCAAe,CACnD,oBAAY,EACZ,mBAAW,EACX,sBAAc,CACf,CAAA"}
\ No newline at end of file \ No newline at end of file
...@@ -2128,9 +2128,9 @@ ...@@ -2128,9 +2128,9 @@
function normalize(x) { function normalize(x) {
return tidy(function () { return tidy(function () {
var avg_r = fill([1, 150, 150, 1], 122.782); var avg_r = fill(x.shape.slice(0, 3).concat([1]), 122.782);
var avg_g = fill([1, 150, 150, 1], 117.001); var avg_g = fill(x.shape.slice(0, 3).concat([1]), 117.001);
var avg_b = fill([1, 150, 150, 1], 104.298); var avg_b = fill(x.shape.slice(0, 3).concat([1]), 104.298);
var avg_rgb = concat([avg_r, avg_g, avg_b], 3); var avg_rgb = concat([avg_r, avg_g, avg_b], 3);
return div(sub(x, avg_rgb), scalar(256)); return div(sub(x, avg_rgb), scalar(256));
}); });
...@@ -2195,13 +2195,11 @@ ...@@ -2195,13 +2195,11 @@
this._params = extractParams$2(weights); this._params = extractParams$2(weights);
}; };
FaceRecognitionNet.prototype.forwardInput = function (input) { FaceRecognitionNet.prototype.forwardInput = function (input) {
return __awaiter$1(this, void 0, void 0, function () {
var _this = this; var _this = this;
return __generator$1(this, function (_a) {
if (!this._params) { if (!this._params) {
throw new Error('FaceRecognitionNet - load model before inference'); throw new Error('FaceRecognitionNet - load model before inference');
} }
return [2 /*return*/, tidy(function () { return tidy(function () {
var batchTensor = input.toBatchTensor(150, true); var batchTensor = input.toBatchTensor(150, true);
var normalized = normalize(batchTensor); var normalized = normalize(batchTensor);
var out = convDown(normalized, _this._params.conv32_down); var out = convDown(normalized, _this._params.conv32_down);
...@@ -2223,8 +2221,6 @@ ...@@ -2223,8 +2221,6 @@
var globalAvg = out.mean([1, 2]); var globalAvg = out.mean([1, 2]);
var fullyConnected = matMul(globalAvg, _this._params.fc); var fullyConnected = matMul(globalAvg, _this._params.fc);
return fullyConnected; return fullyConnected;
})];
});
}); });
}; };
FaceRecognitionNet.prototype.forward = function (input) { FaceRecognitionNet.prototype.forward = function (input) {
...@@ -2242,20 +2238,21 @@ ...@@ -2242,20 +2238,21 @@
}; };
FaceRecognitionNet.prototype.computeFaceDescriptor = function (input) { FaceRecognitionNet.prototype.computeFaceDescriptor = function (input) {
return __awaiter$1(this, void 0, void 0, function () { return __awaiter$1(this, void 0, void 0, function () {
var result, _a, data; var _this = this;
return __generator$1(this, function (_b) { var netInput, faceDescriptorTensors, faceDescriptorsForBatch;
switch (_b.label) { return __generator$1(this, function (_a) {
case 0: switch (_a.label) {
_a = this.forward; case 0: return [4 /*yield*/, toNetInput(input, true)];
return [4 /*yield*/, toNetInput(input, true)]; case 1:
case 1: return [4 /*yield*/, _a.apply(this, [_b.sent()])]; netInput = _a.sent();
faceDescriptorTensors = tidy(function () { return unstack(_this.forwardInput(netInput)); });
return [4 /*yield*/, Promise.all(faceDescriptorTensors.map(function (t) { return t.data(); }))];
case 2: case 2:
result = _b.sent(); faceDescriptorsForBatch = _a.sent();
return [4 /*yield*/, result.data()]; faceDescriptorTensors.forEach(function (t) { return t.dispose(); });
case 3: return [2 /*return*/, netInput.isBatchInput
data = _b.sent(); ? faceDescriptorsForBatch
result.dispose(); : faceDescriptorsForBatch[0]];
return [2 /*return*/, data];
} }
}); });
}); });
...@@ -2270,34 +2267,45 @@ ...@@ -2270,34 +2267,45 @@
} }
function allFacesFactory(detectionNet, landmarkNet, recognitionNet) { function allFacesFactory(detectionNet, landmarkNet, recognitionNet) {
return function (input, minConfidence) { return function (input, minConfidence, useBatchProcessing) {
if (useBatchProcessing === void 0) { useBatchProcessing = false; }
return __awaiter$1(this, void 0, void 0, function () { return __awaiter$1(this, void 0, void 0, function () {
var detections, faceTensors, faceLandmarksByFace, alignedFaceBoxes, alignedFaceTensors, descriptors; var detections, faceTensors, faceLandmarksByFace, _a, alignedFaceBoxes, alignedFaceTensors, descriptors, _b;
return __generator$1(this, function (_a) { return __generator$1(this, function (_c) {
switch (_a.label) { switch (_c.label) {
case 0: return [4 /*yield*/, detectionNet.locateFaces(input, minConfidence)]; case 0: return [4 /*yield*/, detectionNet.locateFaces(input, minConfidence)];
case 1: case 1:
detections = _a.sent(); detections = _c.sent();
return [4 /*yield*/, extractFaceTensors(input, detections) return [4 /*yield*/, extractFaceTensors(input, detections)];
/**
const faceLandmarksByFace = await Promise.all(faceTensors.map(
faceTensor => landmarkNet.detectLandmarks(faceTensor)
)) as FaceLandmarks[]
*/
];
case 2: case 2:
faceTensors = _a.sent(); faceTensors = _c.sent();
if (!useBatchProcessing) return [3 /*break*/, 4];
return [4 /*yield*/, landmarkNet.detectLandmarks(faceTensors)]; return [4 /*yield*/, landmarkNet.detectLandmarks(faceTensors)];
case 3: case 3:
faceLandmarksByFace = _a.sent(); _a = _c.sent();
return [3 /*break*/, 6];
case 4: return [4 /*yield*/, Promise.all(faceTensors.map(function (faceTensor) { return landmarkNet.detectLandmarks(faceTensor); }))];
case 5:
_a = _c.sent();
_c.label = 6;
case 6:
faceLandmarksByFace = _a;
faceTensors.forEach(function (t) { return t.dispose(); }); faceTensors.forEach(function (t) { return t.dispose(); });
alignedFaceBoxes = faceLandmarksByFace.map(function (landmarks, i) { return landmarks.align(detections[i].getBox()); }); alignedFaceBoxes = faceLandmarksByFace.map(function (landmarks, i) { return landmarks.align(detections[i].getBox()); });
return [4 /*yield*/, extractFaceTensors(input, alignedFaceBoxes)]; return [4 /*yield*/, extractFaceTensors(input, alignedFaceBoxes)];
case 4: case 7:
alignedFaceTensors = _a.sent(); alignedFaceTensors = _c.sent();
return [4 /*yield*/, Promise.all(alignedFaceTensors.map(function (faceTensor) { return recognitionNet.computeFaceDescriptor(faceTensor); }))]; if (!useBatchProcessing) return [3 /*break*/, 9];
case 5: return [4 /*yield*/, recognitionNet.computeFaceDescriptor(alignedFaceTensors)];
descriptors = _a.sent(); case 8:
_b = _c.sent();
return [3 /*break*/, 11];
case 9: return [4 /*yield*/, Promise.all(alignedFaceTensors.map(function (faceTensor) { return recognitionNet.computeFaceDescriptor(faceTensor); }))];
case 10:
_b = _c.sent();
_c.label = 11;
case 11:
descriptors = _b;
alignedFaceTensors.forEach(function (t) { return t.dispose(); }); alignedFaceTensors.forEach(function (t) { return t.dispose(); });
return [2 /*return*/, detections.map(function (detection, i) { return [2 /*return*/, detections.map(function (detection, i) {
return new FullFaceDescription(detection, faceLandmarksByFace[i].shiftByPoint(detection.getBox()), descriptors[i]); return new FullFaceDescription(detection, faceLandmarksByFace[i].shiftByPoint(detection.getBox()), descriptors[i]);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment