Unverified Commit d2e2d367 by justadudewhohacks Committed by GitHub

Merge pull request #35 from justadudewhohacks/batch-input

added general handling of batch inputs + face landmark net accepts batch inputs now
parents b8d62591 200f62a7
import { Dimensions, TMediaElement } from './types';
import * as tf from '@tensorflow/tfjs-core';
import { Point } from './Point';
import { TResolvedNetInput } from './types';
export declare class NetInput {
private _canvases;
constructor(medias: Array<TMediaElement>, dims?: Dimensions);
private initCanvas(media, dims?);
readonly canvases: HTMLCanvasElement[];
readonly width: number;
readonly height: number;
readonly dims: Dimensions | null;
private _inputs;
private _isManaged;
private _isBatchInput;
private _inputDimensions;
private _paddings;
constructor(inputs: tf.Tensor4D | Array<TResolvedNetInput>, isBatchInput?: boolean);
readonly inputs: tf.Tensor3D[];
readonly isManaged: boolean;
readonly isBatchInput: boolean;
readonly batchSize: number;
readonly inputDimensions: number[][];
readonly paddings: Point[];
getInputDimensions(batchIdx: number): number[];
getInputHeight(batchIdx: number): number;
getInputWidth(batchIdx: number): number;
getPaddings(batchIdx: number): Point;
toBatchTensor(inputSize: number, isCenterInputs?: boolean): tf.Tensor4D;
/**
* By setting the isManaged flag, all newly created tensors will be automatically
* automatically disposed after the batch tensor has been created
*/
managed(): this;
dispose(): void;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tf = require("@tensorflow/tfjs-core");
var isTensor_1 = require("./commons/isTensor");
var padToSquare_1 = require("./padToSquare");
var Point_1 = require("./Point");
var utils_1 = require("./utils");
var NetInput = /** @class */ (function () {
function NetInput(medias, dims) {
var _this = this;
this._canvases = [];
medias.forEach(function (m) { return _this.initCanvas(m, dims); });
}
NetInput.prototype.initCanvas = function (media, dims) {
if (media instanceof HTMLCanvasElement) {
this._canvases.push(media);
return;
function NetInput(inputs, isBatchInput) {
if (isBatchInput === void 0) { isBatchInput = false; }
this._inputs = [];
this._isManaged = false;
this._isBatchInput = false;
this._inputDimensions = [];
this._paddings = [];
if (isTensor_1.isTensor4D(inputs)) {
this._inputs = tf.unstack(inputs);
}
// if input is batch type, make sure every canvas has the same dimensions
var canvasDims = this.dims || dims;
this._canvases.push(utils_1.createCanvasFromMedia(media, canvasDims));
};
Object.defineProperty(NetInput.prototype, "canvases", {
if (Array.isArray(inputs)) {
this._inputs = inputs.map(function (input) {
if (isTensor_1.isTensor3D(input)) {
// TODO: make sure not to dispose original tensors passed in by the user
return tf.clone(input);
}
return tf.fromPixels(input instanceof HTMLCanvasElement ? input : utils_1.createCanvasFromMedia(input));
});
}
this._isBatchInput = this.batchSize > 1 || isBatchInput;
this._inputDimensions = this._inputs.map(function (t) { return t.shape; });
}
Object.defineProperty(NetInput.prototype, "inputs", {
get: function () {
return this._inputs;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NetInput.prototype, "isManaged", {
get: function () {
return this._canvases;
return this._isManaged;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NetInput.prototype, "width", {
Object.defineProperty(NetInput.prototype, "isBatchInput", {
get: function () {
return (this._canvases[0] || {}).width;
return this._isBatchInput;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NetInput.prototype, "height", {
Object.defineProperty(NetInput.prototype, "batchSize", {
get: function () {
return (this._canvases[0] || {}).height;
return this._inputs.length;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NetInput.prototype, "dims", {
Object.defineProperty(NetInput.prototype, "inputDimensions", {
get: function () {
var _a = this, width = _a.width, height = _a.height;
return (width > 0 && height > 0) ? { width: width, height: height } : null;
return this._inputDimensions;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NetInput.prototype, "paddings", {
get: function () {
return this._paddings;
},
enumerable: true,
configurable: true
});
NetInput.prototype.getInputDimensions = function (batchIdx) {
return this._inputDimensions[batchIdx];
};
NetInput.prototype.getInputHeight = function (batchIdx) {
return this._inputDimensions[batchIdx][0];
};
NetInput.prototype.getInputWidth = function (batchIdx) {
return this._inputDimensions[batchIdx][1];
};
NetInput.prototype.getPaddings = function (batchIdx) {
return this._paddings[batchIdx];
};
NetInput.prototype.toBatchTensor = function (inputSize, isCenterInputs) {
var _this = this;
if (isCenterInputs === void 0) { isCenterInputs = true; }
return tf.tidy(function () {
var inputTensors = _this._inputs.map(function (inputTensor) {
var _a = inputTensor.shape, originalHeight = _a[0], originalWidth = _a[1];
var imgTensor = inputTensor.expandDims().toFloat();
imgTensor = padToSquare_1.padToSquare(imgTensor, isCenterInputs);
var _b = imgTensor.shape.slice(1), heightAfterPadding = _b[0], widthAfterPadding = _b[1];
if (heightAfterPadding !== inputSize || widthAfterPadding !== inputSize) {
imgTensor = tf.image.resizeBilinear(imgTensor, [inputSize, inputSize]);
}
_this._paddings.push(new Point_1.Point(widthAfterPadding - originalWidth, heightAfterPadding - originalHeight));
return imgTensor;
});
var batchTensor = tf.stack(inputTensors).as4D(_this.batchSize, inputSize, inputSize, 3);
if (_this.isManaged) {
_this.dispose();
}
return batchTensor;
});
};
/**
* By setting the isManaged flag, all newly created tensors will be automatically
* automatically disposed after the batch tensor has been created
*/
NetInput.prototype.managed = function () {
this._isManaged = true;
return this;
};
NetInput.prototype.dispose = function () {
this._inputs.forEach(function (t) { return t.dispose(); });
};
return NetInput;
}());
exports.NetInput = NetInput;
......
{"version":3,"file":"NetInput.js","sourceRoot":"","sources":["../src/NetInput.ts"],"names":[],"mappings":";;AACA,iCAAgD;AAEhD;IAGE,kBACE,MAA4B,EAC5B,IAAiB;QAFnB,iBAMC;QAFC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAA;QACnB,MAAM,CAAC,OAAO,CAAC,UAAA,CAAC,IAAI,OAAA,KAAI,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,EAAxB,CAAwB,CAAC,CAAA;IAC/C,CAAC;IAEO,6BAAU,GAAlB,UAAmB,KAAoB,EAAE,IAAiB;QACxD,IAAI,KAAK,YAAY,iBAAiB,EAAE;YACtC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YAC1B,OAAM;SACP;QAED,yEAAyE;QACzE,IAAM,UAAU,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAA;QACpC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,6BAAqB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAA;IAC/D,CAAC;IAED,sBAAW,8BAAQ;aAAnB;YACE,OAAO,IAAI,CAAC,SAAS,CAAA;QACvB,CAAC;;;OAAA;IAED,sBAAW,2BAAK;aAAhB;YACE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAA;QACxC,CAAC;;;OAAA;IAED,sBAAW,4BAAM;aAAjB;YACE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAA;QACzC,CAAC;;;OAAA;IAED,sBAAW,0BAAI;aAAf;YACQ,IAAA,SAAwB,EAAtB,gBAAK,EAAE,kBAAM,CAAS;YAC9B,OAAO,CAAC,KAAK,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,OAAA,EAAE,MAAM,QAAA,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;QAC7D,CAAC;;;OAAA;IACH,eAAC;AAAD,CAAC,AAtCD,IAsCC;AAtCY,4BAAQ"}
\ No newline at end of file
{"version":3,"file":"NetInput.js","sourceRoot":"","sources":["../src/NetInput.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { FaceDetectionNet } from './faceDetectionNet/FaceDetectionNet';
import { FaceLandmarkNet } from './faceLandmarkNet/FaceLandmarkNet';
import { FaceRecognitionNet } from './faceRecognitionNet/FaceRecognitionNet';
import { FullFaceDescription } from './FullFaceDescription';
import { NetInput } from './NetInput';
export declare function allFacesFactory(detectionNet: FaceDetectionNet, landmarkNet: FaceLandmarkNet, recognitionNet: FaceRecognitionNet): (input: string | HTMLCanvasElement | HTMLImageElement | HTMLVideoElement | (string | HTMLCanvasElement | HTMLImageElement | HTMLVideoElement)[] | tf.Tensor<tf.Rank> | NetInput, minConfidence: number) => Promise<FullFaceDescription[]>;
import { TNetInput } from './types';
export declare function allFacesFactory(detectionNet: FaceDetectionNet, landmarkNet: FaceLandmarkNet, recognitionNet: FaceRecognitionNet): (input: TNetInput, minConfidence: number) => Promise<FullFaceDescription[]>;
......@@ -12,21 +12,25 @@ function allFacesFactory(detectionNet, landmarkNet, recognitionNet) {
case 0: return [4 /*yield*/, detectionNet.locateFaces(input, minConfidence)];
case 1:
detections = _a.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:
faceTensors = _a.sent();
return [4 /*yield*/, Promise.all(faceTensors.map(function (faceTensor) { return landmarkNet.detectLandmarks(faceTensor); }))];
return [4 /*yield*/, landmarkNet.detectLandmarks(faceTensors)];
case 3:
faceLandmarksByFace = _a.sent();
faceTensors.forEach(function (t) { return t.dispose(); });
return [4 /*yield*/, Promise.all(faceLandmarksByFace.map(function (landmarks, i) { return landmarks.align(detections[i].getBox()); }))];
case 4:
alignedFaceBoxes = _a.sent();
alignedFaceBoxes = faceLandmarksByFace.map(function (landmarks, i) { return landmarks.align(detections[i].getBox()); });
return [4 /*yield*/, extractFaceTensors_1.extractFaceTensors(input, alignedFaceBoxes)];
case 5:
case 4:
alignedFaceTensors = _a.sent();
return [4 /*yield*/, Promise.all(alignedFaceTensors.map(function (faceTensor) { return recognitionNet.computeFaceDescriptor(faceTensor); }))];
case 6:
case 5:
descriptors = _a.sent();
alignedFaceTensors.forEach(function (t) { return t.dispose(); });
return [2 /*return*/, detections.map(function (detection, i) {
......
{"version":3,"file":"allFacesFactory.js","sourceRoot":"","sources":["../src/allFacesFactory.ts"],"names":[],"mappings":";;;AAEA,2DAA0D;AAI1D,6DAA4D;AAI5D,yBACE,YAA8B,EAC9B,WAA4B,EAC5B,cAAkC;IAElC,OAAO,UACL,KAAuC,EACvC,aAAqB;;;;;4BAGF,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;wBACnC,qBAAM,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAC3D,UAAA,UAAU,IAAI,OAAA,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,EAAvC,CAAuC,CACtD,CAAC,EAAA;;wBAFI,mBAAmB,GAAG,SAE1B;wBACF,WAAW,CAAC,OAAO,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,OAAO,EAAE,EAAX,CAAW,CAAC,CAAA;wBAEZ,qBAAM,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAChE,UAAC,SAAS,EAAE,CAAC,IAAK,OAAA,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAvC,CAAuC,CAC1D,CAAC,EAAA;;wBAFI,gBAAgB,GAAG,SAEvB;wBACyB,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;AArCD,0CAqCC"}
\ No newline at end of file
{"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"}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { NetInput } from '../NetInput';
export declare function getImageTensor(input: tf.Tensor | NetInput): tf.Tensor4D;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tf = require("@tensorflow/tfjs-core");
var NetInput_1 = require("../NetInput");
function getImageTensor(input) {
return tf.tidy(function () {
if (input instanceof tf.Tensor) {
var rank = input.shape.length;
if (rank !== 3 && rank !== 4) {
throw new Error('input tensor must be of rank 3 or 4');
}
return (rank === 3 ? input.expandDims(0) : input).toFloat();
}
if (!(input instanceof NetInput_1.NetInput)) {
throw new Error('getImageTensor - expected input to be a tensor or an instance of NetInput');
}
return tf.concat(input.canvases.map(function (canvas) {
return tf.fromPixels(canvas).expandDims(0).toFloat();
}));
});
}
exports.getImageTensor = getImageTensor;
//# sourceMappingURL=getImageTensor.js.map
\ No newline at end of file
{"version":3,"file":"getImageTensor.js","sourceRoot":"","sources":["../../src/commons/getImageTensor.ts"],"names":[],"mappings":";;AAAA,0CAA4C;AAE5C,wCAAuC;AAEvC,wBAA+B,KAA2B;IACxD,OAAO,EAAE,CAAC,IAAI,CAAC;QACb,IAAI,KAAK,YAAY,EAAE,CAAC,MAAM,EAAE;YAC9B,IAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAA;YAC/B,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE;gBAC5B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAA;aACvD;YAED,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,EAAiB,CAAA;SAC3E;QAED,IAAI,CAAC,CAAC,KAAK,YAAY,mBAAQ,CAAC,EAAE;YAChC,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAA;SAC7F;QAED,OAAO,EAAE,CAAC,MAAM,CACd,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAA,MAAM;YACvB,OAAA,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE;QAA7C,CAA6C,CAC9C,CACa,CAAA;IAClB,CAAC,CAAC,CAAA;AACJ,CAAC;AArBD,wCAqBC"}
\ No newline at end of file
export declare function isMediaElement(input: any): boolean;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function isMediaElement(input) {
return input instanceof HTMLImageElement
|| input instanceof HTMLVideoElement
|| input instanceof HTMLCanvasElement;
}
exports.isMediaElement = isMediaElement;
//# sourceMappingURL=isMediaElement.js.map
\ No newline at end of file
{"version":3,"file":"isMediaElement.js","sourceRoot":"","sources":["../../src/commons/isMediaElement.ts"],"names":[],"mappings":";;AAAA,wBAA+B,KAAU;IACvC,OAAO,KAAK,YAAY,gBAAgB;WACnC,KAAK,YAAY,gBAAgB;WACjC,KAAK,YAAY,iBAAiB,CAAA;AACzC,CAAC;AAJD,wCAIC"}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
export declare function isTensor(tensor: tf.Tensor, dim: number): boolean;
export declare function isTensor1D(tensor: tf.Tensor): boolean;
export declare function isTensor2D(tensor: tf.Tensor): boolean;
export declare function isTensor3D(tensor: tf.Tensor): boolean;
export declare function isTensor4D(tensor: tf.Tensor): boolean;
export declare function isTensor(tensor: any, dim: number): boolean;
export declare function isTensor1D(tensor: any): boolean;
export declare function isTensor2D(tensor: any): boolean;
export declare function isTensor3D(tensor: any): boolean;
export declare function isTensor4D(tensor: any): boolean;
{"version":3,"file":"isTensor.js","sourceRoot":"","sources":["../../src/commons/isTensor.ts"],"names":[],"mappings":";;AAAA,0CAA4C;AAE5C,kBAAyB,MAAiB,EAAE,GAAW;IACrD,OAAO,MAAM,YAAY,EAAE,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,GAAG,CAAA;AACnE,CAAC;AAFD,4BAEC;AAED,oBAA2B,MAAiB;IAC1C,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AAC5B,CAAC;AAFD,gCAEC;AAED,oBAA2B,MAAiB;IAC1C,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AAC5B,CAAC;AAFD,gCAEC;AAED,oBAA2B,MAAiB;IAC1C,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AAC5B,CAAC;AAFD,gCAEC;AAED,oBAA2B,MAAiB;IAC1C,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AAC5B,CAAC;AAFD,gCAEC"}
\ No newline at end of file
{"version":3,"file":"isTensor.js","sourceRoot":"","sources":["../../src/commons/isTensor.ts"],"names":[],"mappings":";;AAAA,0CAA4C;AAE5C,kBAAyB,MAAW,EAAE,GAAW;IAC/C,OAAO,MAAM,YAAY,EAAE,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,GAAG,CAAA;AACnE,CAAC;AAFD,4BAEC;AAED,oBAA2B,MAAW;IACpC,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AAC5B,CAAC;AAFD,gCAEC;AAED,oBAA2B,MAAW;IACpC,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AAC5B,CAAC;AAFD,gCAEC;AAED,oBAA2B,MAAW;IACpC,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AAC5B,CAAC;AAFD,gCAEC;AAED,oBAA2B,MAAW;IACpC,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AAC5B,CAAC;AAFD,gCAEC"}
\ No newline at end of file
......@@ -4,3 +4,9 @@ export declare type ConvParams = {
bias: tf.Tensor1D;
};
export declare type ExtractWeightsFunction = (numWeights: number) => Float32Array;
export declare type BatchReshapeInfo = {
originalWidth: number;
originalHeight: number;
paddingX: number;
paddingY: number;
};
......@@ -26,7 +26,7 @@ function drawText(ctx, x, y, text, options) {
}
exports.drawText = drawText;
function drawDetection(canvasArg, detection, options) {
var canvas = utils_1.getElement(canvasArg);
var canvas = utils_1.resolveInput(canvasArg);
if (!(canvas instanceof HTMLCanvasElement)) {
throw new Error('drawBox - expected canvas to be of type: HTMLCanvasElement');
}
......@@ -66,7 +66,7 @@ function drawContour(ctx, points, isClosed) {
ctx.stroke();
}
function drawLandmarks(canvasArg, faceLandmarks, options) {
var canvas = utils_1.getElement(canvasArg);
var canvas = utils_1.resolveInput(canvasArg);
if (!(canvas instanceof HTMLCanvasElement)) {
throw new Error('drawLandmarks - expected canvas to be of type: HTMLCanvasElement');
}
......
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/drawing/index.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/drawing/index.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { FaceDetection } from './faceDetectionNet/FaceDetection';
import { NetInput } from './NetInput';
import { Rect } from './Rect';
import { TNetInput } from './types';
/**
......@@ -13,4 +12,4 @@ import { TNetInput } from './types';
* @param detections The face detection results or face bounding boxes for that image.
* @returns Tensors of the corresponding image region for each detected face.
*/
export declare function extractFaceTensors(input: tf.Tensor | NetInput | TNetInput, detections: Array<FaceDetection | Rect>): Promise<tf.Tensor4D[]>;
export declare function extractFaceTensors(input: TNetInput, detections: Array<FaceDetection | Rect>): Promise<tf.Tensor4D[]>;
......@@ -2,7 +2,6 @@
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var tf = require("@tensorflow/tfjs-core");
var getImageTensor_1 = require("./commons/getImageTensor");
var FaceDetection_1 = require("./faceDetectionNet/FaceDetection");
var toNetInput_1 = require("./toNetInput");
/**
......@@ -17,23 +16,21 @@ var toNetInput_1 = require("./toNetInput");
*/
function extractFaceTensors(input, detections) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var image, _a;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!(input instanceof tf.Tensor)) return [3 /*break*/, 1];
_a = input;
return [3 /*break*/, 3];
case 1: return [4 /*yield*/, toNetInput_1.toNetInput(input)];
case 2:
_a = _b.sent();
_b.label = 3;
case 3:
image = _a;
var netInput;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, toNetInput_1.toNetInput(input, true)];
case 1:
netInput = _a.sent();
if (netInput.batchSize > 1) {
if (netInput.isManaged) {
netInput.dispose();
}
throw new Error('extractFaceTensors - batchSize > 1 not supported');
}
return [2 /*return*/, tf.tidy(function () {
var imgTensor = getImageTensor_1.getImageTensor(image);
// TODO handle batches
var _a = imgTensor.shape, batchSize = _a[0], imgHeight = _a[1], imgWidth = _a[2], numChannels = _a[3];
var imgTensor = netInput.inputs[0].expandDims().toFloat();
var _a = imgTensor.shape.slice(1), imgHeight = _a[0], imgWidth = _a[1], numChannels = _a[2];
var boxes = detections.map(function (det) { return det instanceof FaceDetection_1.FaceDetection
? det.forSize(imgWidth, imgHeight).getBox().floor()
: det; });
......@@ -41,6 +38,9 @@ function extractFaceTensors(input, detections) {
var x = _a.x, y = _a.y, width = _a.width, height = _a.height;
return tf.slice(imgTensor, [0, y, x, 0], [1, height, width, numChannels]);
});
if (netInput.isManaged) {
netInput.dispose();
}
return faceTensors;
})];
}
......
{"version":3,"file":"extractFaceTensors.js","sourceRoot":"","sources":["../src/extractFaceTensors.ts"],"names":[],"mappings":";;;AAAA,0CAA4C;AAE5C,2DAA0D;AAC1D,kEAAiE;AAIjE,2CAA0C;AAE1C;;;;;;;;;GASG;AACH,4BACE,KAAuC,EACvC,UAAqC;;;;;;yBAGvB,CAAA,KAAK,YAAY,EAAE,CAAC,MAAM,CAAA,EAA1B,wBAA0B;oBACpC,KAAA,KAAK,CAAA;;wBACL,qBAAM,uBAAU,CAAC,KAAK,CAAC,EAAA;;oBAAvB,KAAA,SAAuB,CAAA;;;oBAFrB,KAAK,KAEgB;oBAE3B,sBAAO,EAAE,CAAC,IAAI,CAAC;4BACb,IAAM,SAAS,GAAG,+BAAc,CAAC,KAAK,CAAC,CAAA;4BAEvC,sBAAsB;4BAChB,IAAA,oBAA+D,EAA9D,iBAAS,EAAE,iBAAS,EAAE,gBAAQ,EAAE,mBAAW,CAAmB;4BAErE,IAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAC1B,UAAA,GAAG,IAAI,OAAA,GAAG,YAAY,6BAAa;gCACjC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;gCACnD,CAAC,CAAC,GAAG,EAFA,CAEA,CACR,CAAA;4BACD,IAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,UAAC,EAAuB;oCAArB,QAAC,EAAE,QAAC,EAAE,gBAAK,EAAE,kBAAM;gCAClD,OAAA,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;4BAAlE,CAAkE,CACnE,CAAA;4BAED,OAAO,WAAW,CAAA;wBACpB,CAAC,CAAC,EAAA;;;;CACH;AA1BD,gDA0BC"}
\ No newline at end of file
{"version":3,"file":"extractFaceTensors.js","sourceRoot":"","sources":["../src/extractFaceTensors.ts"],"names":[],"mappings":";;;AAAA,0CAA4C;AAE5C,kEAAiE;AAEjE,2CAA0C;AAG1C;;;;;;;;;GASG;AACH,4BACE,KAAgB,EAChB,UAAuC;;;;;wBAGtB,qBAAM,uBAAU,CAAC,KAAK,EAAE,IAAI,CAAC,EAAA;;oBAAxC,QAAQ,GAAG,SAA6B;oBAE9C,IAAI,QAAQ,CAAC,SAAS,GAAG,CAAC,EAAE;wBAC1B,IAAI,QAAQ,CAAC,SAAS,EAAE;4BACtB,QAAQ,CAAC,OAAO,EAAE,CAAA;yBACnB;wBACD,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;qBACpE;oBAED,sBAAO,EAAE,CAAC,IAAI,CAAC;4BACb,IAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,OAAO,EAAiB,CAAA;4BAEpE,IAAA,6BAA6D,EAA5D,iBAAS,EAAE,gBAAQ,EAAE,mBAAW,CAA4B;4BAEnE,IAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAC1B,UAAA,GAAG,IAAI,OAAA,GAAG,YAAY,6BAAa;gCACjC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;gCACnD,CAAC,CAAC,GAAG,EAFA,CAEA,CACR,CAAA;4BACD,IAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,UAAC,EAAuB;oCAArB,QAAC,EAAE,QAAC,EAAE,gBAAK,EAAE,kBAAM;gCAClD,OAAA,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;4BAAlE,CAAkE,CACnE,CAAA;4BAED,IAAI,QAAQ,CAAC,SAAS,EAAE;gCACtB,QAAQ,CAAC,OAAO,EAAE,CAAA;6BACnB;4BACD,OAAO,WAAW,CAAA;wBACpB,CAAC,CAAC,EAAA;;;;CACH;AAjCD,gDAiCC"}
\ No newline at end of file
import { FaceDetection } from './faceDetectionNet/FaceDetection';
import { Rect } from './Rect';
import { TNetInput } from './types';
/**
* Extracts the image regions containing the detected faces.
*
......@@ -7,4 +8,4 @@ import { Rect } from './Rect';
* @param detections The face detection results or face bounding boxes for that image.
* @returns The Canvases of the corresponding image region for each detected face.
*/
export declare function extractFaces(image: HTMLCanvasElement, detections: Array<FaceDetection | Rect>): HTMLCanvasElement[];
export declare function extractFaces(input: TNetInput, detections: Array<FaceDetection | Rect>): Promise<HTMLCanvasElement[]>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var FaceDetection_1 = require("./faceDetectionNet/FaceDetection");
var toNetInput_1 = require("./toNetInput");
var utils_1 = require("./utils");
/**
* Extracts the image regions containing the detected faces.
......@@ -9,17 +11,41 @@ var utils_1 = require("./utils");
* @param detections The face detection results or face bounding boxes for that image.
* @returns The Canvases of the corresponding image region for each detected face.
*/
function extractFaces(image, detections) {
var ctx = utils_1.getContext2dOrThrow(image);
var boxes = detections.map(function (det) { return det instanceof FaceDetection_1.FaceDetection
? det.forSize(image.width, image.height).getBox().floor()
: det; });
return boxes.map(function (_a) {
var x = _a.x, y = _a.y, width = _a.width, height = _a.height;
var faceImg = utils_1.createCanvas({ width: width, height: height });
utils_1.getContext2dOrThrow(faceImg)
.putImageData(ctx.getImageData(x, y, width, height), 0, 0);
return faceImg;
function extractFaces(input, detections) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var canvas, netInput, ctx, boxes;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
canvas = input;
if (!!(input instanceof HTMLCanvasElement)) return [3 /*break*/, 3];
return [4 /*yield*/, toNetInput_1.toNetInput(input, true)];
case 1:
netInput = _a.sent();
if (netInput.batchSize > 1) {
if (netInput.isManaged) {
netInput.dispose();
}
throw new Error('extractFaces - batchSize > 1 not supported');
}
return [4 /*yield*/, utils_1.imageTensorToCanvas(netInput.inputs[0])];
case 2:
canvas = _a.sent();
_a.label = 3;
case 3:
ctx = utils_1.getContext2dOrThrow(canvas);
boxes = detections.map(function (det) { return det instanceof FaceDetection_1.FaceDetection
? det.forSize(canvas.width, canvas.height).getBox().floor()
: det; });
return [2 /*return*/, boxes.map(function (_a) {
var x = _a.x, y = _a.y, width = _a.width, height = _a.height;
var faceImg = utils_1.createCanvas({ width: width, height: height });
utils_1.getContext2dOrThrow(faceImg)
.putImageData(ctx.getImageData(x, y, width, height), 0, 0);
return faceImg;
})];
}
});
});
}
exports.extractFaces = extractFaces;
......
{"version":3,"file":"extractFaces.js","sourceRoot":"","sources":["../src/extractFaces.ts"],"names":[],"mappings":";;AAAA,kEAAiE;AAEjE,iCAA4D;AAE5D;;;;;;GAMG;AACH,sBACE,KAAwB,EACxB,UAAqC;IAErC,IAAM,GAAG,GAAG,2BAAmB,CAAC,KAAK,CAAC,CAAA;IAEtC,IAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAC1B,UAAA,GAAG,IAAI,OAAA,GAAG,YAAY,6BAAa;QACjC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;QACzD,CAAC,CAAC,GAAG,EAFA,CAEA,CACR,CAAA;IACD,OAAO,KAAK,CAAC,GAAG,CAAC,UAAC,EAAuB;YAArB,QAAC,EAAE,QAAC,EAAE,gBAAK,EAAE,kBAAM;QACrC,IAAM,OAAO,GAAG,oBAAY,CAAC,EAAE,KAAK,OAAA,EAAE,MAAM,QAAA,EAAE,CAAC,CAAA;QAC/C,2BAAmB,CAAC,OAAO,CAAC;aACzB,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QAC5D,OAAO,OAAO,CAAA;IAChB,CAAC,CAAC,CAAA;AACJ,CAAC;AAjBD,oCAiBC"}
\ No newline at end of file
{"version":3,"file":"extractFaces.js","sourceRoot":"","sources":["../src/extractFaces.ts"],"names":[],"mappings":";;;AAAA,kEAAiE;AAEjE,2CAA0C;AAE1C,iCAAiF;AAEjF;;;;;;GAMG;AACH,sBACE,KAAgB,EAChB,UAAuC;;;;;;oBAGnC,MAAM,GAAG,KAA0B,CAAA;yBAEnC,CAAC,CAAC,KAAK,YAAY,iBAAiB,CAAC,EAArC,wBAAqC;oBACtB,qBAAM,uBAAU,CAAC,KAAK,EAAE,IAAI,CAAC,EAAA;;oBAAxC,QAAQ,GAAG,SAA6B;oBAE9C,IAAI,QAAQ,CAAC,SAAS,GAAG,CAAC,EAAE;wBAC1B,IAAI,QAAQ,CAAC,SAAS,EAAE;4BACtB,QAAQ,CAAC,OAAO,EAAE,CAAA;yBACnB;wBACD,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAA;qBAC9D;oBAEQ,qBAAM,2BAAmB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAA;;oBAAtD,MAAM,GAAG,SAA6C,CAAA;;;oBAGlD,GAAG,GAAG,2BAAmB,CAAC,MAAM,CAAC,CAAA;oBAEjC,KAAK,GAAG,UAAU,CAAC,GAAG,CAC1B,UAAA,GAAG,IAAI,OAAA,GAAG,YAAY,6BAAa;wBACjC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;wBAC3D,CAAC,CAAC,GAAG,EAFA,CAEA,CACR,CAAA;oBACD,sBAAO,KAAK,CAAC,GAAG,CAAC,UAAC,EAAuB;gCAArB,QAAC,EAAE,QAAC,EAAE,gBAAK,EAAE,kBAAM;4BACrC,IAAM,OAAO,GAAG,oBAAY,CAAC,EAAE,KAAK,OAAA,EAAE,MAAM,QAAA,EAAE,CAAC,CAAA;4BAC/C,2BAAmB,CAAC,OAAO,CAAC;iCACzB,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;4BAC5D,OAAO,OAAO,CAAA;wBAChB,CAAC,CAAC,EAAA;;;;CACH;AAjCD,oCAiCC"}
\ No newline at end of file
......@@ -6,10 +6,13 @@ export declare class FaceDetectionNet {
private _params;
load(weightsOrUrl?: Float32Array | string): Promise<void>;
extractWeights(weights: Float32Array): void;
private forwardTensor(imgTensor);
forward(input: tf.Tensor | NetInput | TNetInput): Promise<{
forwardInput(input: NetInput): {
boxes: tf.Tensor<tf.Rank.R2>[];
scores: tf.Tensor<tf.Rank.R1>[];
};
forward(input: TNetInput): Promise<{
boxes: tf.Tensor<tf.Rank.R2>[];
scores: tf.Tensor<tf.Rank.R1>[];
}>;
locateFaces(input: tf.Tensor | NetInput | TNetInput, minConfidence?: number, maxResults?: number): Promise<FaceDetection[]>;
locateFaces(input: TNetInput, minConfidence?: number, maxResults?: number): Promise<FaceDetection[]>;
}
......@@ -2,8 +2,6 @@
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var tf = require("@tensorflow/tfjs-core");
var getImageTensor_1 = require("../commons/getImageTensor");
var padToSquare_1 = require("../padToSquare");
var Rect_1 = require("../Rect");
var toNetInput_1 = require("../toNetInput");
var extractParams_1 = require("./extractParams");
......@@ -13,7 +11,6 @@ var mobileNetV1_1 = require("./mobileNetV1");
var nonMaxSuppression_1 = require("./nonMaxSuppression");
var outputLayer_1 = require("./outputLayer");
var predictionLayer_1 = require("./predictionLayer");
var resizeLayer_1 = require("./resizeLayer");
var FaceDetectionNet = /** @class */ (function () {
function FaceDetectionNet() {
}
......@@ -42,37 +39,28 @@ var FaceDetectionNet = /** @class */ (function () {
FaceDetectionNet.prototype.extractWeights = function (weights) {
this._params = extractParams_1.extractParams(weights);
};
FaceDetectionNet.prototype.forwardTensor = function (imgTensor) {
FaceDetectionNet.prototype.forwardInput = function (input) {
var _this = this;
if (!this._params) {
throw new Error('FaceDetectionNet - load model before inference');
}
return tf.tidy(function () {
var resized = resizeLayer_1.resizeLayer(imgTensor);
var features = mobileNetV1_1.mobileNetV1(resized, _this._params.mobilenetv1_params);
var batchTensor = input.toBatchTensor(512, false);
var x = tf.sub(tf.mul(batchTensor, tf.scalar(0.007843137718737125)), tf.scalar(1));
var features = mobileNetV1_1.mobileNetV1(x, _this._params.mobilenetv1_params);
var _a = predictionLayer_1.predictionLayer(features.out, features.conv11, _this._params.prediction_layer_params), boxPredictions = _a.boxPredictions, classPredictions = _a.classPredictions;
return outputLayer_1.outputLayer(boxPredictions, classPredictions, _this._params.output_layer_params);
});
};
FaceDetectionNet.prototype.forward = function (input) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _this = this;
var netInput, _a;
var _a;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!(input instanceof tf.Tensor)) return [3 /*break*/, 1];
_a = input;
return [3 /*break*/, 3];
case 1: return [4 /*yield*/, toNetInput_1.toNetInput(input)];
case 2:
_a = _b.sent();
_b.label = 3;
case 3:
netInput = _a;
return [2 /*return*/, tf.tidy(function () {
return _this.forwardTensor(padToSquare_1.padToSquare(getImageTensor_1.getImageTensor(netInput)));
})];
_a = this.forwardInput;
return [4 /*yield*/, toNetInput_1.toNetInput(input, true)];
case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])];
}
});
});
......@@ -81,42 +69,27 @@ var FaceDetectionNet = /** @class */ (function () {
if (minConfidence === void 0) { minConfidence = 0.8; }
if (maxResults === void 0) { maxResults = 100; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _this = this;
var netInput, _a, paddedHeightRelative, paddedWidthRelative, imageDimensions, _b, _boxes, _scores, boxes, scores, i, scoresData, _c, _d, iouThreshold, indices, results;
return tslib_1.__generator(this, function (_e) {
switch (_e.label) {
case 0:
if (!(input instanceof tf.Tensor)) return [3 /*break*/, 1];
_a = input;
return [3 /*break*/, 3];
case 1: return [4 /*yield*/, toNetInput_1.toNetInput(input)];
case 2:
_a = _e.sent();
_e.label = 3;
case 3:
netInput = _a;
paddedHeightRelative = 1, paddedWidthRelative = 1;
_b = tf.tidy(function () {
var imgTensor = getImageTensor_1.getImageTensor(netInput);
var _a = imgTensor.shape.slice(1), height = _a[0], width = _a[1];
imageDimensions = { width: width, height: height };
imgTensor = padToSquare_1.padToSquare(imgTensor);
paddedHeightRelative = imgTensor.shape[1] / height;
paddedWidthRelative = imgTensor.shape[2] / width;
return _this.forwardTensor(imgTensor);
}), _boxes = _b.boxes, _scores = _b.scores;
var netInput, _a, _boxes, _scores, boxes, scores, i, scoresData, _b, _c, iouThreshold, indices, paddedHeightRelative, paddedWidthRelative, results;
return tslib_1.__generator(this, function (_d) {
switch (_d.label) {
case 0: return [4 /*yield*/, toNetInput_1.toNetInput(input, true)];
case 1:
netInput = _d.sent();
_a = this.forwardInput(netInput), _boxes = _a.boxes, _scores = _a.scores;
boxes = _boxes[0];
scores = _scores[0];
for (i = 1; i < _boxes.length; i++) {
_boxes[i].dispose();
_scores[i].dispose();
}
_d = (_c = Array).from;
_c = (_b = Array).from;
return [4 /*yield*/, scores.data()];
case 4:
scoresData = _d.apply(_c, [_e.sent()]);
case 2:
scoresData = _c.apply(_b, [_d.sent()]);
iouThreshold = 0.5;
indices = nonMaxSuppression_1.nonMaxSuppression(boxes, scoresData, maxResults, iouThreshold, minConfidence);
paddedHeightRelative = (netInput.getPaddings(0).y + netInput.getInputHeight(0)) / netInput.getInputHeight(0);
paddedWidthRelative = (netInput.getPaddings(0).x + netInput.getInputWidth(0)) / netInput.getInputWidth(0);
results = indices
.map(function (idx) {
var _a = [
......@@ -127,7 +100,10 @@ var FaceDetectionNet = /** @class */ (function () {
Math.max(0, boxes.get(idx, 1)),
Math.min(1.0, boxes.get(idx, 3))
].map(function (val) { return val * paddedWidthRelative; }), left = _b[0], right = _b[1];
return new FaceDetection_1.FaceDetection(scoresData[idx], new Rect_1.Rect(left, top, right - left, bottom - top), imageDimensions);
return new FaceDetection_1.FaceDetection(scoresData[idx], new Rect_1.Rect(left, top, right - left, bottom - top), {
height: netInput.getInputHeight(0),
width: netInput.getInputWidth(0)
});
});
boxes.dispose();
scores.dispose();
......
{"version":3,"file":"FaceDetectionNet.js","sourceRoot":"","sources":["../../src/faceDetectionNet/FaceDetectionNet.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
{"version":3,"file":"FaceDetectionNet.js","sourceRoot":"","sources":["../../src/faceDetectionNet/FaceDetectionNet.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
export declare function resizeLayer(x: tf.Tensor4D): tf.Tensor<tf.Rank>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tf = require("@tensorflow/tfjs-core");
var resizedImageSize = [512, 512];
var weight = tf.scalar(0.007843137718737125);
var bias = tf.scalar(1);
function resizeLayer(x) {
return tf.tidy(function () {
var resized = tf.image.resizeBilinear(x, resizedImageSize, false);
return tf.sub(tf.mul(resized, weight), bias);
});
}
exports.resizeLayer = resizeLayer;
//# sourceMappingURL=resizeLayer.js.map
\ No newline at end of file
{"version":3,"file":"resizeLayer.js","sourceRoot":"","sources":["../../src/faceDetectionNet/resizeLayer.ts"],"names":[],"mappings":";;AAAA,0CAA4C;AAE5C,IAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,GAAG,CAAqB,CAAA;AACvD,IAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAA;AAC9C,IAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;AAEzB,qBAA4B,CAAc;IACxC,OAAO,EAAE,CAAC,IAAI,CAAC;QAEb,IAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,CAAA;QACnE,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAA;IAE9C,CAAC,CAAC,CAAA;AACJ,CAAC;AAPD,kCAOC"}
\ No newline at end of file
......@@ -6,7 +6,7 @@ export declare class FaceLandmarkNet {
private _params;
load(weightsOrUrl: Float32Array | string | undefined): Promise<void>;
extractWeights(weights: Float32Array): void;
forwardTensor(imgTensor: tf.Tensor4D): tf.Tensor2D;
forward(input: tf.Tensor | NetInput | TNetInput): Promise<tf.Tensor2D>;
detectLandmarks(input: tf.Tensor | NetInput | TNetInput): Promise<FaceLandmarks>;
forwardInput(input: NetInput): tf.Tensor2D;
forward(input: TNetInput): Promise<tf.Tensor2D>;
detectLandmarks(input: TNetInput): Promise<FaceLandmarks | FaceLandmarks[]>;
}
......@@ -3,8 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var tf = require("@tensorflow/tfjs-core");
var convLayer_1 = require("../commons/convLayer");
var getImageTensor_1 = require("../commons/getImageTensor");
var padToSquare_1 = require("../padToSquare");
var Point_1 = require("../Point");
var toNetInput_1 = require("../toNetInput");
var utils_1 = require("../utils");
......@@ -47,20 +45,14 @@ var FaceLandmarkNet = /** @class */ (function () {
FaceLandmarkNet.prototype.extractWeights = function (weights) {
this._params = extractParams_1.extractParams(weights);
};
FaceLandmarkNet.prototype.forwardTensor = function (imgTensor) {
FaceLandmarkNet.prototype.forwardInput = function (input) {
var params = this._params;
if (!params) {
throw new Error('FaceLandmarkNet - load model before inference');
}
return tf.tidy(function () {
var _a = imgTensor.shape.slice(), batchSize = _a[0], height = _a[1], width = _a[2];
var x = padToSquare_1.padToSquare(imgTensor, true);
var _b = x.shape.slice(1), heightAfterPadding = _b[0], widthAfterPadding = _b[1];
// work with 128 x 128 sized face images
if (heightAfterPadding !== 128 || widthAfterPadding !== 128) {
x = tf.image.resizeBilinear(x, [128, 128]);
}
var out = conv(x, params.conv0_params);
var batchTensor = input.toBatchTensor(128, true);
var out = conv(batchTensor, params.conv0_params);
out = maxPool(out);
out = conv(out, params.conv1_params);
out = conv(out, params.conv2_params);
......@@ -78,37 +70,34 @@ var FaceLandmarkNet = /** @class */ (function () {
return tf.stack([
tf.fill([68], fillX),
tf.fill([68], fillY)
], 1).as2D(batchSize, 136);
], 1).as2D(1, 136).as1D();
};
/* shift coordinates back, to undo centered padding
((x * widthAfterPadding) - shiftX) / width
((y * heightAfterPadding) - shiftY) / height
x = ((x * widthAfterPadding) - shiftX) / width
y = ((y * heightAfterPadding) - shiftY) / height
*/
var shiftX = Math.floor(Math.abs(widthAfterPadding - width) / 2);
var shiftY = Math.floor(Math.abs(heightAfterPadding - height) / 2);
var landmarkTensor = fc1
.mul(createInterleavedTensor(widthAfterPadding, heightAfterPadding))
.sub(createInterleavedTensor(shiftX, shiftY))
.div(createInterleavedTensor(width, height));
return landmarkTensor;
var landmarkTensors = fc1
.mul(tf.stack(Array.from(Array(input.batchSize), function (_, batchIdx) {
return createInterleavedTensor(input.getPaddings(batchIdx).x + input.getInputWidth(batchIdx), input.getPaddings(batchIdx).y + input.getInputHeight(batchIdx));
})))
.sub(tf.stack(Array.from(Array(input.batchSize), function (_, batchIdx) {
return createInterleavedTensor(Math.floor(input.getPaddings(batchIdx).x / 2), Math.floor(input.getPaddings(batchIdx).y / 2));
})))
.div(tf.stack(Array.from(Array(input.batchSize), function (_, batchIdx) {
return createInterleavedTensor(input.getInputWidth(batchIdx), input.getInputHeight(batchIdx));
})));
return landmarkTensors;
});
};
FaceLandmarkNet.prototype.forward = function (input) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var netInput, _a;
var _a;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!(input instanceof tf.Tensor)) return [3 /*break*/, 1];
_a = input;
return [3 /*break*/, 3];
case 1: return [4 /*yield*/, toNetInput_1.toNetInput(input)];
case 2:
_a = _b.sent();
_b.label = 3;
case 3:
netInput = _a;
return [2 /*return*/, this.forwardTensor(getImageTensor_1.getImageTensor(netInput))];
_a = this.forwardInput;
return [4 /*yield*/, toNetInput_1.toNetInput(input, true)];
case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])];
}
});
});
......@@ -116,33 +105,37 @@ var FaceLandmarkNet = /** @class */ (function () {
FaceLandmarkNet.prototype.detectLandmarks = function (input) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _this = this;
var netInput, _a, imageDimensions, outTensor, faceLandmarksArray, _b, _c, xCoords, yCoords;
return tslib_1.__generator(this, function (_d) {
switch (_d.label) {
case 0:
if (!(input instanceof tf.Tensor)) return [3 /*break*/, 1];
_a = input;
return [3 /*break*/, 3];
case 1: return [4 /*yield*/, toNetInput_1.toNetInput(input)];
var netInput, landmarkTensors, landmarksForBatch;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, toNetInput_1.toNetInput(input, true)];
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 FaceLandmarks_1.FaceLandmarks(Array(68).fill(0).map(function (_, i) { return new Point_1.Point(xCoords[i], yCoords[i]); }), {
height: netInput.getInputHeight(batchIdx),
width: netInput.getInputWidth(batchIdx),
})];
}
});
}); }))];
case 2:
_a = _d.sent();
_d.label = 3;
case 3:
netInput = _a;
outTensor = tf.tidy(function () {
var imgTensor = getImageTensor_1.getImageTensor(netInput);
var _a = imgTensor.shape.slice(1), height = _a[0], width = _a[1];
imageDimensions = { width: width, height: height };
return _this.forwardTensor(imgTensor);
});
_c = (_b = Array).from;
return [4 /*yield*/, outTensor.data()];
case 4:
faceLandmarksArray = _c.apply(_b, [_d.sent()]);
outTensor.dispose();
xCoords = faceLandmarksArray.filter(function (_, i) { return utils_1.isEven(i); });
yCoords = faceLandmarksArray.filter(function (_, i) { return !utils_1.isEven(i); });
return [2 /*return*/, new FaceLandmarks_1.FaceLandmarks(Array(68).fill(0).map(function (_, i) { return new Point_1.Point(xCoords[i], yCoords[i]); }), imageDimensions)];
landmarksForBatch = _a.sent();
landmarkTensors.forEach(function (t) { return t.dispose(); });
return [2 /*return*/, netInput.isBatchInput
? landmarksForBatch
: landmarksForBatch[0]];
}
});
});
......
{"version":3,"file":"FaceLandmarkNet.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/FaceLandmarkNet.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
{"version":3,"file":"FaceLandmarkNet.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/FaceLandmarkNet.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
......@@ -5,6 +5,7 @@ export declare class FaceRecognitionNet {
private _params;
load(weightsOrUrl: Float32Array | string | undefined): Promise<void>;
extractWeights(weights: Float32Array): void;
forward(input: tf.Tensor | NetInput | TNetInput): Promise<tf.Tensor2D>;
computeFaceDescriptor(input: tf.Tensor | NetInput | TNetInput): Promise<Float32Array>;
forwardInput(input: NetInput): Promise<tf.Tensor2D>;
forward(input: TNetInput): Promise<tf.Tensor2D>;
computeFaceDescriptor(input: TNetInput): Promise<Float32Array>;
}
......@@ -2,8 +2,6 @@
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var tf = require("@tensorflow/tfjs-core");
var getImageTensor_1 = require("../commons/getImageTensor");
var padToSquare_1 = require("../padToSquare");
var toNetInput_1 = require("../toNetInput");
var convLayer_1 = require("./convLayer");
var extractParams_1 = require("./extractParams");
......@@ -38,76 +36,65 @@ var FaceRecognitionNet = /** @class */ (function () {
FaceRecognitionNet.prototype.extractWeights = function (weights) {
this._params = extractParams_1.extractParams(weights);
};
FaceRecognitionNet.prototype.forward = function (input) {
FaceRecognitionNet.prototype.forwardInput = function (input) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _this = this;
var netInput, _a;
return tslib_1.__generator(this, function (_a) {
if (!this._params) {
throw new Error('FaceRecognitionNet - load model before inference');
}
return [2 /*return*/, tf.tidy(function () {
var batchTensor = input.toBatchTensor(150, true);
var normalized = normalize_1.normalize(batchTensor);
var out = convLayer_1.convDown(normalized, _this._params.conv32_down);
out = tf.maxPool(out, 3, 2, 'valid');
out = residualLayer_1.residual(out, _this._params.conv32_1);
out = residualLayer_1.residual(out, _this._params.conv32_2);
out = residualLayer_1.residual(out, _this._params.conv32_3);
out = residualLayer_1.residualDown(out, _this._params.conv64_down);
out = residualLayer_1.residual(out, _this._params.conv64_1);
out = residualLayer_1.residual(out, _this._params.conv64_2);
out = residualLayer_1.residual(out, _this._params.conv64_3);
out = residualLayer_1.residualDown(out, _this._params.conv128_down);
out = residualLayer_1.residual(out, _this._params.conv128_1);
out = residualLayer_1.residual(out, _this._params.conv128_2);
out = residualLayer_1.residualDown(out, _this._params.conv256_down);
out = residualLayer_1.residual(out, _this._params.conv256_1);
out = residualLayer_1.residual(out, _this._params.conv256_2);
out = residualLayer_1.residualDown(out, _this._params.conv256_down_out);
var globalAvg = out.mean([1, 2]);
var fullyConnected = tf.matMul(globalAvg, _this._params.fc);
return fullyConnected;
})];
});
});
};
FaceRecognitionNet.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:
if (!this._params) {
throw new Error('FaceRecognitionNet - load model before inference');
}
if (!(input instanceof tf.Tensor)) return [3 /*break*/, 1];
_a = input;
return [3 /*break*/, 3];
case 1: return [4 /*yield*/, toNetInput_1.toNetInput(input)];
case 2:
_a = _b.sent();
_b.label = 3;
case 3:
netInput = _a;
return [2 /*return*/, tf.tidy(function () {
var x = padToSquare_1.padToSquare(getImageTensor_1.getImageTensor(netInput), true);
// work with 150 x 150 sized face images
if (x.shape[1] !== 150 || x.shape[2] !== 150) {
x = tf.image.resizeBilinear(x, [150, 150]);
}
x = normalize_1.normalize(x);
var out = convLayer_1.convDown(x, _this._params.conv32_down);
out = tf.maxPool(out, 3, 2, 'valid');
out = residualLayer_1.residual(out, _this._params.conv32_1);
out = residualLayer_1.residual(out, _this._params.conv32_2);
out = residualLayer_1.residual(out, _this._params.conv32_3);
out = residualLayer_1.residualDown(out, _this._params.conv64_down);
out = residualLayer_1.residual(out, _this._params.conv64_1);
out = residualLayer_1.residual(out, _this._params.conv64_2);
out = residualLayer_1.residual(out, _this._params.conv64_3);
out = residualLayer_1.residualDown(out, _this._params.conv128_down);
out = residualLayer_1.residual(out, _this._params.conv128_1);
out = residualLayer_1.residual(out, _this._params.conv128_2);
out = residualLayer_1.residualDown(out, _this._params.conv256_down);
out = residualLayer_1.residual(out, _this._params.conv256_1);
out = residualLayer_1.residual(out, _this._params.conv256_2);
out = residualLayer_1.residualDown(out, _this._params.conv256_down_out);
var globalAvg = out.mean([1, 2]);
var fullyConnected = tf.matMul(globalAvg, _this._params.fc);
return fullyConnected;
})];
_a = this.forwardInput;
return [4 /*yield*/, toNetInput_1.toNetInput(input, true)];
case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])];
}
});
});
};
FaceRecognitionNet.prototype.computeFaceDescriptor = function (input) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var netInput, _a, result, data;
var result, _a, data;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!(input instanceof tf.Tensor)) return [3 /*break*/, 1];
_a = input;
return [3 /*break*/, 3];
case 1: return [4 /*yield*/, toNetInput_1.toNetInput(input)];
_a = this.forward;
return [4 /*yield*/, toNetInput_1.toNetInput(input, true)];
case 1: return [4 /*yield*/, _a.apply(this, [_b.sent()])];
case 2:
_a = _b.sent();
_b.label = 3;
case 3:
netInput = _a;
return [4 /*yield*/, this.forward(netInput)];
case 4:
result = _b.sent();
return [4 /*yield*/, result.data()];
case 5:
case 3:
data = _b.sent();
result.dispose();
return [2 /*return*/, data];
......
{"version":3,"file":"FaceRecognitionNet.js","sourceRoot":"","sources":["../../src/faceRecognitionNet/FaceRecognitionNet.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
{"version":3,"file":"FaceRecognitionNet.js","sourceRoot":"","sources":["../../src/faceRecognitionNet/FaceRecognitionNet.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { NetInput } from './NetInput';
import { TNetInput } from './types';
export declare function getImageTensor(input: tf.Tensor | NetInput | TNetInput): tf.Tensor4D;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tf = require("@tensorflow/tfjs-core");
var NetInput_1 = require("./NetInput");
function getImageTensor(input) {
return tf.tidy(function () {
if (input instanceof tf.Tensor) {
var rank = input.shape.length;
if (rank !== 3 && rank !== 4) {
throw new Error('input tensor must be of rank 3 or 4');
}
return (rank === 3 ? input.expandDims(0) : input).toFloat();
}
var netInput = input instanceof NetInput_1.NetInput ? input : new NetInput_1.NetInput(input);
return tf.concat(netInput.canvases.map(function (canvas) {
return tf.fromPixels(canvas).expandDims(0).toFloat();
}));
});
}
exports.getImageTensor = getImageTensor;
//# sourceMappingURL=getImageTensor.js.map
\ No newline at end of file
{"version":3,"file":"getImageTensor.js","sourceRoot":"","sources":["../src/getImageTensor.ts"],"names":[],"mappings":";;AAAA,0CAA4C;AAE5C,uCAAsC;AAGtC,wBAA+B,KAAuC;IACpE,OAAO,EAAE,CAAC,IAAI,CAAC;QACb,IAAI,KAAK,YAAY,EAAE,CAAC,MAAM,EAAE;YAC9B,IAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAA;YAC/B,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE;gBAC5B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAA;aACvD;YAED,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,EAAiB,CAAA;SAC3E;QAED,IAAM,QAAQ,GAAG,KAAK,YAAY,mBAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,mBAAQ,CAAC,KAAK,CAAC,CAAA;QACxE,OAAO,EAAE,CAAC,MAAM,CACd,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAA,MAAM;YAC1B,OAAA,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE;QAA7C,CAA6C,CAC9C,CACa,CAAA;IAClB,CAAC,CAAC,CAAA;AACJ,CAAC;AAlBD,wCAkBC"}
\ No newline at end of file
......@@ -4,9 +4,9 @@ import { FaceDetectionNet } from './faceDetectionNet/FaceDetectionNet';
import { FaceLandmarkNet } from './faceLandmarkNet/FaceLandmarkNet';
import { FaceLandmarks } from './faceLandmarkNet/FaceLandmarks';
import { FaceRecognitionNet } from './faceRecognitionNet/FaceRecognitionNet';
import { FullFaceDescription } from './FullFaceDescription';
import { NetInput } from './NetInput';
import { TNetInput } from './types';
import { FullFaceDescription } from './FullFaceDescription';
export declare const detectionNet: FaceDetectionNet;
export declare const landmarkNet: FaceLandmarkNet;
export declare const recognitionNet: FaceRecognitionNet;
......@@ -14,7 +14,7 @@ export declare function loadFaceDetectionModel(url: string): Promise<void>;
export declare function loadFaceLandmarkModel(url: string): Promise<void>;
export declare function loadFaceRecognitionModel(url: string): Promise<void>;
export declare function loadModels(url: string): Promise<[void, void, void]>;
export declare function locateFaces(input: tf.Tensor | NetInput | TNetInput, minConfidence?: number, maxResults?: number): Promise<FaceDetection[]>;
export declare function detectLandmarks(input: tf.Tensor | NetInput | TNetInput): Promise<FaceLandmarks>;
export declare function computeFaceDescriptor(input: tf.Tensor | NetInput | TNetInput): Promise<Float32Array>;
export declare function locateFaces(input: TNetInput, minConfidence?: number, maxResults?: number): Promise<FaceDetection[]>;
export declare function detectLandmarks(input: TNetInput): Promise<FaceLandmarks | FaceLandmarks[]>;
export declare function computeFaceDescriptor(input: TNetInput): Promise<Float32Array>;
export declare const allFaces: (input: tf.Tensor | NetInput | TNetInput, minConfidence: number) => 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,KAAuC,EACvC,aAAsB,EACtB,UAAmB;IAEnB,OAAO,oBAAY,CAAC,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,CAAC,CAAA;AACnE,CAAC;AAND,kCAMC;AAED,yBACE,KAAuC;IAEvC,OAAO,mBAAW,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;AAC3C,CAAC;AAJD,0CAIC;AAED,+BACE,KAAuC;IAEvC,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"}
\ No newline at end of file
{"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"}
\ No newline at end of file
{"version":3,"file":"padToSquare.js","sourceRoot":"","sources":["../src/padToSquare.ts"],"names":[],"mappings":";;AAAA,0CAA4C;AAI5C;;;;;;GAMG;AACH,qBACE,SAAsB,EACtB,aAA8B;IAA9B,8BAAA,EAAA,qBAA8B;IAE9B,OAAO,EAAE,CAAC,IAAI,CAAC;QAEP,IAAA,6BAA0C,EAAzC,cAAM,EAAE,aAAK,CAA4B;QAChD,IAAI,MAAM,KAAK,KAAK,EAAE;YACpB,OAAO,SAAS,CAAA;SACjB;QAED,IAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,CAAA;QACxC,IAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACrE,IAAM,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAE1C,IAAM,mBAAmB,GAAG,UAAC,aAAqB;YAChD,IAAM,kBAAkB,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;YAClD,kBAAkB,CAAC,WAAW,CAAC,GAAG,aAAa,CAAA;YAC/C,OAAO,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAA;QACvC,CAAC,CAAA;QAED,IAAM,mBAAmB,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAA;QAC9D,IAAM,sBAAsB,GAAG,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QAE/E,IAAM,oBAAoB,GAAG,aAAa,IAAI,sBAAsB;YAClE,CAAC,CAAC,mBAAmB,CAAC,sBAAsB,CAAC;YAC7C,CAAC,CAAC,IAAI,CAAA;QAER,IAAM,cAAc,GAAG;YACrB,oBAAoB;YACpB,SAAS;YACT,mBAAmB;SACpB;aACE,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,KAAK,IAAI,EAAV,CAAU,CAAkB,CAAA;QAC3C,OAAO,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;IAC/C,CAAC,CAAC,CAAA;AACJ,CAAC;AApCD,kCAoCC"}
\ No newline at end of file
{"version":3,"file":"padToSquare.js","sourceRoot":"","sources":["../src/padToSquare.ts"],"names":[],"mappings":";;AAAA,0CAA4C;AAE5C;;;;;;GAMG;AACH,qBACE,SAAsB,EACtB,aAA8B;IAA9B,8BAAA,EAAA,qBAA8B;IAE9B,OAAO,EAAE,CAAC,IAAI,CAAC;QAEP,IAAA,6BAA0C,EAAzC,cAAM,EAAE,aAAK,CAA4B;QAChD,IAAI,MAAM,KAAK,KAAK,EAAE;YACpB,OAAO,SAAS,CAAA;SACjB;QAED,IAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,CAAA;QACxC,IAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACrE,IAAM,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAE1C,IAAM,mBAAmB,GAAG,UAAC,aAAqB;YAChD,IAAM,kBAAkB,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;YAClD,kBAAkB,CAAC,WAAW,CAAC,GAAG,aAAa,CAAA;YAC/C,OAAO,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAA;QACvC,CAAC,CAAA;QAED,IAAM,mBAAmB,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAA;QAC9D,IAAM,sBAAsB,GAAG,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QAE/E,IAAM,oBAAoB,GAAG,aAAa,IAAI,sBAAsB;YAClE,CAAC,CAAC,mBAAmB,CAAC,sBAAsB,CAAC;YAC7C,CAAC,CAAC,IAAI,CAAA;QAER,IAAM,cAAc,GAAG;YACrB,oBAAoB;YACpB,SAAS;YACT,mBAAmB;SACpB;aACE,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,KAAK,IAAI,EAAV,CAAU,CAAkB,CAAA;QAC3C,OAAO,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;IAC/C,CAAC,CAAC,CAAA;AACJ,CAAC;AApCD,kCAoCC"}
\ No newline at end of file
......@@ -5,6 +5,8 @@ import { TNetInput } from './types';
* to be finished loading.
*
* @param input The input, which can be a media element or an array of different media elements.
* @param manageCreatedInput If a new NetInput instance is created from the inputs, this flag
* determines, whether to set the NetInput as managed or not.
* @returns A NetInput instance, which can be passed into one of the neural networks.
*/
export declare function toNetInput(input: NetInput | TNetInput): Promise<NetInput>;
export declare function toNetInput(inputs: TNetInput, manageCreatedInput?: boolean): Promise<NetInput>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var isMediaElement_1 = require("./commons/isMediaElement");
var isTensor_1 = require("./commons/isTensor");
var NetInput_1 = require("./NetInput");
var utils_1 = require("./utils");
/**
......@@ -8,39 +10,61 @@ var utils_1 = require("./utils");
* to be finished loading.
*
* @param input The input, which can be a media element or an array of different media elements.
* @param manageCreatedInput If a new NetInput instance is created from the inputs, this flag
* determines, whether to set the NetInput as managed or not.
* @returns A NetInput instance, which can be passed into one of the neural networks.
*/
function toNetInput(input) {
function toNetInput(inputs, manageCreatedInput) {
if (manageCreatedInput === void 0) { manageCreatedInput = false; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var mediaArgArray, medias;
var afterCreate, inputArgArray, getIdxHint, inputArray;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (input instanceof NetInput_1.NetInput) {
return [2 /*return*/, input];
if (inputs instanceof NetInput_1.NetInput) {
return [2 /*return*/, inputs];
}
mediaArgArray = Array.isArray(input)
? input
: [input];
if (!mediaArgArray.length) {
afterCreate = function (netInput) { return manageCreatedInput
? netInput.managed()
: netInput; };
if (isTensor_1.isTensor4D(inputs)) {
return [2 /*return*/, afterCreate(new NetInput_1.NetInput(inputs))];
}
inputArgArray = Array.isArray(inputs)
? inputs
: [inputs];
if (!inputArgArray.length) {
throw new Error('toNetInput - empty array passed as input');
}
medias = mediaArgArray.map(utils_1.getElement);
medias.forEach(function (media, i) {
if (!(media instanceof HTMLImageElement || media instanceof HTMLVideoElement || media instanceof HTMLCanvasElement)) {
var idxHint = Array.isArray(input) ? " at input index " + i + ":" : '';
if (typeof mediaArgArray[i] === 'string') {
throw new Error("toNetInput -" + idxHint + " string passed, but could not resolve HTMLElement for element id");
getIdxHint = function (idx) { return Array.isArray(inputs) ? " at input index " + idx + ":" : ''; };
inputArray = inputArgArray
.map(utils_1.resolveInput)
.map(function (input, i) {
if (isTensor_1.isTensor4D(input)) {
// if tf.Tensor4D is passed in the input array, the batch size has to be 1
var batchSize = input.shape[0];
if (batchSize !== 1) {
throw new Error("toNetInput -" + getIdxHint(i) + " tf.Tensor4D with batchSize " + batchSize + " passed, but not supported in input array");
}
// to tf.Tensor3D
return input.reshape(input.shape.slice(1));
}
return input;
});
inputArray.forEach(function (input, i) {
if (!isMediaElement_1.isMediaElement(input) && !isTensor_1.isTensor3D(input)) {
if (typeof inputArgArray[i] === 'string') {
throw new Error("toNetInput -" + getIdxHint(i) + " string passed, but could not resolve HTMLElement for element id " + inputArgArray[i]);
}
throw new Error("toNetInput -" + idxHint + " expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement, or to be an element id");
throw new Error("toNetInput -" + getIdxHint(i) + " expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | tf.Tensor3D, or to be an element id");
}
});
// wait for all media elements being loaded
return [4 /*yield*/, Promise.all(medias.map(function (media) { return utils_1.awaitMediaLoaded(media); }))];
return [4 /*yield*/, Promise.all(inputArray.map(function (input) { return isMediaElement_1.isMediaElement(input) && utils_1.awaitMediaLoaded(input); }))];
case 1:
// wait for all media elements being loaded
_a.sent();
return [2 /*return*/, new NetInput_1.NetInput(medias)];
return [2 /*return*/, afterCreate(new NetInput_1.NetInput(inputArray, Array.isArray(inputs)))];
}
});
});
......
{"version":3,"file":"toNetInput.js","sourceRoot":"","sources":["../src/toNetInput.ts"],"names":[],"mappings":";;;AAAA,uCAAsC;AAEtC,iCAAuD;AAEvD;;;;;;GAMG;AACH,oBACE,KAA2B;;;;;;oBAE3B,IAAI,KAAK,YAAY,mBAAQ,EAAE;wBAC7B,sBAAO,KAAK,EAAA;qBACb;oBAEK,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;wBACtC,CAAC,CAAC,KAAK;wBACP,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;oBAEb,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;wBACzB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;qBAC5D;oBAEK,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,kBAAU,CAAC,CAAA;oBAE5C,MAAM,CAAC,OAAO,CAAC,UAAC,KAAK,EAAE,CAAC;wBACtB,IAAI,CAAC,CAAC,KAAK,YAAY,gBAAgB,IAAI,KAAK,YAAY,gBAAgB,IAAI,KAAK,YAAY,iBAAiB,CAAC,EAAE;4BACnH,IAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,qBAAmB,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,CAAA;4BACnE,IAAI,OAAO,aAAa,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;gCACxC,MAAM,IAAI,KAAK,CAAC,iBAAe,OAAO,qEAAkE,CAAC,CAAA;6BAC1G;4BACD,MAAM,IAAI,KAAK,CAAC,iBAAe,OAAO,kHAA+G,CAAC,CAAA;yBACvJ;oBACH,CAAC,CAAC,CAAA;oBAEF,2CAA2C;oBAC3C,qBAAM,OAAO,CAAC,GAAG,CACf,MAAM,CAAC,GAAG,CAAC,UAAA,KAAK,IAAI,OAAA,wBAAgB,CAAC,KAAK,CAAC,EAAvB,CAAuB,CAAC,CAC7C,EAAA;;oBAHD,2CAA2C;oBAC3C,SAEC,CAAA;oBAED,sBAAO,IAAI,mBAAQ,CAAC,MAAM,CAAC,EAAA;;;;CAC5B;AAjCD,gCAiCC"}
\ No newline at end of file
{"version":3,"file":"toNetInput.js","sourceRoot":"","sources":["../src/toNetInput.ts"],"names":[],"mappings":";;;AAEA,2DAA0D;AAC1D,+CAA4D;AAC5D,uCAAsC;AAEtC,iCAAyD;AAEzD;;;;;;;;GAQG;AACH,oBACE,MAAiB,EACjB,kBAAmC;IAAnC,mCAAA,EAAA,0BAAmC;;;;;;oBAEnC,IAAI,MAAM,YAAY,mBAAQ,EAAE;wBAC9B,sBAAO,MAAM,EAAA;qBACd;oBAEK,WAAW,GAAG,UAAC,QAAkB,IAAK,OAAA,kBAAkB;wBAC5D,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE;wBACpB,CAAC,CAAC,QAAQ,EAFgC,CAEhC,CAAA;oBAEZ,IAAI,qBAAU,CAAC,MAAM,CAAC,EAAE;wBACtB,sBAAO,WAAW,CAAC,IAAI,mBAAQ,CAAC,MAAqB,CAAC,CAAC,EAAA;qBACxD;oBAEG,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;wBACrC,CAAC,CAAC,MAAM;wBACR,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;oBAEd,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;wBACzB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;qBAC5D;oBAEK,UAAU,GAAG,UAAC,GAAW,IAAK,OAAA,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,qBAAmB,GAAG,MAAG,CAAC,CAAC,CAAC,EAAE,EAAtD,CAAsD,CAAA;oBAEpF,UAAU,GAAG,aAAa;yBAC7B,GAAG,CAAC,oBAAY,CAAC;yBACjB,GAAG,CAAC,UAAC,KAAK,EAAE,CAAC;wBACZ,IAAI,qBAAU,CAAC,KAAK,CAAC,EAAE;4BACrB,0EAA0E;4BAC1E,IAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;4BAChC,IAAI,SAAS,KAAK,CAAC,EAAE;gCACnB,MAAM,IAAI,KAAK,CAAC,iBAAe,UAAU,CAAC,CAAC,CAAC,oCAA+B,SAAS,8CAA2C,CAAC,CAAA;6BACjI;4BACD,iBAAiB;4BACjB,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;yBAC3C;wBACD,OAAO,KAAK,CAAA;oBACd,CAAC,CAAC,CAAA;oBAEJ,UAAU,CAAC,OAAO,CAAC,UAAC,KAAK,EAAE,CAAC;wBAC1B,IAAI,CAAC,+BAAc,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAU,CAAC,KAAK,CAAC,EAAE;4BAEhD,IAAI,OAAO,aAAa,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;gCACxC,MAAM,IAAI,KAAK,CAAC,iBAAe,UAAU,CAAC,CAAC,CAAC,yEAAoE,aAAa,CAAC,CAAC,CAAG,CAAC,CAAA;6BACpI;4BAED,MAAM,IAAI,KAAK,CAAC,iBAAe,UAAU,CAAC,CAAC,CAAC,gIAA6H,CAAC,CAAA;yBAC3K;oBACH,CAAC,CAAC,CAAA;oBAEF,2CAA2C;oBAC3C,qBAAM,OAAO,CAAC,GAAG,CACf,UAAU,CAAC,GAAG,CAAC,UAAA,KAAK,IAAI,OAAA,+BAAc,CAAC,KAAK,CAAC,IAAI,wBAAgB,CAAC,KAAK,CAAC,EAAhD,CAAgD,CAAC,CAC1E,EAAA;;oBAHD,2CAA2C;oBAC3C,SAEC,CAAA;oBAED,sBAAO,WAAW,CAAC,IAAI,mBAAQ,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAA;;;;CACpE;AA1DD,gCA0DC"}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { NetInput } from './NetInput';
export declare type TMediaElement = HTMLImageElement | HTMLVideoElement | HTMLCanvasElement;
export declare type TNetInputArg = string | TMediaElement;
export declare type TNetInput = TNetInputArg | Array<TNetInputArg>;
export declare type TResolvedNetInput = TMediaElement | tf.Tensor3D | tf.Tensor4D;
export declare type TNetInputArg = string | TResolvedNetInput;
export declare type TNetInput = TNetInputArg | Array<TNetInputArg> | NetInput | tf.Tensor4D;
export declare type Dimensions = {
width: number;
height: number;
......
......@@ -3,7 +3,7 @@ import { Dimensions } from './types';
export declare function isFloat(num: number): boolean;
export declare function isEven(num: number): boolean;
export declare function round(num: number): number;
export declare function getElement(arg: string | any): any;
export declare function resolveInput(arg: string | any): any;
export declare function isLoaded(media: HTMLImageElement | HTMLVideoElement): boolean;
export declare function awaitMediaLoaded(media: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement): Promise<{}>;
export declare function getContext2dOrThrow(canvas: HTMLCanvasElement): CanvasRenderingContext2D;
......@@ -14,4 +14,4 @@ export declare function getMediaDimensions(media: HTMLImageElement | HTMLVideoEl
height: number;
};
export declare function bufferToImage(buf: Blob): Promise<HTMLImageElement>;
export declare function imageTensorToCanvas(imgTensor: tf.Tensor4D, canvas?: HTMLCanvasElement): Promise<HTMLCanvasElement>;
export declare function imageTensorToCanvas(imgTensor: tf.Tensor, canvas?: HTMLCanvasElement): Promise<HTMLCanvasElement>;
......@@ -2,6 +2,7 @@
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var tf = require("@tensorflow/tfjs-core");
var isTensor_1 = require("./commons/isTensor");
function isFloat(num) {
return num % 1 !== 0;
}
......@@ -14,13 +15,13 @@ function round(num) {
return Math.floor(num * 100) / 100;
}
exports.round = round;
function getElement(arg) {
function resolveInput(arg) {
if (typeof arg === 'string') {
return document.getElementById(arg);
}
return arg;
}
exports.getElement = getElement;
exports.resolveInput = resolveInput;
function isLoaded(media) {
return (media instanceof HTMLImageElement && media.complete)
|| (media instanceof HTMLVideoElement && media.readyState >= 3);
......@@ -105,12 +106,12 @@ function bufferToImage(buf) {
exports.bufferToImage = bufferToImage;
function imageTensorToCanvas(imgTensor, canvas) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var targetCanvas, _a, _, height, width, numChannels;
var targetCanvas, _a, height, width, numChannels;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
targetCanvas = canvas || document.createElement('canvas');
_a = imgTensor.shape, _ = _a[0], height = _a[1], width = _a[2], numChannels = _a[3];
_a = imgTensor.shape.slice(isTensor_1.isTensor4D(imgTensor) ? 1 : 0), height = _a[0], width = _a[1], numChannels = _a[2];
return [4 /*yield*/, tf.toPixels(imgTensor.as3D(height, width, numChannels).toInt(), targetCanvas)];
case 1:
_b.sent();
......
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
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.
......@@ -113,6 +113,10 @@ function renderNavBar(navbarId, exampleUri) {
{
uri: 'detect_and_recognize_faces',
name: 'Detect and Recognize Faces'
},
{
uri: 'batch_face_landmarks',
name: 'Batch Face Landmarks'
}
]
......@@ -152,9 +156,11 @@ function renderNavBar(navbarId, exampleUri) {
menuContent.appendChild(li)
examples
.filter(ex => ex.uri !== exampleUri)
.forEach(ex => {
const li = document.createElement('li')
if (ex.uri === exampleUri) {
li.style.background='#b0b0b0'
}
const a = document.createElement('a')
a.classList.add('waves-effect', 'waves-light')
a.href = ex.uri
......
......@@ -24,6 +24,9 @@ app.get('/detect_and_draw_faces', (req, res) => res.sendFile(path.join(viewsDir,
app.get('/detect_and_draw_landmarks', (req, res) => res.sendFile(path.join(viewsDir, 'detectAndDrawLandmarks.html')))
app.get('/face_alignment', (req, res) => res.sendFile(path.join(viewsDir, 'faceAlignment.html')))
app.get('/detect_and_recognize_faces', (req, res) => res.sendFile(path.join(viewsDir, 'detectAndRecognizeFaces.html')))
app.get('/batch_face_landmarks', (req, res) => res.sendFile(path.join(viewsDir, 'batchFaceLandmarks.html')))
app.post('/fetch_external_image', async (req, res) => {
const { imageUrl } = req.body
......
<!DOCTYPE html>
<html>
<head>
<script src="face-api.js"></script>
<script src="commons.js"></script>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
</head>
<body>
<div id="navbar"></div>
<div class="center-content page-container">
<div>
<div class="progress" id="loader">
<div class="indeterminate"></div>
</div>
<div class="row side-by-side">
<div class="row">
<label for="timeNoBatch">Time for processing each face seperately:</label>
<input disabled value="-" id="timeNoBatch" type="text" class="bold"/>
</div>
<div class="row">
<label for="timeBatch">Time for processing in Batch:</label>
<input disabled value="-" id="timeBatch" type="text" class="bold"/>
</div>
</div>
<div class="row side-by-side">
<div>
<label for="numImages">Num Images:</label>
<input id="numImages" type="text" class="bold" value="40"/>
</div>
<button
class="waves-effect waves-light btn"
onclick="measureTimingsAndDisplay()"
>
Ok
</button>
</div>
<div class="row side-by-side">
<div class="center-content">
<div id="faceContainer"></div>
</div>
</div>
</div>
</div>
<script>
let images = []
let landmarksByFace = []
let numImages = 40
function onNumImagesChanged(e) {
const val = parseInt(e.target.value) || 40
numImages = Math.min(Math.max(val, 0), 40)
e.target.value = numImages
}
function displayTimeStats(timeNoBatch, timeBatch) {
$('#timeNoBatch').val(`${timeNoBatch} ms`)
$('#timeBatch').val(`${timeBatch} ms`)
}
function drawLandmarkCanvas(img, landmarks) {
const canvas = faceapi.createCanvasFromMedia(img)
$('#faceContainer').append(canvas)
faceapi.drawLandmarks(canvas, landmarks, { lineWidth: 2 , drawLines: true })
}
async function runLandmarkDetection(useBatchInput) {
const ts = Date.now()
landmarksByFace = useBatchInput
? await faceapi.detectLandmarks(images.slice(0, numImages))
: await Promise.all(images.slice(0, numImages).map(img => faceapi.detectLandmarks(img)))
const time = Date.now() - ts
return time
}
async function measureTimings() {
const timeNoBatch = await runLandmarkDetection(false)
const timeBatch = await runLandmarkDetection(true)
return { timeNoBatch, timeBatch }
}
async function measureTimingsAndDisplay() {
const { timeNoBatch, timeBatch } = await measureTimings()
displayTimeStats(timeNoBatch, timeBatch)
$('#faceContainer').empty()
landmarksByFace.forEach((landmarks, i) => drawLandmarkCanvas(images[i], landmarks))
}
async function run() {
await faceapi.loadFaceLandmarkModel('/')
$('#loader').hide()
const allImgUris = classes
.map(clazz => Array.from(Array(5), (_, idx) => getFaceImageUri(clazz, idx + 1)))
.reduce((flat, arr) => flat.concat(arr))
images = await Promise.all(allImgUris.map(
async uri => faceapi.bufferToImage(await fetchImage(uri))
))
// warmup
await measureTimings()
// run
measureTimingsAndDisplay()
}
$(document).ready(function() {
$('#numImages').on('change', onNumImagesChanged)
renderNavBar('#navbar', 'batch_face_landmarks')
run()
})
</script>
</body>
</html>
\ No newline at end of file
......@@ -84,9 +84,12 @@
const detections = await faceapi.locateFaces(input, minConfidence)
faceapi.drawDetection('overlay', detections.map(det => det.forSize(width, height)))
const faceImages = await faceapi.extractFaces(input.canvases[0], detections)
const faceImages = await faceapi.extractFaces(input.inputs[0], detections)
$('#facesContainer').empty()
faceImages.forEach(canvas => $('#facesContainer').append(canvas))
// free memory for input tensors
input.dispose()
}
async function onSelectionChanged(uri) {
......
......@@ -103,6 +103,9 @@
faceapi.drawLandmarks(canvas, landmarksByFace, { lineWidth: drawLines ? 2 : 4, drawLines, color: 'red' })
faceapi.drawDetection('overlay', locations.map(det => det.forSize(width, height)))
// free memory for input tensors
input.dispose()
}
async function run() {
......
......@@ -84,7 +84,7 @@
const input = await faceapi.toNetInput(inputImgEl)
const locations = await faceapi.locateFaces(input, minConfidence)
const faceImages = await faceapi.extractFaces(input.canvases[0], locations)
const faceImages = await faceapi.extractFaces(input.inputs[0], locations)
// detect landmarks and get the aligned face image bounding boxes
const alignedFaceBoxes = await Promise.all(faceImages.map(
......@@ -93,7 +93,10 @@
return faceLandmarks.align(locations[i])
}
))
const alignedFaceImages = await faceapi.extractFaces(input.canvases[0], alignedFaceBoxes)
const alignedFaceImages = await faceapi.extractFaces(input.inputs[0], alignedFaceBoxes)
// free memory for input tensors
input.dispose()
$('#facesContainer').empty()
faceImages.forEach(async (faceCanvas, i) => {
......
......@@ -72,14 +72,13 @@
if(videoEl.paused || videoEl.ended || !modelLoaded)
return false
const input = await faceapi.toNetInput(videoEl)
const { width, height } = input
const { width, height } = faceapi.getMediaDimensions(videoEl)
const canvas = $('#overlay').get(0)
canvas.width = width
canvas.height = height
const ts = Date.now()
result = await faceapi.locateFaces(input, minConfidence)
result = await faceapi.locateFaces(videoEl, minConfidence)
displayTimeStats(Date.now() - ts)
faceapi.drawDetection('overlay', result.map(det => det.forSize(width, height)))
......
......@@ -2,6 +2,7 @@ const dataFiles = [
'test/images/*.jpg',
'test/images/*.png',
'test/data/*.json',
'test/media/*.mp4',
'weights/**/*'
].map(pattern => ({
pattern,
......@@ -24,6 +25,12 @@ module.exports = function(config) {
karmaTypescriptConfig: {
tsconfig: 'tsconfig.test.json'
},
browsers: ['Chrome']
browsers: ['Chrome'],
browserNoActivityTimeout: 60000,
client: {
jasmine: {
timeoutInterval: 30000
}
}
})
}
import { Dimensions, TMediaElement } from './types';
import * as tf from '@tensorflow/tfjs-core';
import { isTensor3D, isTensor4D } from './commons/isTensor';
import { padToSquare } from './padToSquare';
import { Point } from './Point';
import { TResolvedNetInput } from './types';
import { createCanvasFromMedia } from './utils';
export class NetInput {
private _canvases: HTMLCanvasElement[]
private _inputs: tf.Tensor3D[] = []
private _isManaged: boolean = false
private _isBatchInput: boolean = false
private _inputDimensions: number[][] = []
private _paddings: Point[] = []
constructor(
medias: Array<TMediaElement>,
dims?: Dimensions
inputs: tf.Tensor4D | Array<TResolvedNetInput>,
isBatchInput: boolean = false
) {
this._canvases = []
medias.forEach(m => this.initCanvas(m, dims))
}
if (isTensor4D(inputs)) {
this._inputs = tf.unstack(inputs as tf.Tensor4D) as tf.Tensor3D[]
}
private initCanvas(media: TMediaElement, dims?: Dimensions) {
if (media instanceof HTMLCanvasElement) {
this._canvases.push(media)
return
if (Array.isArray(inputs)) {
this._inputs = inputs.map(input => {
if (isTensor3D(input)) {
// TODO: make sure not to dispose original tensors passed in by the user
return tf.clone(input as tf.Tensor3D)
}
return tf.fromPixels(
input instanceof HTMLCanvasElement ? input : createCanvasFromMedia(input as HTMLImageElement | HTMLVideoElement)
)
})
}
// if input is batch type, make sure every canvas has the same dimensions
const canvasDims = this.dims || dims
this._canvases.push(createCanvasFromMedia(media, canvasDims))
this._isBatchInput = this.batchSize > 1 || isBatchInput
this._inputDimensions = this._inputs.map(t => t.shape)
}
public get inputs(): tf.Tensor3D[] {
return this._inputs
}
public get isManaged(): boolean {
return this._isManaged
}
public get isBatchInput(): boolean {
return this._isBatchInput
}
public get batchSize(): number {
return this._inputs.length
}
public get inputDimensions(): number[][] {
return this._inputDimensions
}
public get paddings(): Point[] {
return this._paddings
}
public getInputDimensions(batchIdx: number): number[] {
return this._inputDimensions[batchIdx]
}
public getInputHeight(batchIdx: number): number {
return this._inputDimensions[batchIdx][0]
}
public getInputWidth(batchIdx: number): number {
return this._inputDimensions[batchIdx][1]
}
public get canvases() : HTMLCanvasElement[] {
return this._canvases
public getPaddings(batchIdx: number): Point {
return this._paddings[batchIdx]
}
public get width() : number {
return (this._canvases[0] || {}).width
public toBatchTensor(inputSize: number, isCenterInputs: boolean = true): tf.Tensor4D {
return tf.tidy(() => {
const inputTensors = this._inputs.map((inputTensor: tf.Tensor3D) => {
const [originalHeight, originalWidth] = inputTensor.shape
let imgTensor = inputTensor.expandDims().toFloat() as tf.Tensor4D
imgTensor = padToSquare(imgTensor, isCenterInputs)
const [heightAfterPadding, widthAfterPadding] = imgTensor.shape.slice(1)
if (heightAfterPadding !== inputSize || widthAfterPadding !== inputSize) {
imgTensor = tf.image.resizeBilinear(imgTensor, [inputSize, inputSize])
}
this._paddings.push(new Point(
widthAfterPadding - originalWidth,
heightAfterPadding - originalHeight
))
return imgTensor
})
const batchTensor = tf.stack(inputTensors).as4D(this.batchSize, inputSize, inputSize, 3)
if (this.isManaged) {
this.dispose()
}
return batchTensor
})
}
public get height() : number {
return (this._canvases[0] || {}).height
/**
* By setting the isManaged flag, all newly created tensors will be automatically
* automatically disposed after the batch tensor has been created
*/
public managed() {
this._isManaged = true
return this
}
public get dims() : Dimensions | null {
const { width, height } = this
return (width > 0 && height > 0) ? { width, height } : null
public dispose() {
this._inputs.forEach(t => t.dispose())
}
}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { extractFaceTensors } from './extractFaceTensors';
import { FaceDetectionNet } from './faceDetectionNet/FaceDetectionNet';
import { FaceLandmarkNet } from './faceLandmarkNet/FaceLandmarkNet';
import { FaceLandmarks } from './faceLandmarkNet/FaceLandmarks';
import { FaceRecognitionNet } from './faceRecognitionNet/FaceRecognitionNet';
import { FullFaceDescription } from './FullFaceDescription';
import { NetInput } from './NetInput';
import { TNetInput } from './types';
export function allFacesFactory(
......@@ -14,21 +12,25 @@ export function allFacesFactory(
recognitionNet: FaceRecognitionNet
) {
return async function(
input: tf.Tensor | NetInput | TNetInput,
input: TNetInput,
minConfidence: number
): Promise<FullFaceDescription[]> {
const detections = await detectionNet.locateFaces(input, minConfidence)
const faceTensors = await extractFaceTensors(input, detections)
/**
const faceLandmarksByFace = await Promise.all(faceTensors.map(
faceTensor => landmarkNet.detectLandmarks(faceTensor)
))
)) as FaceLandmarks[]
*/
const faceLandmarksByFace = await landmarkNet.detectLandmarks(faceTensors) as FaceLandmarks[]
faceTensors.forEach(t => t.dispose())
const alignedFaceBoxes = await Promise.all(faceLandmarksByFace.map(
const alignedFaceBoxes = faceLandmarksByFace.map(
(landmarks, i) => landmarks.align(detections[i].getBox())
))
)
const alignedFaceTensors = await extractFaceTensors(input, alignedFaceBoxes)
const descriptors = await Promise.all(alignedFaceTensors.map(
......
import * as tf from '@tensorflow/tfjs-core';
import { NetInput } from '../NetInput';
export function getImageTensor(input: tf.Tensor | NetInput): tf.Tensor4D {
return tf.tidy(() => {
if (input instanceof tf.Tensor) {
const rank = input.shape.length
if (rank !== 3 && rank !== 4) {
throw new Error('input tensor must be of rank 3 or 4')
}
return (rank === 3 ? input.expandDims(0) : input).toFloat() as tf.Tensor4D
}
if (!(input instanceof NetInput)) {
throw new Error('getImageTensor - expected input to be a tensor or an instance of NetInput')
}
return tf.concat(
input.canvases.map(canvas =>
tf.fromPixels(canvas).expandDims(0).toFloat()
)
) as tf.Tensor4D
})
}
\ No newline at end of file
export function isMediaElement(input: any) {
return input instanceof HTMLImageElement
|| input instanceof HTMLVideoElement
|| input instanceof HTMLCanvasElement
}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
export function isTensor(tensor: tf.Tensor, dim: number) {
export function isTensor(tensor: any, dim: number) {
return tensor instanceof tf.Tensor && tensor.shape.length === dim
}
export function isTensor1D(tensor: tf.Tensor) {
export function isTensor1D(tensor: any) {
return isTensor(tensor, 1)
}
export function isTensor2D(tensor: tf.Tensor) {
export function isTensor2D(tensor: any) {
return isTensor(tensor, 2)
}
export function isTensor3D(tensor: tf.Tensor) {
export function isTensor3D(tensor: any) {
return isTensor(tensor, 3)
}
export function isTensor4D(tensor: tf.Tensor) {
export function isTensor4D(tensor: any) {
return isTensor(tensor, 4)
}
\ No newline at end of file
......@@ -5,4 +5,11 @@ export type ConvParams = {
bias: tf.Tensor1D
}
export type ExtractWeightsFunction = (numWeights: number) => Float32Array
\ No newline at end of file
export type ExtractWeightsFunction = (numWeights: number) => Float32Array
export type BatchReshapeInfo = {
originalWidth: number
originalHeight: number
paddingX: number
paddingY: number
}
import { FaceDetection } from '../faceDetectionNet/FaceDetection';
import { FaceLandmarks } from '../faceLandmarkNet/FaceLandmarks';
import { Point } from '../Point';
import { getContext2dOrThrow, getElement, round } from '../utils';
import { getContext2dOrThrow, resolveInput, round } from '../utils';
import { DrawBoxOptions, DrawLandmarksOptions, DrawOptions, DrawTextOptions } from './types';
export function getDefaultDrawOptions(): DrawOptions {
......@@ -55,7 +55,7 @@ export function drawDetection(
detection: FaceDetection | FaceDetection[],
options?: DrawBoxOptions & DrawTextOptions & { withScore: boolean }
) {
const canvas = getElement(canvasArg)
const canvas = resolveInput(canvasArg)
if (!(canvas instanceof HTMLCanvasElement)) {
throw new Error('drawBox - expected canvas to be of type: HTMLCanvasElement')
}
......@@ -132,7 +132,7 @@ export function drawLandmarks(
faceLandmarks: FaceLandmarks | FaceLandmarks[],
options?: DrawLandmarksOptions & { drawLines: boolean }
) {
const canvas = getElement(canvasArg)
const canvas = resolveInput(canvasArg)
if (!(canvas instanceof HTMLCanvasElement)) {
throw new Error('drawLandmarks - expected canvas to be of type: HTMLCanvasElement')
}
......
import * as tf from '@tensorflow/tfjs-core';
import { getImageTensor } from './commons/getImageTensor';
import { FaceDetection } from './faceDetectionNet/FaceDetection';
import { NetInput } from './NetInput';
import { Rect } from './Rect';
import { TNetInput } from './types';
import { toNetInput } from './toNetInput';
import { TNetInput } from './types';
/**
* Extracts the tensors of the image regions containing the detected faces.
......@@ -18,19 +16,23 @@ import { toNetInput } from './toNetInput';
* @returns Tensors of the corresponding image region for each detected face.
*/
export async function extractFaceTensors(
input: tf.Tensor | NetInput | TNetInput,
detections: Array<FaceDetection|Rect>
input: TNetInput,
detections: Array<FaceDetection | Rect>
): Promise<tf.Tensor4D[]> {
const image = input instanceof tf.Tensor
? input
: await toNetInput(input)
const netInput = await toNetInput(input, true)
if (netInput.batchSize > 1) {
if (netInput.isManaged) {
netInput.dispose()
}
throw new Error('extractFaceTensors - batchSize > 1 not supported')
}
return tf.tidy(() => {
const imgTensor = getImageTensor(image)
const imgTensor = netInput.inputs[0].expandDims().toFloat() as tf.Tensor4D
// TODO handle batches
const [batchSize, imgHeight, imgWidth, numChannels] = imgTensor.shape
const [imgHeight, imgWidth, numChannels] = imgTensor.shape.slice(1)
const boxes = detections.map(
det => det instanceof FaceDetection
......@@ -41,6 +43,9 @@ export async function extractFaceTensors(
tf.slice(imgTensor, [0, y, x, 0], [1, height, width, numChannels])
)
if (netInput.isManaged) {
netInput.dispose()
}
return faceTensors
})
}
\ No newline at end of file
import { FaceDetection } from './faceDetectionNet/FaceDetection';
import { Rect } from './Rect';
import { createCanvas, getContext2dOrThrow } from './utils';
import { toNetInput } from './toNetInput';
import { TNetInput } from './types';
import { createCanvas, getContext2dOrThrow, imageTensorToCanvas } from './utils';
/**
* Extracts the image regions containing the detected faces.
......@@ -9,15 +11,31 @@ import { createCanvas, getContext2dOrThrow } from './utils';
* @param detections The face detection results or face bounding boxes for that image.
* @returns The Canvases of the corresponding image region for each detected face.
*/
export function extractFaces(
image: HTMLCanvasElement,
detections: Array<FaceDetection|Rect>
): HTMLCanvasElement[] {
const ctx = getContext2dOrThrow(image)
export async function extractFaces(
input: TNetInput,
detections: Array<FaceDetection | Rect>
): Promise<HTMLCanvasElement[]> {
let canvas = input as HTMLCanvasElement
if (!(input instanceof HTMLCanvasElement)) {
const netInput = await toNetInput(input, true)
if (netInput.batchSize > 1) {
if (netInput.isManaged) {
netInput.dispose()
}
throw new Error('extractFaces - batchSize > 1 not supported')
}
canvas = await imageTensorToCanvas(netInput.inputs[0])
}
const ctx = getContext2dOrThrow(canvas)
const boxes = detections.map(
det => det instanceof FaceDetection
? det.forSize(image.width, image.height).getBox().floor()
? det.forSize(canvas.width, canvas.height).getBox().floor()
: det
)
return boxes.map(({ x, y, width, height }) => {
......
import * as tf from '@tensorflow/tfjs-core';
import { getImageTensor } from '../commons/getImageTensor';
import { NetInput } from '../NetInput';
import { padToSquare } from '../padToSquare';
import { Rect } from '../Rect';
import { toNetInput } from '../toNetInput';
import { Dimensions, TNetInput } from '../types';
import { TNetInput } from '../types';
import { extractParams } from './extractParams';
import { FaceDetection } from './FaceDetection';
import { loadQuantizedParams } from './loadQuantizedParams';
......@@ -13,7 +11,6 @@ import { mobileNetV1 } from './mobileNetV1';
import { nonMaxSuppression } from './nonMaxSuppression';
import { outputLayer } from './outputLayer';
import { predictionLayer } from './predictionLayer';
import { resizeLayer } from './resizeLayer';
import { NetParams } from './types';
export class FaceDetectionNet {
......@@ -36,15 +33,16 @@ export class FaceDetectionNet {
this._params = extractParams(weights)
}
private forwardTensor(imgTensor: tf.Tensor4D) {
public forwardInput(input: NetInput) {
if (!this._params) {
throw new Error('FaceDetectionNet - load model before inference')
}
return tf.tidy(() => {
const batchTensor = input.toBatchTensor(512, false)
const resized = resizeLayer(imgTensor) as tf.Tensor4D
const features = mobileNetV1(resized, this._params.mobilenetv1_params)
const x = tf.sub(tf.mul(batchTensor, tf.scalar(0.007843137718737125)), tf.scalar(1)) as tf.Tensor4D
const features = mobileNetV1(x, this._params.mobilenetv1_params)
const {
boxPredictions,
......@@ -55,44 +53,23 @@ export class FaceDetectionNet {
})
}
public async forward(input: tf.Tensor | NetInput | TNetInput) {
const netInput = input instanceof tf.Tensor
? input
: await toNetInput(input)
return tf.tidy(() =>
this.forwardTensor(padToSquare(getImageTensor(netInput)))
)
public async forward(input: TNetInput) {
return this.forwardInput(await toNetInput(input, true))
}
public async locateFaces(
input: tf.Tensor | NetInput | TNetInput,
input: TNetInput,
minConfidence: number = 0.8,
maxResults: number = 100,
): Promise<FaceDetection[]> {
const netInput = input instanceof tf.Tensor
? input
: await toNetInput(input)
let paddedHeightRelative = 1, paddedWidthRelative = 1
let imageDimensions: Dimensions | undefined
const netInput = await toNetInput(input, true)
const {
boxes: _boxes,
scores: _scores
} = tf.tidy(() => {
let imgTensor = getImageTensor(netInput)
const [height, width] = imgTensor.shape.slice(1)
imageDimensions = { width, height }
} = this.forwardInput(netInput)
imgTensor = padToSquare(imgTensor)
paddedHeightRelative = imgTensor.shape[1] / height
paddedWidthRelative = imgTensor.shape[2] / width
return this.forwardTensor(imgTensor)
})
// TODO batches
const boxes = _boxes[0]
......@@ -114,6 +91,10 @@ export class FaceDetectionNet {
minConfidence
)
const paddedHeightRelative = (netInput.getPaddings(0).y + netInput.getInputHeight(0)) / netInput.getInputHeight(0)
const paddedWidthRelative = (netInput.getPaddings(0).x + netInput.getInputWidth(0)) / netInput.getInputWidth(0)
const results = indices
.map(idx => {
const [top, bottom] = [
......@@ -132,7 +113,10 @@ export class FaceDetectionNet {
right - left,
bottom - top
),
imageDimensions as Dimensions
{
height: netInput.getInputHeight(0),
width: netInput.getInputWidth(0)
}
)
})
......
import * as tf from '@tensorflow/tfjs-core';
const resizedImageSize = [512, 512] as [number, number]
const weight = tf.scalar(0.007843137718737125)
const bias = tf.scalar(1)
export function resizeLayer(x: tf.Tensor4D) {
return tf.tidy(() => {
const resized = tf.image.resizeBilinear(x, resizedImageSize, false)
return tf.sub(tf.mul(resized, weight), bias)
})
}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { convLayer } from '../commons/convLayer';
import { getImageTensor } from '../commons/getImageTensor';
import { ConvParams } from '../commons/types';
import { NetInput } from '../NetInput';
import { padToSquare } from '../padToSquare';
import { Point } from '../Point';
import { toNetInput } from '../toNetInput';
import { Dimensions, TNetInput } from '../types';
import { TNetInput } from '../types';
import { isEven } from '../utils';
import { extractParams } from './extractParams';
import { FaceLandmarks } from './FaceLandmarks';
......@@ -43,7 +41,7 @@ export class FaceLandmarkNet {
this._params = extractParams(weights)
}
public forwardTensor(imgTensor: tf.Tensor4D): tf.Tensor2D {
public forwardInput(input: NetInput): tf.Tensor2D {
const params = this._params
if (!params) {
......@@ -51,17 +49,9 @@ export class FaceLandmarkNet {
}
return tf.tidy(() => {
const [batchSize, height, width] = imgTensor.shape.slice()
const batchTensor = input.toBatchTensor(128, true)
let x = padToSquare(imgTensor, true)
const [heightAfterPadding, widthAfterPadding] = x.shape.slice(1)
// work with 128 x 128 sized face images
if (heightAfterPadding !== 128 || widthAfterPadding !== 128) {
x = tf.image.resizeBilinear(x, [128, 128])
}
let out = conv(x, params.conv0_params)
let out = conv(batchTensor, params.conv0_params)
out = maxPool(out)
out = conv(out, params.conv1_params)
out = conv(out, params.conv2_params)
......@@ -76,62 +66,72 @@ export class FaceLandmarkNet {
const fc0 = tf.relu(fullyConnectedLayer(out.as2D(out.shape[0], -1), params.fc0_params))
const fc1 = fullyConnectedLayer(fc0, params.fc1_params)
const createInterleavedTensor = (fillX: number, fillY: number) =>
tf.stack([
tf.fill([68], fillX),
tf.fill([68], fillY)
], 1).as2D(batchSize, 136)
tf.stack([
tf.fill([68], fillX),
tf.fill([68], fillY)
], 1).as2D(1, 136).as1D()
/* shift coordinates back, to undo centered padding
((x * widthAfterPadding) - shiftX) / width
((y * heightAfterPadding) - shiftY) / height
x = ((x * widthAfterPadding) - shiftX) / width
y = ((y * heightAfterPadding) - shiftY) / height
*/
const shiftX = Math.floor(Math.abs(widthAfterPadding - width) / 2)
const shiftY = Math.floor(Math.abs(heightAfterPadding - height) / 2)
const landmarkTensor = fc1
.mul(createInterleavedTensor(widthAfterPadding, heightAfterPadding))
.sub(createInterleavedTensor(shiftX, shiftY))
.div(createInterleavedTensor(width, height))
return landmarkTensor as tf.Tensor2D
const landmarkTensors = fc1
.mul(tf.stack(Array.from(Array(input.batchSize), (_, batchIdx) =>
createInterleavedTensor(
input.getPaddings(batchIdx).x + input.getInputWidth(batchIdx),
input.getPaddings(batchIdx).y + input.getInputHeight(batchIdx)
)
)))
.sub(tf.stack(Array.from(Array(input.batchSize), (_, batchIdx) =>
createInterleavedTensor(
Math.floor(input.getPaddings(batchIdx).x / 2),
Math.floor(input.getPaddings(batchIdx).y / 2)
)
)))
.div(tf.stack(Array.from(Array(input.batchSize), (_, batchIdx) =>
createInterleavedTensor(
input.getInputWidth(batchIdx),
input.getInputHeight(batchIdx)
)
)))
return landmarkTensors as tf.Tensor2D
})
}
public async forward(input: tf.Tensor | NetInput | TNetInput): Promise<tf.Tensor2D> {
const netInput = input instanceof tf.Tensor
? input
: await toNetInput(input)
return this.forwardTensor(getImageTensor(netInput))
public async forward(input: TNetInput): Promise<tf.Tensor2D> {
return this.forwardInput(await toNetInput(input, true))
}
public async detectLandmarks(input: tf.Tensor | NetInput | TNetInput) {
const netInput = input instanceof tf.Tensor
? input
: await toNetInput(input)
public async detectLandmarks(input: TNetInput): Promise<FaceLandmarks | FaceLandmarks[]> {
const netInput = await toNetInput(input, true)
let imageDimensions: Dimensions | undefined
const outTensor = tf.tidy(() => {
const imgTensor = getImageTensor(netInput)
const [height, width] = imgTensor.shape.slice(1)
imageDimensions = { width, height }
return this.forwardTensor(imgTensor)
})
const landmarkTensors = tf.tidy(
() => tf.unstack(this.forwardInput(netInput))
)
const faceLandmarksArray = Array.from(await outTensor.data())
outTensor.dispose()
const landmarksForBatch = await Promise.all(landmarkTensors.map(
async (landmarkTensor, batchIdx) => {
const landmarksArray = Array.from(await landmarkTensor.data())
const xCoords = landmarksArray.filter((_, i) => isEven(i))
const yCoords = landmarksArray.filter((_, i) => !isEven(i))
return new FaceLandmarks(
Array(68).fill(0).map((_, i) => new Point(xCoords[i], yCoords[i])),
{
height: netInput.getInputHeight(batchIdx),
width : netInput.getInputWidth(batchIdx),
}
)
}
))
const xCoords = faceLandmarksArray.filter((_, i) => isEven(i))
const yCoords = faceLandmarksArray.filter((_, i) => !isEven(i))
landmarkTensors.forEach(t => t.dispose())
return new FaceLandmarks(
Array(68).fill(0).map((_, i) => new Point(xCoords[i], yCoords[i])),
imageDimensions as Dimensions
)
return netInput.isBatchInput
? landmarksForBatch
: landmarksForBatch[0]
}
}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { getImageTensor } from '../commons/getImageTensor';
import { NetInput } from '../NetInput';
import { padToSquare } from '../padToSquare';
import { toNetInput } from '../toNetInput';
import { TNetInput } from '../types';
import { convDown } from './convLayer';
......@@ -32,25 +30,18 @@ export class FaceRecognitionNet {
this._params = extractParams(weights)
}
public async forward(input: tf.Tensor | NetInput | TNetInput): Promise<tf.Tensor2D> {
public async forwardInput(input: NetInput): Promise<tf.Tensor2D> {
if (!this._params) {
throw new Error('FaceRecognitionNet - load model before inference')
}
const netInput = input instanceof tf.Tensor
? input
: await toNetInput(input)
return tf.tidy(() => {
const batchTensor = input.toBatchTensor(150, true)
let x = padToSquare(getImageTensor(netInput), true)
// work with 150 x 150 sized face images
if (x.shape[1] !== 150 || x.shape[2] !== 150) {
x = tf.image.resizeBilinear(x, [150, 150])
}
x = normalize(x)
const normalized = normalize(batchTensor)
let out = convDown(x, this._params.conv32_down)
let out = convDown(normalized, this._params.conv32_down)
out = tf.maxPool(out, 3, 2, 'valid')
out = residual(out, this._params.conv32_1)
......@@ -77,13 +68,12 @@ export class FaceRecognitionNet {
return fullyConnected
})
}
public async forward(input: TNetInput): Promise<tf.Tensor2D> {
return this.forwardInput(await toNetInput(input, true))
}
public async computeFaceDescriptor(input: tf.Tensor | NetInput | TNetInput) {
const netInput = input instanceof tf.Tensor
? input
: await toNetInput(input)
const result = await this.forward(netInput)
public async computeFaceDescriptor(input: TNetInput) {
const result = await this.forward(await toNetInput(input, true))
const data = await result.data()
result.dispose()
return data as Float32Array
......
......@@ -6,9 +6,9 @@ import { FaceDetectionNet } from './faceDetectionNet/FaceDetectionNet';
import { FaceLandmarkNet } from './faceLandmarkNet/FaceLandmarkNet';
import { FaceLandmarks } from './faceLandmarkNet/FaceLandmarks';
import { FaceRecognitionNet } from './faceRecognitionNet/FaceRecognitionNet';
import { FullFaceDescription } from './FullFaceDescription';
import { NetInput } from './NetInput';
import { TNetInput } from './types';
import { FullFaceDescription } from './FullFaceDescription';
export const detectionNet = new FaceDetectionNet()
export const landmarkNet = new FaceLandmarkNet()
......@@ -35,7 +35,7 @@ export function loadModels(url: string) {
}
export function locateFaces(
input: tf.Tensor | NetInput | TNetInput,
input: TNetInput,
minConfidence?: number,
maxResults?: number
): Promise<FaceDetection[]> {
......@@ -43,13 +43,13 @@ export function locateFaces(
}
export function detectLandmarks(
input: tf.Tensor | NetInput | TNetInput
): Promise<FaceLandmarks> {
input: TNetInput
): Promise<FaceLandmarks | FaceLandmarks[]> {
return landmarkNet.detectLandmarks(input)
}
export function computeFaceDescriptor(
input: tf.Tensor | NetInput | TNetInput
input: TNetInput
): Promise<Float32Array> {
return recognitionNet.computeFaceDescriptor(input)
}
......
import * as tf from '@tensorflow/tfjs-core';
import { isEven } from './utils';
/**
* Pads the smaller dimension of an image tensor with zeros, such that width === height.
*
......
import * as tf from '@tensorflow/tfjs-core';
import { isMediaElement } from './commons/isMediaElement';
import { isTensor3D, isTensor4D } from './commons/isTensor';
import { NetInput } from './NetInput';
import { TNetInput } from './types';
import { awaitMediaLoaded, getElement } from './utils';
import { awaitMediaLoaded, resolveInput } from './utils';
/**
* Validates the input to make sure, they are valid net inputs and awaits all media elements
* to be finished loading.
*
* @param input The input, which can be a media element or an array of different media elements.
* @param manageCreatedInput If a new NetInput instance is created from the inputs, this flag
* determines, whether to set the NetInput as managed or not.
* @returns A NetInput instance, which can be passed into one of the neural networks.
*/
export async function toNetInput(
input: NetInput | TNetInput
inputs: TNetInput,
manageCreatedInput: boolean = false
): Promise<NetInput> {
if (input instanceof NetInput) {
return input
if (inputs instanceof NetInput) {
return inputs
}
const afterCreate = (netInput: NetInput) => manageCreatedInput
? netInput.managed()
: netInput
if (isTensor4D(inputs)) {
return afterCreate(new NetInput(inputs as tf.Tensor4D))
}
const mediaArgArray = Array.isArray(input)
? input
: [input]
let inputArgArray = Array.isArray(inputs)
? inputs
: [inputs]
if (!mediaArgArray.length) {
if (!inputArgArray.length) {
throw new Error('toNetInput - empty array passed as input')
}
const medias = mediaArgArray.map(getElement)
const getIdxHint = (idx: number) => Array.isArray(inputs) ? ` at input index ${idx}:` : ''
medias.forEach((media, i) => {
if (!(media instanceof HTMLImageElement || media instanceof HTMLVideoElement || media instanceof HTMLCanvasElement)) {
const idxHint = Array.isArray(input) ? ` at input index ${i}:` : ''
if (typeof mediaArgArray[i] === 'string') {
throw new Error(`toNetInput -${idxHint} string passed, but could not resolve HTMLElement for element id`)
const inputArray = inputArgArray
.map(resolveInput)
.map((input, i) => {
if (isTensor4D(input)) {
// if tf.Tensor4D is passed in the input array, the batch size has to be 1
const batchSize = input.shape[0]
if (batchSize !== 1) {
throw new Error(`toNetInput -${getIdxHint(i)} tf.Tensor4D with batchSize ${batchSize} passed, but not supported in input array`)
}
// to tf.Tensor3D
return input.reshape(input.shape.slice(1))
}
throw new Error(`toNetInput -${idxHint} expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement, or to be an element id`)
return input
})
inputArray.forEach((input, i) => {
if (!isMediaElement(input) && !isTensor3D(input)) {
if (typeof inputArgArray[i] === 'string') {
throw new Error(`toNetInput -${getIdxHint(i)} string passed, but could not resolve HTMLElement for element id ${inputArgArray[i]}`)
}
throw new Error(`toNetInput -${getIdxHint(i)} expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | tf.Tensor3D, or to be an element id`)
}
})
// wait for all media elements being loaded
await Promise.all(
medias.map(media => awaitMediaLoaded(media))
inputArray.map(input => isMediaElement(input) && awaitMediaLoaded(input))
)
return new NetInput(medias)
return afterCreate(new NetInput(inputArray, Array.isArray(inputs)))
}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { NetInput } from './NetInput';
export type TMediaElement = HTMLImageElement | HTMLVideoElement | HTMLCanvasElement
export type TNetInputArg = string | TMediaElement
export type TResolvedNetInput = TMediaElement | tf.Tensor3D | tf.Tensor4D
export type TNetInputArg = string | TResolvedNetInput
export type TNetInput = TNetInputArg | Array<TNetInputArg>
export type TNetInput = TNetInputArg | Array<TNetInputArg> | NetInput | tf.Tensor4D
export type Dimensions = {
width: number
......
import * as tf from '@tensorflow/tfjs-core';
import { isTensor4D } from './commons/isTensor';
import { Dimensions } from './types';
export function isFloat(num: number) {
......@@ -14,7 +15,7 @@ export function round(num: number) {
return Math.floor(num * 100) / 100
}
export function getElement(arg: string | any) {
export function resolveInput(arg: string | any) {
if (typeof arg === 'string') {
return document.getElementById(arg)
}
......@@ -106,12 +107,12 @@ export function bufferToImage(buf: Blob): Promise<HTMLImageElement> {
}
export async function imageTensorToCanvas(
imgTensor: tf.Tensor4D,
imgTensor: tf.Tensor,
canvas?: HTMLCanvasElement
): Promise<HTMLCanvasElement> {
const targetCanvas = canvas || document.createElement('canvas')
const [_, height, width, numChannels] = imgTensor.shape
const [height, width, numChannels] = imgTensor.shape.slice(isTensor4D(imgTensor) ? 1 : 0)
await tf.toPixels(imgTensor.as3D(height, width, numChannels).toInt(), targetCanvas)
return targetCanvas
......
[{"x": 9.995004907250404, "y": 53.55449616909027}, {"x": 12.50796876847744, "y": 71.41348421573639}, {"x": 16.677917540073395, "y": 88.59677910804749}, {"x": 22.6475290954113, "y": 104.6014130115509}, {"x": 30.59161528944969, "y": 119.35952603816986}, {"x": 41.422560811042786, "y": 132.23226964473724}, {"x": 54.74700182676315, "y": 142.4335777759552}, {"x": 70.32481580972672, "y": 149.33189749717712}, {"x": 87.31497824192047, "y": 150.50972700119019}, {"x": 103.98584604263306, "y": 145.98273038864136}, {"x": 117.90181696414948, "y": 135.19554734230042}, {"x": 128.67935299873352, "y": 121.79077863693237}, {"x": 136.7296814918518, "y": 105.85636496543884}, {"x": 140.29521346092224, "y": 88.25878500938416}, {"x": 140.9232795238495, "y": 70.16736567020416}, {"x": 140.2374029159546, "y": 52.73242145776749}, {"x": 137.97148168087006, "y": 34.537942707538605}, {"x": 14.37721811234951, "y": 33.1049881875515}, {"x": 22.6781465113163, "y": 24.685607850551605}, {"x": 34.36600640416145, "y": 21.1758591234684}, {"x": 46.24761343002319, "y": 22.49436378479004}, {"x": 57.12086856365204, "y": 26.742971688508987}, {"x": 81.21025264263153, "y": 23.014162480831146}, {"x": 92.2086775302887, "y": 15.48520065844059}, {"x": 104.77548837661743, "y": 11.306393891572952}, {"x": 117.67798662185669, "y": 11.740228906273842}, {"x": 127.28274464607239, "y": 18.115675449371338}, {"x": 69.62742805480957, "y": 41.51403307914734}, {"x": 70.82946002483368, "y": 55.146731436252594}, {"x": 71.84555232524872, "y": 68.59723627567291}, {"x": 73.0046421289444, "y": 81.93029165267944}, {"x": 60.417647659778595, "y": 88.01697492599487}, {"x": 67.98770427703857, "y": 90.65443575382233}, {"x": 76.07284784317017, "y": 91.86699986457825}, {"x": 84.35145914554596, "y": 88.2117748260498}, {"x": 90.86072444915771, "y": 83.67109894752502}, {"x": 28.828849643468857, "y": 47.794362902641296}, {"x": 36.311765760183334, "y": 43.33548992872238}, {"x": 44.95347887277603, "y": 43.20283681154251}, {"x": 52.85406410694122, "y": 48.07424694299698}, {"x": 44.7566494345665, "y": 49.9691516160965}, {"x": 35.997654497623444, "y": 50.32083839178085}, {"x": 89.51361179351807, "y": 42.501528561115265}, {"x": 97.55686819553375, "y": 35.38782298564911}, {"x": 106.73499405384064, "y": 33.59129726886749}, {"x": 114.8474782705307, "y": 36.34611591696739}, {"x": 108.40394496917725, "y": 40.97002297639847}, {"x": 98.98389279842377, "y": 42.47862249612808}, {"x": 53.17014008760452, "y": 109.99322533607483}, {"x": 62.47727572917938, "y": 105.5664449930191}, {"x": 72.82306104898453, "y": 102.35638618469238}, {"x": 80.85319697856903, "y": 103.16510796546936}, {"x": 89.42103087902069, "y": 100.08856952190399}, {"x": 99.8135894536972, "y": 100.0435084104538}, {"x": 109.78849232196808, "y": 101.60946249961853}, {"x": 101.90783143043518, "y": 115.25328755378723}, {"x": 92.65078604221344, "y": 122.49988317489624}, {"x": 83.28675627708435, "y": 125.00075697898865}, {"x": 74.31002408266068, "y": 125.16917288303375}, {"x": 63.37641924619675, "y": 121.38420939445496}, {"x": 57.85811394453049, "y": 110.28821468353271}, {"x": 73.27612638473511, "y": 108.2253098487854}, {"x": 81.34059011936188, "y": 108.251291513443}, {"x": 89.9710088968277, "y": 105.99507093429565}, {"x": 104.85810041427612, "y": 103.1228095293045}, {"x": 90.87785482406616, "y": 112.19902038574219}, {"x": 82.05846548080444, "y": 114.52528238296509}, {"x": 73.8232746720314, "y": 114.64338898658752}]
\ No newline at end of file
[{"x": 1.41040606983006, "y": 39.10264679789543}, {"x": 6.364097021520138, "y": 59.51536446809769}, {"x": 9.736957371234894, "y": 77.80020213127136}, {"x": 13.817122921347618, "y": 96.05930614471436}, {"x": 20.00808236002922, "y": 110.73724734783173}, {"x": 26.37610113620758, "y": 121.9759613275528}, {"x": 33.717534959316254, "y": 132.17582309246063}, {"x": 41.72355371713638, "y": 140.95428133010864}, {"x": 50.880420446395874, "y": 146.48704254627228}, {"x": 61.8572758436203, "y": 146.95429050922394}, {"x": 72.31115305423737, "y": 142.27578461170197}, {"x": 81.12127649784088, "y": 134.44229400157928}, {"x": 90.62704622745514, "y": 123.21754229068756}, {"x": 99.09188437461853, "y": 110.66853940486908}, {"x": 106.08789837360382, "y": 92.88722932338715}, {"x": 110.42981934547424, "y": 72.83273243904114}, {"x": 110.97252583503723, "y": 51.15715354681015}, {"x": 19.203872233629227, "y": 37.71118628978729}, {"x": 30.421346753835678, "y": 37.16629707813263}, {"x": 39.97739166021347, "y": 40.400769114494324}, {"x": 49.04381215572357, "y": 45.61803185939789}, {"x": 56.723132252693176, "y": 53.29851043224335}, {"x": 56.084791123867035, "y": 46.76303869485855}, {"x": 65.71077406406403, "y": 46.11447751522064}, {"x": 75.0335134267807, "y": 46.96638810634613}, {"x": 83.45012521743774, "y": 51.2211879491806}, {"x": 90.43923103809357, "y": 59.06730401515961}, {"x": 57.634793639183044, "y": 60.69884181022644}, {"x": 56.081126153469086, "y": 72.10934686660767}, {"x": 54.33526223897934, "y": 84.50968235731125}, {"x": 52.046833634376526, "y": 99.18286514282227}, {"x": 43.99328297376633, "y": 99.4484453201294}, {"x": 49.026043593883514, "y": 104.39998996257782}, {"x": 55.01739031076431, "y": 107.4150230884552}, {"x": 59.81684720516205, "y": 105.90647208690643}, {"x": 64.0739357471466, "y": 101.74840021133423}, {"x": 27.087938010692596, "y": 55.09133046865463}, {"x": 34.27653384208679, "y": 55.21461433172226}, {"x": 42.54729217290878, "y": 57.39108908176422}, {"x": 48.454275488853455, "y": 61.82331371307373}, {"x": 41.1783966422081, "y": 61.66855639219284}, {"x": 34.177026987075806, "y": 60.50751310586929}, {"x": 59.51743584871292, "y": 62.6235288977623}, {"x": 65.59782898426056, "y": 61.08310657739639}, {"x": 73.38363683223724, "y": 63.624403953552246}, {"x": 78.78980994224548, "y": 67.99472141265869}, {"x": 72.09050583839417, "y": 68.4499539732933}, {"x": 64.50075209140778, "y": 66.9551106095314}, {"x": 34.73506963253021, "y": 112.76923489570618}, {"x": 42.499454855918884, "y": 113.63057744503021}, {"x": 49.24748706817627, "y": 114.29424142837524}, {"x": 55.50651115179062, "y": 115.7518025636673}, {"x": 62.20475721359253, "y": 116.19831931591034}, {"x": 66.55372452735901, "y": 117.66684019565582}, {"x": 71.82598805427551, "y": 118.23190891742706}, {"x": 64.1076112985611, "y": 127.00456368923187}, {"x": 58.63429069519043, "y": 129.7624831199646}, {"x": 52.65244817733765, "y": 129.39003217220306}, {"x": 47.463079154491425, "y": 127.39845669269562}, {"x": 42.28087282180786, "y": 123.10187613964081}, {"x": 38.320072412490845, "y": 114.88845479488373}, {"x": 49.383214592933655, "y": 119.21215355396271}, {"x": 55.4133198261261, "y": 120.68333745002747}, {"x": 60.75339984893799, "y": 121.00764191150665}, {"x": 67.49378943443298, "y": 118.56007528305054}, {"x": 59.50732082128525, "y": 124.34931361675262}, {"x": 54.06349813938141, "y": 124.39959263801575}, {"x": 48.627867102622986, "y": 122.32591986656189}]
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { NetInput } from '../../src/NetInput';
import { bufferToImage, createCanvasFromMedia } from '../../src/utils';
import { expectAllTensorsReleased, tensor3D } from '../utils';
describe('NetInput', () => {
let imgEl: HTMLImageElement, canvasEl: HTMLCanvasElement
beforeAll(async () => {
const img = await (await fetch('base/test/images/face1.png')).blob()
imgEl = await bufferToImage(img)
canvasEl = createCanvasFromMedia(imgEl)
})
describe('no memory leaks', () => {
describe('constructor', () => {
it('single image element', async () => {
await expectAllTensorsReleased(() => {
const net = new NetInput([imgEl])
net.dispose()
})
})
it('multiple image elements', async () => {
await expectAllTensorsReleased(() => {
const net = new NetInput([imgEl, imgEl, imgEl])
net.dispose()
})
})
it('single tf.Tensor3D', async () => {
const tensor = tensor3D()
await expectAllTensorsReleased(() => {
const net = new NetInput([tensor])
net.dispose()
})
tensor.dispose()
})
it('multiple tf.Tensor3Ds', async () => {
const tensors = [tensor3D(), tensor3D(), tensor3D()]
await expectAllTensorsReleased(() => {
const net = new NetInput(tensors)
net.dispose()
})
tensors.forEach(t => t.dispose())
})
})
describe('toBatchTensor', () => {
it('single image element', async () => {
await expectAllTensorsReleased(() => {
const net = new NetInput([imgEl])
const batchTensor = net.toBatchTensor(100, false)
net.dispose()
batchTensor.dispose()
})
})
it('multiple image elements', async () => {
await expectAllTensorsReleased(() => {
const net = new NetInput([imgEl, imgEl, imgEl])
const batchTensor = net.toBatchTensor(100, false)
net.dispose()
batchTensor.dispose()
})
})
it('managed, single image element', async () => {
await expectAllTensorsReleased(() => {
const net = (new NetInput([imgEl])).managed()
const batchTensor = net.toBatchTensor(100, false)
batchTensor.dispose()
})
})
it('managed, multiple image elements', async () => {
await expectAllTensorsReleased(() => {
const net = (new NetInput([imgEl, imgEl, imgEl])).managed()
const batchTensor = net.toBatchTensor(100, false)
batchTensor.dispose()
})
})
})
})
})
......@@ -9,7 +9,7 @@ describe('faceRecognitionNet', () => {
const weights = new Float32Array(await res.arrayBuffer())
faceRecognitionNet = faceapi.faceRecognitionNet(weights)
const img = await (await fetch('base/test/images/face.png')).blob()
const img = await (await fetch('base/test/images/face1.png')).blob()
imgEl = await faceapi.bufferToImage(img)
faceDescriptor = await (await fetch('base/test/data/faceDescriptor.json')).json()
})
......
import { NetInput } from '../../src/NetInput';
import { toNetInput } from '../../src/toNetInput';
import { bufferToImage, createCanvasFromMedia } from '../../src/utils';
import { createFakeHTMLVideoElement } from '../utils';
describe('toNetInput', () => {
let imgEl: HTMLImageElement, canvasEl: HTMLCanvasElement
beforeAll(async () => {
const img = await (await fetch('base/test/images/face1.png')).blob()
imgEl = await bufferToImage(img)
canvasEl = createCanvasFromMedia(imgEl)
})
describe('valid args', () => {
it('from HTMLImageElement', async () => {
const netInput = await toNetInput(document.createElement('img'))
const netInput = await toNetInput(imgEl, true)
expect(netInput instanceof NetInput).toBe(true)
expect(netInput.canvases.length).toEqual(1)
expect(netInput.batchSize).toEqual(1)
})
it('from HTMLVideoElement', async () => {
const videoEl = document.createElement('video')
spyOnProperty(videoEl, 'readyState', 'get').and.returnValue(4)
const netInput = await toNetInput(videoEl)
const videoEl = await createFakeHTMLVideoElement()
const netInput = await toNetInput(videoEl, true)
expect(netInput instanceof NetInput).toBe(true)
expect(netInput.canvases.length).toEqual(1)
expect(netInput.batchSize).toEqual(1)
})
it('from HTMLCanvasElement', async () => {
const netInput = await toNetInput(document.createElement('canvas'))
const netInput = await toNetInput(canvasEl, true)
expect(netInput instanceof NetInput).toBe(true)
expect(netInput.canvases.length).toEqual(1)
expect(netInput.batchSize).toEqual(1)
})
it('from HTMLImageElement array', async () => {
const netInput = await toNetInput([
document.createElement('img'),
document.createElement('img')
])
imgEl,
imgEl
], true)
expect(netInput instanceof NetInput).toBe(true)
expect(netInput.canvases.length).toEqual(2)
expect(netInput.batchSize).toEqual(2)
})
it('from HTMLVideoElement array', async () => {
const videoElements = [
document.createElement('video'),
document.createElement('video')
await createFakeHTMLVideoElement(),
await createFakeHTMLVideoElement()
]
videoElements.forEach(videoEl =>
spyOnProperty(videoEl, 'readyState', 'get').and.returnValue(4)
)
const netInput = await toNetInput(videoElements)
const netInput = await toNetInput(videoElements, true)
expect(netInput instanceof NetInput).toBe(true)
expect(netInput.canvases.length).toEqual(2)
expect(netInput.batchSize).toEqual(2)
})
it('from HTMLCanvasElement array', async () => {
const netInput = await toNetInput([
document.createElement('canvas'),
document.createElement('canvas')
])
canvasEl,
canvasEl
], true)
expect(netInput instanceof NetInput).toBe(true)
expect(netInput.canvases.length).toEqual(2)
expect(netInput.batchSize).toEqual(2)
})
it('from mixed media array', async () => {
const videoEl = document.createElement('video')
spyOnProperty(videoEl, 'readyState', 'get').and.returnValue(4)
const netInput = await toNetInput([
document.createElement('img'),
document.createElement('canvas'),
videoEl
])
imgEl,
canvasEl,
await createFakeHTMLVideoElement()
], true)
expect(netInput instanceof NetInput).toBe(true)
expect(netInput.canvases.length).toEqual(3)
expect(netInput.batchSize).toEqual(3)
})
})
......@@ -81,7 +86,7 @@ describe('toNetInput', () => {
} catch (error) {
errorMessage = error.message;
}
expect(errorMessage).toBe('toNetInput - expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement, or to be an element id')
expect(errorMessage).toBe('toNetInput - expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | tf.Tensor3D, or to be an element id')
})
it('empty array', async () => {
......@@ -101,7 +106,7 @@ describe('toNetInput', () => {
} catch (error) {
errorMessage = error.message;
}
expect(errorMessage).toBe('toNetInput - at input index 1: expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement, or to be an element id')
expect(errorMessage).toBe('toNetInput - at input index 1: expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | tf.Tensor3D, or to be an element id')
})
})
......
import * as tf from '@tensorflow/tfjs-core';
export function zeros(length: number): Float32Array {
return new Float32Array(length)
}
......@@ -9,3 +11,22 @@ export function ones(length: number): Float32Array {
export function expectMaxDelta(val1: number, val2: number, maxDelta: number) {
expect(Math.abs(val1 - val2)).toBeLessThan(maxDelta)
}
export async function createFakeHTMLVideoElement() {
const videoEl = document.createElement('video')
videoEl.muted = true
videoEl.src = 'base/test/media/video.mp4'
await videoEl.pause()
await videoEl.play()
return videoEl
}
export async function expectAllTensorsReleased(fn: () => any) {
const numTensorsBefore = tf.memory().numTensors
await fn()
expect(tf.memory().numTensors - numTensorsBefore).toEqual(0)
}
export function tensor3D() {
return tf.tensor3d([[[0]]])
}
\ No newline at end of file
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