ngx-face-api-js
Version:
Angular directives for face detection and face recognition in the browser. It is a wrapper for face-api.js, so it is not dependent on the browser implementation.
945 lines (927 loc) • 34.1 kB
JavaScript
import { BrowserModule } from '@angular/platform-browser';
import { of, fromEvent, interval, Subscription, Subject, combineLatest } from 'rxjs';
import * as faceapi from 'face-api.js';
import { resizeResults, FaceDetection, draw, round, loadSsdMobilenetv1Model, loadMtcnnModel, loadFaceExpressionModel, loadFaceLandmarkModel, loadFaceRecognitionModel, loadTinyFaceDetectorModel, loadAgeGenderModel, DetectSingleFaceTask, DetectAllFacesTask } from 'face-api.js';
import { switchMap, shareReplay, map, startWith } from 'rxjs/operators';
import { ComponentPortal, PortalModule } from '@angular/cdk/portal';
import { __extends, __read, __awaiter, __generator, __spread } from 'tslib';
import { InjectionToken, Injectable, Inject, Optional, Component, ViewChild, ElementRef, Renderer2, HostListener, Injector, Directive, Input, NgModule } from '@angular/core';
import { OverlayConfig, Overlay, OverlayModule } from '@angular/cdk/overlay';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var DetectTask = /** @class */ (function () {
function DetectTask(option) {
var _this = this;
this.type = option.type;
this.tokens = option.tokens;
this.realtime = option.realtime || false;
this.target = new Promise((/**
* @param {?} resolver
* @return {?}
*/
function (resolver) { return (_this.targetResolver = resolver); }));
}
Object.defineProperty(DetectTask.prototype, "resolveTarget", {
get: /**
* @return {?}
*/
function () {
return this.targetResolver;
},
enumerable: true,
configurable: true
});
/**
* @private
* @param {?} patten
* @param {?} target
* @return {?}
*/
DetectTask.prototype.isMatchPattern = /**
* @private
* @param {?} patten
* @param {?} target
* @return {?}
*/
function (patten, target) {
return patten.every((/**
* @param {?} item
* @return {?}
*/
function (item) { return target.includes(item); }));
};
/**
* @template THIS
* @this {THIS}
* @param {...?} tokens
* @return {THIS}
*/
DetectTask.prototype.with = /**
* @template THIS
* @this {THIS}
* @param {...?} tokens
* @return {THIS}
*/
function () {
var tokens = [];
for (var _i = 0; _i < arguments.length; _i++) {
tokens[_i] = arguments[_i];
}
var _a;
(_a = (/** @type {?} */ (this)).tokens).push.apply(_a, __spread(tokens));
return (/** @type {?} */ (this));
};
/**
* @param {?=} option
* @return {?}
*/
DetectTask.prototype.detect = /**
* @param {?=} option
* @return {?}
*/
function (option) {
return __awaiter(this, void 0, void 0, function () {
var t, _a, _b, _c, _d;
return __generator(this, function (_e) {
switch (_e.label) {
case 0:
if (!(this.type === 'all')) return [3 /*break*/, 2];
_b = (_a = faceapi).detectAllFaces;
return [4 /*yield*/, this.target];
case 1:
t = _b.apply(_a, [_e.sent(), option || undefined]);
return [3 /*break*/, 4];
case 2:
_d = (_c = faceapi).detectSingleFace;
return [4 /*yield*/, this.target];
case 3:
t = _d.apply(_c, [_e.sent(), option || undefined]);
_e.label = 4;
case 4:
if (this.isMatchPattern(['expressions', 'landmarks', 'ageAndGender', 'descriptors'], this.tokens)) {
if (t instanceof DetectSingleFaceTask) {
return [2 /*return*/, t
.withFaceLandmarks()
.withFaceExpressions()
.withAgeAndGender()
.withFaceDescriptor()
.run()];
}
else if (t instanceof DetectAllFacesTask) {
return [2 /*return*/, t
.withFaceLandmarks()
.withFaceExpressions()
.withAgeAndGender()
.withFaceDescriptors()
.run()];
}
}
else if (this.isMatchPattern(['expressions', 'landmarks', 'descriptors'], this.tokens)) {
if (t instanceof DetectSingleFaceTask) {
return [2 /*return*/, t
.withFaceLandmarks()
.withFaceExpressions()
.withFaceDescriptor()
.run()];
}
else if (t instanceof DetectAllFacesTask) {
return [2 /*return*/, t
.withFaceLandmarks()
.withFaceExpressions()
.withFaceDescriptors()
.run()];
}
}
else if (this.isMatchPattern(['expressions', 'landmarks', 'ageAndGender'], this.tokens)) {
return [2 /*return*/, t
.withFaceLandmarks()
.withFaceExpressions()
.withAgeAndGender()
.run()];
}
else if (this.isMatchPattern(['expressions', 'landmarks'], this.tokens)) {
return [2 /*return*/, t
.withFaceLandmarks()
.withFaceExpressions()
.run()];
}
else if (this.isMatchPattern(['expressions', 'ageAndGender'], this.tokens)) {
return [2 /*return*/, t
.withFaceExpressions()
.withAgeAndGender()
.run()];
}
else if (this.isMatchPattern(['expressions'], this.tokens)) {
return [2 /*return*/, t.withFaceExpressions().run()];
}
else if (this.isMatchPattern(['landmarks', 'ageAndGender'], this.tokens)) {
return [2 /*return*/, t
.withFaceLandmarks()
.withAgeAndGender()
.run()];
}
else if (this.isMatchPattern(['landmarks'], this.tokens)) {
return [2 /*return*/, t.withFaceLandmarks().run()];
}
return [2 /*return*/, t.run()];
}
});
});
};
return DetectTask;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var FaceDetectionOptions = new InjectionToken('ngx-face-api-js.face-detection-options');
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var ExpressionsFeatureToken = 'expressions';
/** @type {?} */
var LandmarksFeatureToken = 'landmarks';
/** @type {?} */
var DescriptorsFeatureToken = 'descriptors';
/** @type {?} */
var AgeAndGenderToken = 'ageAndGender';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var SsdMobilenetv1Model = 'SsdMobilenetv1Model';
/** @type {?} */
var MtcnnModel = 'MtcnnModel';
/** @type {?} */
var FaceExpressionModel = 'FaceExpressionModel';
/** @type {?} */
var FaceLandmarkModel = 'FaceLandmarkModel';
/** @type {?} */
var FaceRecognitionModel = 'FaceRecognitionModel';
/** @type {?} */
var TinyFaceDetectorModel = 'TinyFaceDetectorModel';
/** @type {?} */
var AgeAndGenderModel = 'AgeAndGenderModel';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var ModelsUrl = new InjectionToken('ngx-face-api-js.models-url');
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var ModelLoaderService = /** @class */ (function () {
function ModelLoaderService(modelUrl) {
this.modelUrl = modelUrl;
this.loadedModels = [];
}
/**
* @private
* @param {?} tokens
* @return {?}
*/
ModelLoaderService.prototype.getReqiredModels = /**
* @private
* @param {?} tokens
* @return {?}
*/
function (tokens) {
var _a;
return [SsdMobilenetv1Model].concat(Object.entries((_a = {},
_a[ExpressionsFeatureToken] = [FaceExpressionModel, SsdMobilenetv1Model],
_a[LandmarksFeatureToken] = [FaceLandmarkModel, SsdMobilenetv1Model],
_a[DescriptorsFeatureToken] = [FaceRecognitionModel],
_a[AgeAndGenderToken] = [AgeAndGenderModel],
_a))
.map((/**
* @param {?} __0
* @return {?}
*/
function (_a) {
var _b = __read(_a, 2), key = _b[0], models = _b[1];
return tokens.includes((/** @type {?} */ (key))) ? models : [];
}))
.reduce((/**
* @param {?} a
* @param {?} b
* @return {?}
*/
function (a, b) { return a.concat(b); }))
.filter((/**
* @param {?} v
* @param {?} i
* @param {?} arr
* @return {?}
*/
function (v, i, arr) { return arr.indexOf(v) === i; })));
};
/**
* @private
* @param {?} model
* @return {?}
*/
ModelLoaderService.prototype.mapLoadFunction = /**
* @private
* @param {?} model
* @return {?}
*/
function (model) {
switch (model) {
case SsdMobilenetv1Model:
return loadSsdMobilenetv1Model;
case MtcnnModel:
return loadMtcnnModel;
case FaceExpressionModel:
return loadFaceExpressionModel;
case FaceLandmarkModel:
return loadFaceLandmarkModel;
case FaceRecognitionModel:
return loadFaceRecognitionModel;
case TinyFaceDetectorModel:
return loadTinyFaceDetectorModel;
case AgeAndGenderModel:
return loadAgeGenderModel;
}
};
/**
* @param {?} model
* @return {?}
*/
ModelLoaderService.prototype.isLoaded = /**
* @param {?} model
* @return {?}
*/
function (model) {
return this.loadedModels.includes(model);
};
/**
* @param {...?} models
* @return {?}
*/
ModelLoaderService.prototype.load = /**
* @param {...?} models
* @return {?}
*/
function () {
var models = [];
for (var _i = 0; _i < arguments.length; _i++) {
models[_i] = arguments[_i];
}
return __awaiter(this, void 0, void 0, function () {
var loadTargetModels;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
loadTargetModels = models.filter((/**
* @param {?} m
* @return {?}
*/
function (m) { return _this.isLoaded(m) === false; }));
return [4 /*yield*/, Promise.all(loadTargetModels
.map((/**
* @param {?} m
* @return {?}
*/
function (m) { return _this.mapLoadFunction(m); }))
.map((/**
* @param {?} load
* @return {?}
*/
function (load) { return load(_this.modelUrl); })))];
case 1:
_a.sent();
if (loadTargetModels.length >= 0) {
this.loadedModels = loadTargetModels.concat(this.loadedModels);
}
return [2 /*return*/];
}
});
});
};
/**
* @param {?} tokens
* @return {?}
*/
ModelLoaderService.prototype.loadForFeature = /**
* @param {?} tokens
* @return {?}
*/
function (tokens) {
return __awaiter(this, void 0, void 0, function () {
var reqiredModels;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
reqiredModels = this.getReqiredModels(tokens);
console.log({ reqiredModels: reqiredModels });
return [4 /*yield*/, this.load.apply(this, __spread(reqiredModels))];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
ModelLoaderService.decorators = [
{ type: Injectable }
];
/** @nocollapse */
ModelLoaderService.ctorParameters = function () { return [
{ type: String, decorators: [{ type: Inject, args: [ModelsUrl,] }] }
]; };
return ModelLoaderService;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var FaceDetectorService = /** @class */ (function () {
function FaceDetectorService(modelLoader, option) {
this.modelLoader = modelLoader;
this.option = option;
}
/**
* @param {?} task
* @return {?}
*/
FaceDetectorService.prototype.detect = /**
* @param {?} task
* @return {?}
*/
function (task) {
var _this = this;
if (task.realtime === true) {
return of(task).pipe(switchMap((/**
* @param {?} t
* @return {?}
*/
function (t) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, t.target];
case 1: return [2 /*return*/, _a.sent()];
}
}); }); })), switchMap((/**
* @param {?} video
* @return {?}
*/
function (video) { return fromEvent(video, 'loadeddata'); })), switchMap((/**
* @return {?}
*/
function () { return _this.modelLoader.loadForFeature(task.tokens); })), switchMap((/**
* @return {?}
*/
function () { return interval(300); })), switchMap((/**
* @return {?}
*/
function () { return task.detect(_this.option); })), shareReplay(1));
}
return of(task).pipe(switchMap((/**
* @param {?} t
* @return {?}
*/
function (t) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, t.target];
case 1: return [2 /*return*/, _a.sent()];
}
}); }); })), switchMap((/**
* @param {?} image
* @return {?}
*/
function (image) { return fromEvent(image, 'load'); })), switchMap((/**
* @return {?}
*/
function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.modelLoader.loadForFeature(task.tokens)];
case 1: return [2 /*return*/, _a.sent()];
}
}); }); })), switchMap((/**
* @return {?}
*/
function () { return task.detect(_this.option); })), shareReplay(1));
};
FaceDetectorService.decorators = [
{ type: Injectable }
];
/** @nocollapse */
FaceDetectorService.ctorParameters = function () { return [
{ type: ModelLoaderService },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [FaceDetectionOptions,] }] }
]; };
return FaceDetectorService;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var DetectionResultComponent = /** @class */ (function () {
function DetectionResultComponent(task, el, renderer, faceDetector) {
this.task = task;
this.el = el;
this.renderer = renderer;
this.faceDetector = faceDetector;
this.subscription = new Subscription();
this.resize$ = new Subject();
}
Object.defineProperty(DetectionResultComponent.prototype, "canvas", {
get: /**
* @private
* @return {?}
*/
function () {
return this.canvasEl.nativeElement;
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
DetectionResultComponent.prototype.onResize = /**
* @return {?}
*/
function () {
this.resize$.next('onResize');
};
/**
* @private
* @param {?} result
* @return {?}
*/
DetectionResultComponent.prototype.convertResultToArray = /**
* @private
* @param {?} result
* @return {?}
*/
function (result) {
if (Array.isArray(result)) {
return result;
}
return [result];
};
/**
* @return {?}
*/
DetectionResultComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
var _this = this;
this.subscription.add(combineLatest(this.faceDetector.detect(this.task), this.resize$.pipe(startWith('init')))
.pipe(map((/**
* @param {?} __0
* @return {?}
*/
function (_a) {
var _b = __read(_a, 1), result = _b[0];
return _this.convertResultToArray(result);
})))
.subscribe((/**
* @param {?} result
* @return {?}
*/
function (result) { return _this.draw(result); })));
};
/**
* @return {?}
*/
DetectionResultComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.subscription.unsubscribe();
};
/**
* @private
* @param {?} results
* @return {?}
*/
DetectionResultComponent.prototype.draw = /**
* @private
* @param {?} results
* @return {?}
*/
function (results) {
return __awaiter(this, void 0, void 0, function () {
var target, width, height, detectionsForSize, resizeResults$$1;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.task.target];
case 1:
target = _a.sent();
width = target.width, height = target.height;
if (target instanceof HTMLVideoElement) {
height = target.videoHeight;
width = target.videoWidth;
}
detectionsForSize = resizeResults(results.map((/**
* @param {?} result
* @return {?}
*/
function (result) {
return result instanceof FaceDetection ? result : result.detection;
})), { width: width, height: height });
this.canvas.width = width;
this.canvas.height = height;
this.renderer.setStyle(this.canvas, 'width', width + "px");
this.renderer.setStyle(this.canvas, 'height', height + "px");
if (this.task.tokens.length >= 1) {
draw.drawDetections(this.canvas, detectionsForSize);
resizeResults$$1 = resizeResults(results, { width: width, height: height });
if (this.task.tokens.includes('expressions')) {
draw.drawFaceExpressions(this.canvas, resizeResults$$1.map((/**
* @param {?} __0
* @return {?}
*/
function (_a) {
var detection = _a.detection, expressions = _a.expressions;
return ({
position: detection.box,
expressions: expressions,
});
})));
}
if (this.task.tokens.includes('landmarks')) {
draw.drawFaceLandmarks(this.canvas, resizeResults$$1.map((/**
* @param {?} __0
* @return {?}
*/
function (_a) {
var landmarks = _a.landmarks;
return landmarks;
})));
}
if (this.task.tokens.includes('ageAndGender')) {
resizeResults$$1.forEach((/**
* @param {?} result
* @return {?}
*/
function (result) {
var age = result.age, gender = result.gender, genderProbability = result.genderProbability;
/** @type {?} */
var text = new draw.DrawTextField([
round(age, 0) + " years",
gender + " (" + round(genderProbability) + ")",
], result.detection.box.bottomLeft);
text.draw(_this.canvas);
}));
}
}
else {
draw.drawDetections(this.canvas, detectionsForSize);
}
return [2 /*return*/];
}
});
});
};
DetectionResultComponent.decorators = [
{ type: Component, args: [{
template: "<canvas #canvas></canvas>\n",
styles: ["canvas{width:100%;height:100%}"]
}] }
];
/** @nocollapse */
DetectionResultComponent.ctorParameters = function () { return [
{ type: DetectTask },
{ type: ElementRef },
{ type: Renderer2 },
{ type: FaceDetectorService }
]; };
DetectionResultComponent.propDecorators = {
canvasEl: [{ type: ViewChild, args: ['canvas',] }],
onResize: [{ type: HostListener, args: ['window:resize',] }]
};
return DetectionResultComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @abstract
*/
var /**
* @abstract
*/
AbstractDetectDirective = /** @class */ (function () {
function AbstractDetectDirective(el, overlay, injector) {
this.el = el;
this.overlay = overlay;
this.injector = injector;
this.with = [];
}
/**
* @return {?}
*/
AbstractDetectDirective.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.task = new DetectTask({
type: this.type,
tokens: this.with,
realtime: this.stream,
});
};
Object.defineProperty(AbstractDetectDirective.prototype, "orverlayPositionStrategy", {
get: /**
* @private
* @return {?}
*/
function () {
return this.overlay
.position()
.flexibleConnectedTo(this.el)
.withPositions([
{
overlayX: 'start',
overlayY: 'top',
originX: 'start',
originY: 'top',
},
])
.withFlexibleDimensions(false)
.withLockedPosition(true);
},
enumerable: true,
configurable: true
});
/**
* @private
* @return {?}
*/
AbstractDetectDirective.prototype.createOverlay = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var scrollStrategy = this.overlay.scrollStrategies.reposition();
/** @type {?} */
var config = new OverlayConfig({
positionStrategy: this.orverlayPositionStrategy,
scrollStrategy: scrollStrategy,
hasBackdrop: false,
});
return this.overlay.create(config);
};
/**
* @private
* @return {?}
*/
AbstractDetectDirective.prototype.createInjector = /**
* @private
* @return {?}
*/
function () {
return Injector.create({
parent: this.injector,
providers: [
{
provide: DetectTask,
useValue: this.task,
},
],
});
};
/**
* @return {?}
*/
AbstractDetectDirective.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
this.task.resolveTarget(this.el.nativeElement);
/** @type {?} */
var overlayRef = this.createOverlay();
/** @type {?} */
var injector = this.createInjector();
/** @type {?} */
var portal = new ComponentPortal(DetectionResultComponent, undefined, injector);
overlayRef.attach(portal);
};
return AbstractDetectDirective;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var DetectAllFacesImgDirective = /** @class */ (function (_super) {
__extends(DetectAllFacesImgDirective, _super);
function DetectAllFacesImgDirective(el, overlay, injector) {
var _this = _super.call(this, el, overlay, injector) || this;
_this.with = [];
_this.type = 'all';
_this.stream = false;
return _this;
}
DetectAllFacesImgDirective.decorators = [
{ type: Directive, args: [{
selector: 'img[allFaces]',
exportAs: 'faces',
},] }
];
/** @nocollapse */
DetectAllFacesImgDirective.ctorParameters = function () { return [
{ type: ElementRef },
{ type: Overlay },
{ type: Injector }
]; };
DetectAllFacesImgDirective.propDecorators = {
with: [{ type: Input }]
};
return DetectAllFacesImgDirective;
}(AbstractDetectDirective));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var DetectSingleFaceImgDirective = /** @class */ (function (_super) {
__extends(DetectSingleFaceImgDirective, _super);
function DetectSingleFaceImgDirective(el, overlay, injector) {
var _this = _super.call(this, el, overlay, injector) || this;
_this.with = [];
_this.type = 'single';
_this.stream = false;
return _this;
}
/**
* @return {?}
*/
DetectSingleFaceImgDirective.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.task = new DetectTask({
type: this.type,
tokens: this.with,
realtime: this.stream,
});
};
DetectSingleFaceImgDirective.decorators = [
{ type: Directive, args: [{
selector: 'img[singleFace]',
exportAs: 'face',
},] }
];
/** @nocollapse */
DetectSingleFaceImgDirective.ctorParameters = function () { return [
{ type: ElementRef },
{ type: Overlay },
{ type: Injector }
]; };
DetectSingleFaceImgDirective.propDecorators = {
with: [{ type: Input }]
};
return DetectSingleFaceImgDirective;
}(AbstractDetectDirective));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var DetectAllFacesVideoDirective = /** @class */ (function (_super) {
__extends(DetectAllFacesVideoDirective, _super);
function DetectAllFacesVideoDirective(el, overlay, injector) {
var _this = _super.call(this, el, overlay, injector) || this;
_this.with = [];
_this.type = 'all';
_this.stream = true;
return _this;
}
DetectAllFacesVideoDirective.decorators = [
{ type: Directive, args: [{
selector: 'video[allFaces]',
exportAs: 'faces',
},] }
];
/** @nocollapse */
DetectAllFacesVideoDirective.ctorParameters = function () { return [
{ type: ElementRef },
{ type: Overlay },
{ type: Injector }
]; };
DetectAllFacesVideoDirective.propDecorators = {
with: [{ type: Input }]
};
return DetectAllFacesVideoDirective;
}(AbstractDetectDirective));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var NgxFaceApiJsModule = /** @class */ (function () {
function NgxFaceApiJsModule() {
}
/**
* @param {?} options
* @return {?}
*/
NgxFaceApiJsModule.forRoot = /**
* @param {?} options
* @return {?}
*/
function (options) {
return {
ngModule: NgxFaceApiJsModule,
providers: __spread([
{
provide: ModelsUrl,
useValue: options.modelsUrl,
},
ModelLoaderService,
FaceDetectorService
], [
options.faceDetectionOptions
? {
provide: FaceDetectionOptions,
useValue: options.faceDetectionOptions,
}
: [],
]),
};
};
NgxFaceApiJsModule.decorators = [
{ type: NgModule, args: [{
declarations: [
DetectionResultComponent,
DetectAllFacesImgDirective,
DetectSingleFaceImgDirective,
DetectAllFacesVideoDirective,
],
imports: [BrowserModule, OverlayModule, PortalModule],
exports: [
DetectAllFacesImgDirective,
DetectSingleFaceImgDirective,
DetectAllFacesVideoDirective,
],
entryComponents: [DetectionResultComponent],
},] }
];
return NgxFaceApiJsModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
export { DetectTask, FaceDetectionOptions, ExpressionsFeatureToken, LandmarksFeatureToken, DescriptorsFeatureToken, AgeAndGenderToken, SsdMobilenetv1Model, MtcnnModel, FaceExpressionModel, FaceLandmarkModel, FaceRecognitionModel, TinyFaceDetectorModel, AgeAndGenderModel, ModelsUrl, FaceDetectorService, ModelLoaderService, NgxFaceApiJsModule, DetectionResultComponent as ɵa, AbstractDetectDirective as ɵc, DetectAllFacesImgDirective as ɵb, DetectAllFacesVideoDirective as ɵe, DetectSingleFaceImgDirective as ɵd };
//# sourceMappingURL=ngx-face-api-js.js.map