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.
228 lines • 18.4 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Component, ViewChild, ElementRef, Renderer2, HostListener, } from '@angular/core';
import { Subscription, Subject, combineLatest } from 'rxjs';
import * as faceapi from 'face-api.js';
import { map, startWith } from 'rxjs/operators';
import { DetectTask } from '../../classes/DetectTask';
import { FaceDetectorService } from '../../services/face-detector.service';
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 = tslib_1.__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 tslib_1.__awaiter(this, void 0, void 0, function () {
var target, width, height, detectionsForSize, resizeResults;
var _this = this;
return tslib_1.__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 = faceapi.resizeResults(results.map((/**
* @param {?} result
* @return {?}
*/
function (result) {
return result instanceof faceapi.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) {
faceapi.draw.drawDetections(this.canvas, detectionsForSize);
resizeResults = faceapi.resizeResults(results, { width: width, height: height });
if (this.task.tokens.includes('expressions')) {
faceapi.draw.drawFaceExpressions(this.canvas, resizeResults.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')) {
faceapi.draw.drawFaceLandmarks(this.canvas, resizeResults.map((/**
* @param {?} __0
* @return {?}
*/
function (_a) {
var landmarks = _a.landmarks;
return landmarks;
})));
}
if (this.task.tokens.includes('ageAndGender')) {
resizeResults.forEach((/**
* @param {?} result
* @return {?}
*/
function (result) {
var age = result.age, gender = result.gender, genderProbability = result.genderProbability;
/** @type {?} */
var text = new faceapi.draw.DrawTextField([
faceapi.round(age, 0) + " years",
gender + " (" + faceapi.round(genderProbability) + ")",
], result.detection.box.bottomLeft);
text.draw(_this.canvas);
}));
}
}
else {
faceapi.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;
}());
export { DetectionResultComponent };
if (false) {
/** @type {?} */
DetectionResultComponent.prototype.subscription;
/**
* @type {?}
* @private
*/
DetectionResultComponent.prototype.canvasEl;
/**
* @type {?}
* @private
*/
DetectionResultComponent.prototype.resize$;
/**
* @type {?}
* @private
*/
DetectionResultComponent.prototype.task;
/**
* @type {?}
* @private
*/
DetectionResultComponent.prototype.el;
/**
* @type {?}
* @private
*/
DetectionResultComponent.prototype.renderer;
/**
* @type {?}
* @private
*/
DetectionResultComponent.prototype.faceDetector;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV0ZWN0aW9uLXJlc3VsdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtZmFjZS1hcGktanMvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy9kZXRlY3Rpb24tcmVzdWx0L2RldGVjdGlvbi1yZXN1bHQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUNMLFNBQVMsRUFFVCxTQUFTLEVBQ1QsVUFBVSxFQUNWLFNBQVMsRUFFVCxZQUFZLEdBQ2IsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRTVELE9BQU8sS0FBSyxPQUFPLE1BQU0sYUFBYSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBRTNFO0lBcUJFLGtDQUNVLElBQWdCLEVBQ2hCLEVBQWMsRUFDZCxRQUFtQixFQUNuQixZQUFpQztRQUhqQyxTQUFJLEdBQUosSUFBSSxDQUFZO1FBQ2hCLE9BQUUsR0FBRixFQUFFLENBQVk7UUFDZCxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBQ25CLGlCQUFZLEdBQVosWUFBWSxDQUFxQjtRQXBCM0MsaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBUzFCLFlBQU8sR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0lBWTdCLENBQUM7SUFoQkosc0JBQVksNENBQU07Ozs7O1FBQWxCO1lBQ0UsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQztRQUNyQyxDQUFDOzs7T0FBQTs7OztJQUtNLDJDQUFROzs7SUFEZjtRQUVFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFD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QUFDLENBQUM7eUJBQzdEOzs7OztLQUNGOztnQkF6R0YsU0FBUyxTQUFDO29CQUNULHVDQUFnRDs7aUJBRWpEOzs7O2dCQU5RLFVBQVU7Z0JBVGpCLFVBQVU7Z0JBQ1YsU0FBUztnQkFTRixtQkFBbUI7OzsyQkFTekIsU0FBUyxTQUFDLFFBQVE7MkJBU2xCLFlBQVksU0FBQyxlQUFlOztJQTBGL0IsK0JBQUM7Q0FBQSxBQTFHRCxJQTBHQztTQXRHWSx3QkFBd0I7OztJQUNuQyxnREFBa0M7Ozs7O0lBRWxDLDRDQUNnRDs7Ozs7SUFNaEQsMkNBQWdDOzs7OztJQVE5Qix3Q0FBd0I7Ozs7O0lBQ3hCLHNDQUFzQjs7Ozs7SUFDdEIsNENBQTJCOzs7OztJQUMzQixnREFBeUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIE9uSW5pdCxcbiAgVmlld0NoaWxkLFxuICBFbGVtZW50UmVmLFxuICBSZW5kZXJlcjIsXG4gIE9uRGVzdHJveSxcbiAgSG9zdExpc3RlbmVyLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiwgU3ViamVjdCwgY29tYmluZUxhdGVzdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgKiBhcyBmYWNlYXBpIGZyb20gJ2ZhY2UtYXBpLmpzJztcbmltcG9ydCB7IG1hcCwgc3RhcnRXaXRoIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgRGV0ZWN0VGFzayB9IGZyb20gJy4uLy4uL2NsYXNzZXMvRGV0ZWN0VGFzayc7XG5pbXBvcnQgeyBGYWNlRGV0ZWN0b3JTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZmFjZS1kZXRlY3Rvci5zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gIHRlbXBsYXRlVXJsOiAnLi9kZXRlY3Rpb24tcmVzdWx0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZGV0ZWN0aW9uLXJlc3VsdC5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBEZXRlY3Rpb25SZXN1bHRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIHN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICBAVmlld0NoaWxkKCdjYW52YXMnKVxuICBwcml2YXRlIGNhbnZhc0VsOiBFbGVtZW50UmVmPEhUTUxDYW52YXNFbGVtZW50PjtcblxuICBwcml2YXRlIGdldCBjYW52YXMoKTogSFRNTENhbnZhc0VsZW1lbnQge1xuICAgIHJldHVybiB0aGlzLmNhbnZhc0VsLm5hdGl2ZUVsZW1lbnQ7XG4gIH1cblxuICBwcml2YXRlIHJlc2l6ZSQgPSBuZXcgU3ViamVjdCgpO1xuXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnKVxuICBwdWJsaWMgb25SZXNpemUoKSB7XG4gICAgdGhpcy5yZXNpemUkLm5leHQoJ29uUmVzaXplJyk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHRhc2s6IERldGVjdFRhc2ssXG4gICAgcHJpdmF0ZSBlbDogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSBmYWNlRGV0ZWN0b3I6IEZhY2VEZXRlY3RvclNlcnZpY2UsXG4gICkge31cblxuICBwcml2YXRlIGNvbnZlcnRSZXN1bHRUb0FycmF5KHJlc3VsdDogYW55KTogYW55W10ge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHJlc3VsdCkpIHtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIHJldHVybiBbcmVzdWx0XTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZChcbiAgICAgIGNvbWJpbmVMYXRlc3QoXG4gICAgICAgIHRoaXMuZmFjZURldGVjdG9yLmRldGVjdCh0aGlzLnRhc2spLFxuICAgICAgICB0aGlzLnJlc2l6ZSQucGlwZShzdGFydFdpdGgoJ2luaXQnKSksXG4gICAgICApXG4gICAgICAgIC5waXBlKG1hcCgoW3Jlc3VsdF0pID0+IHRoaXMuY29udmVydFJlc3VsdFRvQXJyYXkocmVzdWx0KSkpXG4gICAgICAgIC5zdWJzY3JpYmUocmVzdWx0ID0+IHRoaXMuZHJhdyhyZXN1bHQpKSxcbiAgICApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxuICBwcml2YXRlIGFzeW5jIGRyYXcocmVzdWx0czogYW55W10pIHtcbiAgICBjb25zdCB0YXJnZXQgPSBhd2FpdCB0aGlzLnRhc2sudGFyZ2V0O1xuICAgIGxldCB7IHdpZHRoLCBoZWlnaHQgfSA9IHRhcmdldDtcbiAgICBpZiAodGFyZ2V0IGluc3RhbmNlb2YgSFRNTFZpZGVvRWxlbWVudCkge1xuICAgICAgaGVpZ2h0ID0gdGFyZ2V0LnZpZGVvSGVpZ2h0O1xuICAgICAgd2lkdGggPSB0YXJnZXQudmlkZW9XaWR0aDtcbiAgICB9XG5cbiAgICBjb25zdCBkZXRlY3Rpb25zRm9yU2l6ZSA9IGZhY2VhcGkucmVzaXplUmVzdWx0cyhcbiAgICAgIHJlc3VsdHMubWFwKHJlc3VsdCA9PlxuICAgICAgICByZXN1bHQgaW5zdGFuY2VvZiBmYWNlYXBpLkZhY2VEZXRlY3Rpb24gPyByZXN1bHQgOiByZXN1bHQuZGV0ZWN0aW9uLFxuICAgICAgKSxcbiAgICAgIHsgd2lkdGgsIGhlaWdodCB9LFxuICAgICk7XG5cbiAgICB0aGlzLmNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgIHRoaXMuY2FudmFzLmhlaWdodCA9IGhlaWdodDtcbiAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuY2FudmFzLCAnd2lkdGgnLCBgJHt3aWR0aH1weGApO1xuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5jYW52YXMsICdoZWlnaHQnLCBgJHtoZWlnaHR9cHhgKTtcbiAgICBpZiAodGhpcy50YXNrLnRva2Vucy5sZW5ndGggPj0gMSkge1xuICAgICAgZmFjZWFwaS5kcmF3LmRyYXdEZXRlY3Rpb25zKHRoaXMuY2FudmFzLCBkZXRlY3Rpb25zRm9yU2l6ZSk7XG5cbiAgICAgIGNvbnN0IHJlc2l6ZVJlc3VsdHMgPSBmYWNlYXBpLnJlc2l6ZVJlc3VsdHMocmVzdWx0cywgeyB3aWR0aCwgaGVpZ2h0IH0pO1xuICAgICAgaWYgKHRoaXMudGFzay50b2tlbnMuaW5jbHVkZXMoJ2V4cHJlc3Npb25zJykpIHtcbiAgICAgICAgZmFjZWFwaS5kcmF3LmRyYXdGYWNlRXhwcmVzc2lvbnMoXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgcmVzaXplUmVzdWx0cy5tYXAoKHsgZGV0ZWN0aW9uLCBleHByZXNzaW9ucyB9KSA9PiAoe1xuICAgICAgICAgICAgcG9zaXRpb246IGRldGVjdGlvbi5ib3gsXG4gICAgICAgICAgICBleHByZXNzaW9ucyxcbiAgICAgICAgICB9KSksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnRhc2sudG9rZW5zLmluY2x1ZGVzKCdsYW5kbWFya3MnKSkge1xuICAgICAgICBmYWNlYXBpLmRyYXcuZHJhd0ZhY2VMYW5kbWFya3MoXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgcmVzaXplUmVzdWx0cy5tYXAoKHsgbGFuZG1hcmtzIH0pID0+IGxhbmRtYXJrcyksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnRhc2sudG9rZW5zLmluY2x1ZGVzKCdhZ2VBbmRHZW5kZXInKSkge1xuICAgICAgICByZXNpemVSZXN1bHRzLmZvckVhY2gocmVzdWx0ID0+IHtcbiAgICAgICAgICBjb25zdCB7IGFnZSwgZ2VuZGVyLCBnZW5kZXJQcm9iYWJpbGl0eSB9ID0gcmVzdWx0O1xuICAgICAgICAgIGNvbnN0IHRleHQgPSBuZXcgZmFjZWFwaS5kcmF3LkRyYXdUZXh0RmllbGQoXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgIGAke2ZhY2VhcGkucm91bmQoYWdlLCAwKX0geWVhcnNgLFxuICAgICAgICAgICAgICBgJHtnZW5kZXJ9ICgke2ZhY2VhcGkucm91bmQoZ2VuZGVyUHJvYmFiaWxpdHkpfSlgLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHJlc3VsdC5kZXRlY3Rpb24uYm94LmJvdHRvbUxlZnQsXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0ZXh0LmRyYXcodGhpcy5jYW52YXMpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZmFjZWFwaS5kcmF3LmRyYXdEZXRlY3Rpb25zKHRoaXMuY2FudmFzLCBkZXRlY3Rpb25zRm9yU2l6ZSk7XG4gICAgfVxuICB9XG59XG4iXX0=