Unverified Commit 12b439fc by justadudewhohacks Committed by GitHub

Merge pull request #20 from justadudewhohacks/all-faces

faceapi.allFaces + global api
parents 9012be3d fe036c90
......@@ -105,6 +105,15 @@ To load a model, you have provide the corresponding manifest.json file as well a
Assuming the models reside in **public/models**:
``` javascript
await faceapi.loadFaceDetectionModel('/models')
// accordingly for the other models:
// await faceapi.loadFaceLandmarkModel('/models')
// await faceapi.loadFaceRecognitionModel('/models')
```
As an alternative, you can also create instance of the neural nets:
``` javascript
const net = new faceapi.FaceDetectionNet()
// accordingly for the other models:
// const net = new faceapi.FaceLandmarkNet()
......@@ -118,7 +127,7 @@ await net.load('/models/face_detection_model-weights_manifest.json')
await net.load('/models')
```
Alternatively you can load the weights as a Float32Array (in case you want to use the uncompressed models):
Using instances, you can also load the weights as a Float32Array (in case you want to use the uncompressed models):
``` javascript
// using fetch
......@@ -145,7 +154,7 @@ const maxResults = 10
// inputs can be html canvas, img or video element or their ids ...
const myImg = document.getElementById('myImg')
const detections = await detectionNet.locateFaces(myImg, minConfidence, maxResults)
const detections = await faceapi.locateFaces(myImg, minConfidence, maxResults)
```
Draw the detected faces to a canvas:
......@@ -162,7 +171,7 @@ faceapi.drawDetection(canvas, detectionsForSize, { withScore: false })
You can also obtain the tensors of the unfiltered bounding boxes and scores for each image in the batch (tensors have to be disposed manually):
``` javascript
const { boxes, scores } = detectionNet.forward('myImg')
const { boxes, scores } = net.forward('myImg')
```
<a name="usage-face-recognition"></a>
......@@ -173,8 +182,8 @@ Compute and compare the descriptors of two face images:
``` javascript
// inputs can be html canvas, img or video element or their ids ...
const descriptor1 = await recognitionNet.computeFaceDescriptor('myImg')
const descriptor2 = await recognitionNet.computeFaceDescriptor(document.getElementById('myCanvas'))
const descriptor1 = await faceapi.computeFaceDescriptor('myImg')
const descriptor2 = await faceapi.computeFaceDescriptor(document.getElementById('myCanvas'))
const distance = faceapi.euclidianDistance(descriptor1, descriptor2)
if (distance < 0.6)
......@@ -183,16 +192,10 @@ else
console.log('no match')
```
You can also get the face descriptor data synchronously:
``` javascript
const desc = recognitionNet.computeFaceDescriptorSync('myImg')
```
Or simply obtain the tensor (tensor has to be disposed manually):
``` javascript
const t = recognitionNet.forward('myImg')
const t = net.forward('myImg')
```
<a name="usage-face-landmark-detection"></a>
......@@ -204,7 +207,7 @@ Detect face landmarks:
``` javascript
// inputs can be html canvas, img or video element or their ids ...
const myImg = document.getElementById('myImg')
const landmarks = await faceLandmarkNet.detectLandmarks(myImg)
const landmarks = await faceapi.detectLandmarks(myImg)
```
Draw the detected face landmarks to a canvas:
......@@ -236,11 +239,11 @@ const rightEyeBrow = landmarks.getRightEyeBrow()
Compute the Face Landmarks for Detected Faces:
``` javascript
const detections = await detectionNet.locateFaces(input)
const detections = await faceapi.locateFaces(input)
// get the face tensors from the image (have to be disposed manually)
const faceTensors = await faceapi.extractFaceTensors(input, detections)
const landmarksByFace = await Promise.all(faceTensors.map(t => faceLandmarkNet.detectLandmarks(t)))
const landmarksByFace = await Promise.all(faceTensors.map(t => faceapi.detectLandmarks(t)))
// free memory for face image tensors after we computed their descriptors
faceTensors.forEach(t => t.dispose())
......@@ -250,11 +253,23 @@ faceTensors.forEach(t => t.dispose())
### Full Face Detection and Recognition Pipeline
After face detection has been performed, I would recommend to align the bounding boxes of the detected faces before passing them to the face recognition net, which will make the computed face descriptor much more accurate. You can easily align the faces from their face landmark positions as shown in the following example:
After face detection has been performed, I would recommend to align the bounding boxes of the detected faces before passing them to the face recognition net, which will make the computed face descriptor much more accurate. Fortunately, the api can do this for you under the hood. You can obtain the full face descriptions (location, landmarks and descriptor) of each face in an input image as follows:
``` javascript
const fullFaceDescriptions = await faceapi.allFaces(input, minConfidence)
const fullFaceDescription0 = fullFaceDescriptions[0]
console.log(fullFaceDescription0.detection) // bounding box & score
console.log(fullFaceDescription0.landmarks) // 68 point face landmarks
console.log(fullFaceDescription0.descriptor) // face descriptors
```
You can also do everything manually as shown in the following:
``` javascript
// first detect the face locations
const detections = await detectionNet.locateFaces(input)
const detections = await faceapi.locateFaces(input, minConfidence)
// get the face tensors from the image (have to be disposed manually)
const faceTensors = (await faceapi.extractFaceTensors(input, detections))
......@@ -262,7 +277,7 @@ const faceTensors = (await faceapi.extractFaceTensors(input, detections))
// detect landmarks and get the aligned face image bounding boxes
const alignedFaceBoxes = await Promise.all(faceTensors.map(
async (faceTensor, i) => {
const faceLandmarks = await landmarkNet.detectLandmarks(faceTensor)
const faceLandmarks = await faceapi.detectLandmarks(faceTensor)
return faceLandmarks.align(detections[i])
}
))
......@@ -275,7 +290,7 @@ const alignedFaceTensors = (await faceapi.extractFaceTensors(input, alignedFaceB
// compute the face descriptors from the aligned face images
const descriptors = await Promise.all(alignedFaceTensors.map(
faceTensor => recognitionNet.computeFaceDescriptor(faceTensor)
faceTensor => faceapi.computeFaceDescriptor(faceTensor)
))
// free memory for face image tensors after we computed their descriptors
......
import { FaceDetection } from './faceDetectionNet/FaceDetection';
import { FaceLandmarks } from './faceLandmarkNet/FaceLandmarks';
export declare class FullFaceDescription {
private _detection;
private _landmarks;
private _descriptor;
constructor(_detection: FaceDetection, _landmarks: FaceLandmarks, _descriptor: Float32Array);
readonly detection: FaceDetection;
readonly landmarks: FaceLandmarks;
readonly descriptor: Float32Array;
forSize(width: number, height: number): FullFaceDescription;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var FullFaceDescription = /** @class */ (function () {
function FullFaceDescription(_detection, _landmarks, _descriptor) {
this._detection = _detection;
this._landmarks = _landmarks;
this._descriptor = _descriptor;
}
Object.defineProperty(FullFaceDescription.prototype, "detection", {
get: function () {
return this._detection;
},
enumerable: true,
configurable: true
});
Object.defineProperty(FullFaceDescription.prototype, "landmarks", {
get: function () {
return this._landmarks;
},
enumerable: true,
configurable: true
});
Object.defineProperty(FullFaceDescription.prototype, "descriptor", {
get: function () {
return this._descriptor;
},
enumerable: true,
configurable: true
});
FullFaceDescription.prototype.forSize = function (width, height) {
return new FullFaceDescription(this._detection.forSize(width, height), this._landmarks.forSize(width, height), this._descriptor);
};
return FullFaceDescription;
}());
exports.FullFaceDescription = FullFaceDescription;
//# sourceMappingURL=FullFaceDescription.js.map
\ No newline at end of file
{"version":3,"file":"FullFaceDescription.js","sourceRoot":"","sources":["../src/FullFaceDescription.ts"],"names":[],"mappings":";;AAGA;IACE,6BACU,UAAyB,EACzB,UAAyB,EACzB,WAAyB;QAFzB,eAAU,GAAV,UAAU,CAAe;QACzB,eAAU,GAAV,UAAU,CAAe;QACzB,gBAAW,GAAX,WAAW,CAAc;IAChC,CAAC;IAEJ,sBAAW,0CAAS;aAApB;YACE,OAAO,IAAI,CAAC,UAAU,CAAA;QACxB,CAAC;;;OAAA;IAED,sBAAW,0CAAS;aAApB;YACE,OAAO,IAAI,CAAC,UAAU,CAAA;QACxB,CAAC;;;OAAA;IAED,sBAAW,2CAAU;aAArB;YACE,OAAO,IAAI,CAAC,WAAW,CAAA;QACzB,CAAC;;;OAAA;IAEM,qCAAO,GAAd,UAAe,KAAa,EAAE,MAAc;QAC1C,OAAO,IAAI,mBAAmB,CAC5B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,EACtC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,EACtC,IAAI,CAAC,WAAW,CACjB,CAAA;IACH,CAAC;IACH,0BAAC;AAAD,CAAC,AA1BD,IA0BC;AA1BY,kDAAmB"}
\ No newline at end of file
{"version":3,"file":"NetInput.js","sourceRoot":"","sources":["../src/NetInput.ts"],"names":[],"mappings":";;AACA,iCAAqG;AAErG;IAGE,kBACE,QAAmB,EACnB,IAAiB;QAFnB,iBA2BC;QAvBC,IAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC3C,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;QAEd,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;YACzB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;SAC1D;QAED,IAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,kBAAU,CAAC,CAAA;QAG5C,MAAM,CAAC,OAAO,CAAC,UAAC,KAAK,EAAE,CAAC;YACtB,IAAI,CAAC,CAAC,KAAK,YAAY,gBAAgB,IAAI,KAAK,YAAY,gBAAgB,IAAI,KAAK,YAAY,iBAAiB,CAAC,EAAE;gBACnH,IAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,qBAAmB,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,CAAA;gBACtE,IAAI,OAAO,aAAa,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;oBACxC,MAAM,IAAI,KAAK,CAAC,eAAa,OAAO,qEAAkE,CAAC,CAAA;iBACxG;gBACD,MAAM,IAAI,KAAK,CAAC,eAAa,OAAO,kHAA+G,CAAC,CAAA;aACrJ;QACH,CAAC,CAAC,CAAA;QAEF,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,AA3DD,IA2DC;AA3DY,4BAAQ"}
\ No newline at end of file
{"version":3,"file":"NetInput.js","sourceRoot":"","sources":["../src/NetInput.ts"],"names":[],"mappings":";;AACA,iCAA4D;AAE5D;IAGE,kBACE,QAAmB,EACnB,IAAiB;QAFnB,iBA2BC;QAvBC,IAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC3C,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;QAEd,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;YACzB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;SAC1D;QAED,IAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,kBAAU,CAAC,CAAA;QAG5C,MAAM,CAAC,OAAO,CAAC,UAAC,KAAK,EAAE,CAAC;YACtB,IAAI,CAAC,CAAC,KAAK,YAAY,gBAAgB,IAAI,KAAK,YAAY,gBAAgB,IAAI,KAAK,YAAY,iBAAiB,CAAC,EAAE;gBACnH,IAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,qBAAmB,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,CAAA;gBACtE,IAAI,OAAO,aAAa,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;oBACxC,MAAM,IAAI,KAAK,CAAC,eAAa,OAAO,qEAAkE,CAAC,CAAA;iBACxG;gBACD,MAAM,IAAI,KAAK,CAAC,eAAa,OAAO,kHAA+G,CAAC,CAAA;aACrJ;QACH,CAAC,CAAC,CAAA;QAEF,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,AA3DD,IA2DC;AA3DY,4BAAQ"}
\ 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[]>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var extractFaceTensors_1 = require("./extractFaceTensors");
var FullFaceDescription_1 = require("./FullFaceDescription");
function allFacesFactory(detectionNet, landmarkNet, recognitionNet) {
return function (input, minConfidence) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var detections, faceTensors, faceLandmarksByFace, alignedFaceBoxes, alignedFaceTensors, descriptors;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, detectionNet.locateFaces(input, minConfidence)];
case 1:
detections = _a.sent();
return [4 /*yield*/, extractFaceTensors_1.extractFaceTensors(input, detections)];
case 2:
faceTensors = _a.sent();
return [4 /*yield*/, Promise.all(faceTensors.map(function (faceTensor) { return landmarkNet.detectLandmarks(faceTensor); }))];
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();
return [4 /*yield*/, extractFaceTensors_1.extractFaceTensors(input, alignedFaceBoxes)];
case 5:
alignedFaceTensors = (_a.sent());
return [4 /*yield*/, Promise.all(alignedFaceTensors.map(function (faceTensor) { return recognitionNet.computeFaceDescriptor(faceTensor); }))];
case 6:
descriptors = _a.sent();
alignedFaceTensors.forEach(function (t) { return t.dispose(); });
return [2 /*return*/, detections.map(function (detection, i) {
return new FullFaceDescription_1.FullFaceDescription(detection, faceLandmarksByFace[i].shiftByPoint(detection.getBox()), descriptors[i]);
})];
}
});
});
};
}
exports.allFacesFactory = allFacesFactory;
//# sourceMappingURL=allFacesFactory.js.map
\ No newline at end of file
{"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;wBAC0B,qBAAM,uCAAkB,CAAC,KAAK,EAAE,gBAAgB,CAAC,EAAA;;wBAAvE,kBAAkB,GAAG,CAAC,SAAiD,CAAC;wBAE1D,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
import { FaceDetectionNet } from './FaceDetectionNet';
export * from './FaceDetectionNet';
export * from './FaceDetection';
export declare function faceDetectionNet(weights: Float32Array): FaceDetectionNet;
......@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var FaceDetectionNet_1 = require("./FaceDetectionNet");
tslib_1.__exportStar(require("./FaceDetectionNet"), exports);
tslib_1.__exportStar(require("./FaceDetection"), exports);
function faceDetectionNet(weights) {
var net = new FaceDetectionNet_1.FaceDetectionNet();
net.extractWeights(weights);
......
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/faceDetectionNet/index.ts"],"names":[],"mappings":";;;AAAA,uDAAsD;AAEtD,6DAAmC;AAEnC,0BAAiC,OAAqB;IACpD,IAAM,GAAG,GAAG,IAAI,mCAAgB,EAAE,CAAA;IAClC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;IAC3B,OAAO,GAAG,CAAA;AACZ,CAAC;AAJD,4CAIC"}
\ No newline at end of file
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/faceDetectionNet/index.ts"],"names":[],"mappings":";;;AAAA,uDAAsD;AAEtD,6DAAmC;AACnC,0DAAgC;AAEhC,0BAAiC,OAAqB;IACpD,IAAM,GAAG,GAAG,IAAI,mCAAgB,EAAE,CAAA;IAClC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;IAC3B,OAAO,GAAG,CAAA;AACZ,CAAC;AAJD,4CAIC"}
\ No newline at end of file
import { Point } from '../Point';
import { IPoint, Point } from '../Point';
import { Rect } from '../Rect';
import { Dimensions } from '../types';
export declare class FaceLandmarks {
......@@ -21,6 +21,7 @@ export declare class FaceLandmarks {
getMouth(): Point[];
forSize(width: number, height: number): FaceLandmarks;
shift(x: number, y: number): FaceLandmarks;
shiftByPoint(pt: IPoint): FaceLandmarks;
/**
* Aligns the face landmarks after face detection from the relative positions of the faces
* bounding box, or it's current shift. This function should be used to align the face images
......
......@@ -60,6 +60,9 @@ var FaceLandmarks = /** @class */ (function () {
FaceLandmarks.prototype.shift = function (x, y) {
return new FaceLandmarks(this.getRelativePositions(), { width: this._imageWidth, height: this._imageHeight }, new Point_1.Point(x, y));
};
FaceLandmarks.prototype.shiftByPoint = function (pt) {
return this.shift(pt.x, pt.y);
};
/**
* Aligns the face landmarks after face detection from the relative positions of the faces
* bounding box, or it's current shift. This function should be used to align the face images
......
{"version":3,"file":"FaceLandmarks.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/FaceLandmarks.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
{"version":3,"file":"FaceLandmarks.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/FaceLandmarks.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
import { FaceLandmarkNet } from './FaceLandmarkNet';
export * from './FaceLandmarkNet';
export * from './FaceLandmarks';
export declare function faceLandmarkNet(weights: Float32Array): FaceLandmarkNet;
......@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var FaceLandmarkNet_1 = require("./FaceLandmarkNet");
tslib_1.__exportStar(require("./FaceLandmarkNet"), exports);
tslib_1.__exportStar(require("./FaceLandmarks"), exports);
function faceLandmarkNet(weights) {
var net = new FaceLandmarkNet_1.FaceLandmarkNet();
net.extractWeights(weights);
......
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/index.ts"],"names":[],"mappings":";;;AAAA,qDAAoD;AAEpD,4DAAkC;AAElC,yBAAgC,OAAqB;IACnD,IAAM,GAAG,GAAG,IAAI,iCAAe,EAAE,CAAA;IACjC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;IAC3B,OAAO,GAAG,CAAA;AACZ,CAAC;AAJD,0CAIC"}
\ No newline at end of file
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/index.ts"],"names":[],"mappings":";;;AAAA,qDAAoD;AAEpD,4DAAkC;AAClC,0DAAgC;AAEhC,yBAAgC,OAAqB;IACnD,IAAM,GAAG,GAAG,IAAI,iCAAe,EAAE,CAAA;IACjC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;IAC3B,OAAO,GAAG,CAAA;AACZ,CAAC;AAJD,0CAIC"}
\ No newline at end of file
......@@ -6,6 +6,6 @@ export declare class FaceRecognitionNet {
load(weightsOrUrl: Float32Array | string | undefined): Promise<void>;
extractWeights(weights: Float32Array): void;
forward(input: tf.Tensor | NetInput | TNetInput): tf.Tensor<tf.Rank.R2>;
computeFaceDescriptor(input: tf.Tensor | NetInput | TNetInput): Promise<Int32Array | Uint8Array | Float32Array>;
computeFaceDescriptorSync(input: tf.Tensor | NetInput | TNetInput): Promise<Int32Array | Uint8Array | Float32Array>;
computeFaceDescriptor(input: tf.Tensor | NetInput | TNetInput): Promise<Float32Array>;
computeFaceDescriptorSync(input: tf.Tensor | NetInput | TNetInput): Promise<Float32Array>;
}
{"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 { FaceDetection } from './faceDetectionNet/FaceDetection';
import { FaceDetectionNet } from './faceDetectionNet/FaceDetectionNet';
import { FaceLandmarkNet } from './faceLandmarkNet/FaceLandmarkNet';
import { FaceLandmarks } from './faceLandmarkNet/FaceLandmarks';
import { FaceRecognitionNet } from './faceRecognitionNet/FaceRecognitionNet';
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;
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 const allFaces: (input: tf.Tensor | NetInput | TNetInput, minConfidence: number) => Promise<FullFaceDescription[]>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var allFacesFactory_1 = require("./allFacesFactory");
var FaceDetectionNet_1 = require("./faceDetectionNet/FaceDetectionNet");
var FaceLandmarkNet_1 = require("./faceLandmarkNet/FaceLandmarkNet");
var FaceRecognitionNet_1 = require("./faceRecognitionNet/FaceRecognitionNet");
exports.detectionNet = new FaceDetectionNet_1.FaceDetectionNet();
exports.landmarkNet = new FaceLandmarkNet_1.FaceLandmarkNet();
exports.recognitionNet = new FaceRecognitionNet_1.FaceRecognitionNet();
function loadFaceDetectionModel(url) {
return exports.detectionNet.load(url);
}
exports.loadFaceDetectionModel = loadFaceDetectionModel;
function loadFaceLandmarkModel(url) {
return exports.landmarkNet.load(url);
}
exports.loadFaceLandmarkModel = loadFaceLandmarkModel;
function loadFaceRecognitionModel(url) {
return exports.recognitionNet.load(url);
}
exports.loadFaceRecognitionModel = loadFaceRecognitionModel;
function loadModels(url) {
return Promise.all([
loadFaceDetectionModel(url),
loadFaceLandmarkModel(url),
loadFaceRecognitionModel(url)
]);
}
exports.loadModels = loadModels;
function locateFaces(input, minConfidence, maxResults) {
return exports.detectionNet.locateFaces(input, minConfidence, maxResults);
}
exports.locateFaces = locateFaces;
function detectLandmarks(input) {
return exports.landmarkNet.detectLandmarks(input);
}
exports.detectLandmarks = detectLandmarks;
function computeFaceDescriptor(input) {
return exports.recognitionNet.computeFaceDescriptor(input);
}
exports.computeFaceDescriptor = computeFaceDescriptor;
exports.allFaces = allFacesFactory_1.allFacesFactory(exports.detectionNet, exports.landmarkNet, exports.recognitionNet);
//# sourceMappingURL=globalApi.js.map
\ 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,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
import * as tf from '@tensorflow/tfjs-core';
import { euclideanDistance } from './euclideanDistance';
import { NetInput } from './NetInput';
import { padToSquare } from './padToSquare';
export { euclideanDistance, NetInput, tf, padToSquare };
export { tf };
export * from './FullFaceDescription';
export * from './NetInput';
export * from './Point';
export * from './Rect';
export * from './euclideanDistance';
export * from './extractFaces';
export * from './extractFaceTensors';
export * from './faceDetectionNet';
export * from './faceLandmarkNet';
export * from './faceRecognitionNet';
export * from './globalApi';
export * from './padToSquare';
export * from './utils';
......@@ -3,16 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var tf = require("@tensorflow/tfjs-core");
exports.tf = tf;
var euclideanDistance_1 = require("./euclideanDistance");
exports.euclideanDistance = euclideanDistance_1.euclideanDistance;
var NetInput_1 = require("./NetInput");
exports.NetInput = NetInput_1.NetInput;
var padToSquare_1 = require("./padToSquare");
exports.padToSquare = padToSquare_1.padToSquare;
tslib_1.__exportStar(require("./FullFaceDescription"), exports);
tslib_1.__exportStar(require("./NetInput"), exports);
tslib_1.__exportStar(require("./Point"), exports);
tslib_1.__exportStar(require("./Rect"), exports);
tslib_1.__exportStar(require("./euclideanDistance"), exports);
tslib_1.__exportStar(require("./extractFaces"), exports);
tslib_1.__exportStar(require("./extractFaceTensors"), exports);
tslib_1.__exportStar(require("./faceDetectionNet"), exports);
tslib_1.__exportStar(require("./faceLandmarkNet"), exports);
tslib_1.__exportStar(require("./faceRecognitionNet"), exports);
tslib_1.__exportStar(require("./globalApi"), exports);
tslib_1.__exportStar(require("./padToSquare"), exports);
tslib_1.__exportStar(require("./utils"), exports);
//# sourceMappingURL=index.js.map
\ No newline at end of file
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,0CAA4C;AAS1C,gBAAE;AAPJ,yDAAwD;AAKtD,4BALO,qCAAiB,CAKP;AAJnB,uCAAsC;AAKpC,mBALO,mBAAQ,CAKP;AAJV,6CAA4C;AAM1C,sBANO,yBAAW,CAMP;AAGb,yDAA8B;AAC9B,+DAAoC;AACpC,6DAAmC;AACnC,4DAAkC;AAClC,+DAAqC;AACrC,kDAAuB"}
\ No newline at end of file
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,0CAA4C;AAG1C,gBAAE;AAGJ,gEAAsC;AACtC,qDAA2B;AAC3B,kDAAwB;AACxB,iDAAuB;AAEvB,8DAAoC;AACpC,yDAA8B;AAC9B,+DAAoC;AACpC,6DAAmC;AACnC,4DAAkC;AAClC,+DAAqC;AACrC,sDAA4B;AAC5B,wDAA8B;AAC9B,kDAAuB"}
\ No newline at end of file
......@@ -21,6 +21,6 @@ export declare function drawText(ctx: CanvasRenderingContext2D, x: number, y: nu
export declare function drawDetection(canvasArg: string | HTMLCanvasElement, detection: FaceDetection | FaceDetection[], options?: DrawBoxOptions & DrawTextOptions & {
withScore: boolean;
}): void;
export declare function drawLandmarks(canvasArg: string | HTMLCanvasElement, faceLandmarks: FaceLandmarks, options?: DrawLandmarksOptions & {
export declare function drawLandmarks(canvasArg: string | HTMLCanvasElement, faceLandmarks: FaceLandmarks | FaceLandmarks[], options?: DrawLandmarksOptions & {
drawLines: boolean;
}): void;
......@@ -161,22 +161,25 @@ function drawLandmarks(canvasArg, faceLandmarks, options) {
var drawLines = Object.assign({ drawLines: false }, (options || {})).drawLines;
var ctx = getContext2dOrThrow(canvas);
var lineWidth = drawOptions.lineWidth, color = drawOptions.color;
if (drawLines) {
ctx.strokeStyle = color;
ctx.lineWidth = lineWidth;
drawContour(ctx, faceLandmarks.getJawOutline());
drawContour(ctx, faceLandmarks.getLeftEyeBrow());
drawContour(ctx, faceLandmarks.getRightEyeBrow());
drawContour(ctx, faceLandmarks.getNose());
drawContour(ctx, faceLandmarks.getLeftEye(), true);
drawContour(ctx, faceLandmarks.getRightEye(), true);
drawContour(ctx, faceLandmarks.getMouth(), true);
return;
}
// else draw points
var ptOffset = lineWidth / 2;
ctx.fillStyle = color;
faceLandmarks.getPositions().forEach(function (pt) { return ctx.fillRect(pt.x - ptOffset, pt.y - ptOffset, lineWidth, lineWidth); });
var faceLandmarksArray = Array.isArray(faceLandmarks) ? faceLandmarks : [faceLandmarks];
faceLandmarksArray.forEach(function (landmarks) {
if (drawLines) {
ctx.strokeStyle = color;
ctx.lineWidth = lineWidth;
drawContour(ctx, landmarks.getJawOutline());
drawContour(ctx, landmarks.getLeftEyeBrow());
drawContour(ctx, landmarks.getRightEyeBrow());
drawContour(ctx, landmarks.getNose());
drawContour(ctx, landmarks.getLeftEye(), true);
drawContour(ctx, landmarks.getRightEye(), true);
drawContour(ctx, landmarks.getMouth(), true);
return;
}
// else draw points
var ptOffset = lineWidth / 2;
ctx.fillStyle = color;
landmarks.getPositions().forEach(function (pt) { return ctx.fillRect(pt.x - ptOffset, pt.y - ptOffset, lineWidth, lineWidth); });
});
}
exports.drawLandmarks = drawLandmarks;
//# sourceMappingURL=utils.js.map
\ 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.
......@@ -54,7 +54,6 @@
<script>
let minConfidence = 0.7
let net
function onIncreaseThreshold() {
minConfidence = Math.min(faceapi.round(minConfidence + 0.1), 1.0)
......@@ -82,7 +81,7 @@
canvas.height = height
const input = new faceapi.NetInput(inputImgEl)
const detections = await net.locateFaces(input, minConfidence)
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)
......@@ -97,8 +96,7 @@
}
async function run() {
net = new faceapi.FaceDetectionNet()
await net.load('/')
await faceapi.loadFaceDetectionModel('/')
$('#loader').hide()
onSelectionChanged($('#selectList select').val())
}
......
......@@ -54,7 +54,6 @@
<script>
let minConfidence = 0.7
let drawLines = true
let detectionNet, landmarkNet
function onIncreaseMinConfidence() {
minConfidence = Math.min(faceapi.round(minConfidence + 0.1), 1.0)
......@@ -88,28 +87,27 @@
canvas.height = height
const input = new faceapi.NetInput(inputImgEl)
const locations = await detectionNet.locateFaces(input, minConfidence)
const locations = await faceapi.locateFaces(input, minConfidence)
const faceTensors = (await faceapi.extractFaceTensors(input, locations))
landmarksByFace = await Promise.all(faceTensors.map(t => landmarkNet.detectLandmarks(t)))
let landmarksByFace = await Promise.all(faceTensors.map(t => faceapi.detectLandmarks(t)))
// free memory for face image tensors after we computed their descriptors
faceTensors.forEach(t => t.dispose())
landmarksByFace.forEach((landmarks, i) => {
// shift and scale the face landmarks to the face image position in the canvas
// shift and scale the face landmarks to the face image position in the canvas
landmarksByFace = landmarksByFace.map((landmarks, i) => {
const box = locations[i].forSize(width, height).getBox()
faceapi.drawLandmarks(canvas, landmarks.forSize(box.width, box.height).shift(box.x, box.y), { lineWidth: drawLines ? 2 : 4, drawLines, color: 'red' })
return landmarks.forSize(box.width, box.height).shift(box.x, box.y)
})
faceapi.drawLandmarks(canvas, landmarksByFace, { lineWidth: drawLines ? 2 : 4, drawLines, color: 'red' })
faceapi.drawDetection('overlay', locations.map(det => det.forSize(width, height)))
}
async function run() {
detectionNet = new faceapi.FaceDetectionNet()
await detectionNet.load('/')
landmarkNet = new faceapi.FaceLandmarkNet()
await landmarkNet.load('/')
await faceapi.loadFaceDetectionModel('/')
await faceapi.loadFaceLandmarkModel('/')
$('#loader').hide()
onSelectionChanged($('#selectList select').val())
}
......
......@@ -111,38 +111,14 @@
canvas.height = height
const input = new faceapi.NetInput(inputImgEl)
const detections = await detectionNet.locateFaces(input, minConfidence)
const faceTensors = (await faceapi.extractFaceTensors(input, detections))
const fullFaceDescriptions = (await faceapi.allFaces(input, minConfidence))
.map(fd => fd.forSize(width, height))
// detect landmarks and get the aligned face image bounding boxes
const alignedFaceBoxes = await Promise.all(faceTensors.map(
async (faceTensor, i) => {
const faceLandmarks = await landmarkNet.detectLandmarks(faceTensor)
return faceLandmarks.align(detections[i])
}
))
// free memory for face image tensors after we detected the face landmarks
faceTensors.forEach(t => t.dispose())
const alignedFaceTensors = (await faceapi.extractFaceTensors(input, alignedFaceBoxes))
const descriptors = await Promise.all(alignedFaceTensors.map(
faceTensor => recognitionNet.computeFaceDescriptor(faceTensor)
))
// free memory for face image tensors after we computed their descriptors
alignedFaceTensors.forEach(t => t.dispose())
// draw detections
const detectionsForSize = detections.map(det => det.forSize(width, height))
faceapi.drawDetection('overlay', detectionsForSize, { withScore: false })
// draw the recognition results
descriptors.forEach((descriptor, i) => {
fullFaceDescriptions.forEach(({ detection, descriptor }) => {
faceapi.drawDetection('overlay', [detection], { withScore: false })
const bestMatch = getBestMatch(trainDescriptorsByClass, descriptor)
const text = `${bestMatch.distance < maxDistance ? bestMatch.className : 'unkown'} (${bestMatch.distance})`
const { x, y, height: boxHeight } = detectionsForSize[i].getBox()
const { x, y, height: boxHeight } = detection.getBox()
faceapi.drawText(
canvas.getContext('2d'),
x,
......@@ -160,13 +136,8 @@
}
async function run() {
detectionNet = new faceapi.FaceDetectionNet()
await detectionNet.load('/')
landmarkNet = new faceapi.FaceLandmarkNet()
await landmarkNet.load('/')
recognitionNet = new faceapi.FaceRecognitionNet()
await recognitionNet.load('/')
trainDescriptorsByClass = await initTrainDescriptorsByClass(recognitionNet, 1)
await faceapi.loadModels('/')
trainDescriptorsByClass = await initTrainDescriptorsByClass(faceapi.recognitionNet, 1)
$('#loader').hide()
onSelectionChanged($('#selectList select').val())
}
......
......@@ -55,7 +55,6 @@
<script>
let minConfidence = 0.7
let drawLines = true
let detectionNet, landmarkNet
function onIncreaseMinConfidence() {
minConfidence = Math.min(faceapi.round(minConfidence + 0.1), 1.0)
......@@ -83,14 +82,14 @@
canvas.height = height
const input = new faceapi.NetInput(inputImgEl)
const locations = await detectionNet.locateFaces(input, minConfidence)
const locations = await faceapi.locateFaces(input, minConfidence)
const faceImages = await faceapi.extractFaces(input.canvases[0], locations)
// detect landmarks and get the aligned face image bounding boxes
const alignedFaceBoxes = await Promise.all(faceImages.map(
async (faceCanvas, i) => {
const faceLandmarks = await landmarkNet.detectLandmarks(faceCanvas)
const faceLandmarks = await faceapi.detectLandmarks(faceCanvas)
return faceLandmarks.align(locations[i])
}
))
......@@ -110,10 +109,8 @@
}
async function run() {
detectionNet = new faceapi.FaceDetectionNet()
await detectionNet.load('/')
landmarkNet = new faceapi.FaceLandmarkNet()
await landmarkNet.load('/')
await faceapi.loadFaceDetectionModel('/')
await faceapi.loadFaceLandmarkModel('/')
$('#loader').hide()
onSelectionChanged($('#selectList select').val())
}
......
......@@ -53,7 +53,7 @@
<script>
let minConfidence = 0.7
let net, result
let result
function onIncreaseThreshold() {
minConfidence = Math.min(faceapi.round(minConfidence + 0.1), 1.0)
......@@ -81,7 +81,7 @@
canvas.height = height
const input = new faceapi.NetInput(inputImgEl)
result = await net.locateFaces(input, minConfidence)
result = await faceapi.locateFaces(input, minConfidence)
faceapi.drawDetection('overlay', result.map(det => det.forSize(width, height)))
}
......@@ -92,8 +92,7 @@
}
async function run() {
net = new faceapi.FaceDetectionNet()
await net.load('/')
await faceapi.loadFaceDetectionModel('/')
$('#loader').hide()
onSelectionChanged($('#selectList select').val())
}
......
......@@ -50,7 +50,7 @@
<script>
let minConfidence = 0.7
let net, result
let result
function onIncreaseThreshold() {
minConfidence = Math.min(faceapi.round(minConfidence + 0.1), 1.0)
......@@ -78,7 +78,7 @@
canvas.height = height
const ts = Date.now()
result = await net.locateFaces(input, minConfidence)
result = await faceapi.locateFaces(input, minConfidence)
displayTimeStats(Date.now() - ts)
faceapi.drawDetection('overlay', result.map(det => det.forSize(width, height)))
......@@ -86,8 +86,7 @@
}
async function run() {
net = new faceapi.FaceDetectionNet()
await net.load('/')
await faceapi.loadFaceDetectionModel('/')
$('#loader').hide()
}
......
......@@ -29,7 +29,6 @@
</div>
<script>
let net
let drawLines = true
let landmarks
let currentImg
......@@ -49,13 +48,12 @@
async function onSelectionChanged(uri) {
const imgBuf = await fetchImage(uri)
currentImg = await faceapi.bufferToImage(imgBuf)
landmarks = await net.detectLandmarks(currentImg)
landmarks = await faceapi.detectLandmarks(currentImg)
redraw()
}
async function run() {
net = new faceapi.FaceLandmarkNet()
await net.load('/')
await faceapi.loadFaceLandmarkModel('/')
$('#loader').hide()
await onSelectionChanged($('#selectList select').val())
}
......
......@@ -69,7 +69,6 @@
let isStop = false
let trainDescriptorsByClass = []
let net
let currImageIdx = 2, currClassIdx = 0
let to = null
......@@ -114,7 +113,7 @@
imgEl.src = input.src
const ts = Date.now()
const descriptor = await net.computeFaceDescriptor(input)
const descriptor = await faceapi.computeFaceDescriptor(input)
displayTimeStats(Date.now() - ts)
const bestMatch = getBestMatch(trainDescriptorsByClass, descriptor)
......@@ -135,12 +134,11 @@
try {
setStatusText('loading model file...')
net = new faceapi.FaceRecognitionNet()
await net.load('/')
await faceapi.loadFaceRecognitionModel('/')
setStatusText('computing initial descriptors...')
trainDescriptorsByClass = await initTrainDescriptorsByClass(net)
trainDescriptorsByClass = await initTrainDescriptorsByClass(faceapi.recognitionNet)
$('#loader').hide()
runFaceRecognition()
......
......@@ -35,7 +35,7 @@
<script>
const threshold = 0.6
let net, descriptors = { desc1: null, desc2: null }
let descriptors = { desc1: null, desc2: null }
function updateResult() {
const distance = faceapi.round(
......@@ -56,12 +56,11 @@
const input = await faceapi.bufferToImage(imgBuf)
const imgEl = $(`#face${which}`).get(0)
imgEl.src = input.src
descriptors[`desc${which}`] = await net.computeFaceDescriptor(input)
descriptors[`desc${which}`] = await faceapi.computeFaceDescriptor(input)
}
async function run() {
net = new faceapi.FaceRecognitionNet()
await net.load('/')
await faceapi.loadFaceRecognitionModel()
$('#loader').hide()
await onSelectionChanged(1, $('#selectList1 select').val())
await onSelectionChanged(2, $('#selectList2 select').val())
......
import { FaceDetection } from './faceDetectionNet/FaceDetection';
import { FaceLandmarks } from './faceLandmarkNet/FaceLandmarks';
export class FullFaceDescription {
constructor(
private _detection: FaceDetection,
private _landmarks: FaceLandmarks,
private _descriptor: Float32Array
) {}
public get detection(): FaceDetection {
return this._detection
}
public get landmarks(): FaceLandmarks {
return this._landmarks
}
public get descriptor(): Float32Array {
return this._descriptor
}
public forSize(width: number, height: number): FullFaceDescription {
return new FullFaceDescription(
this._detection.forSize(width, height),
this._landmarks.forSize(width, height),
this._descriptor
)
}
}
\ No newline at end of file
import { Dimensions, TMediaElement, TNetInput } from './types';
import { createCanvasFromMedia, getContext2dOrThrow, getElement, getMediaDimensions } from './utils';
import { createCanvasFromMedia, getElement } from './utils';
export class NetInput {
private _canvases: HTMLCanvasElement[]
......
import * as tf from '@tensorflow/tfjs-core';
import { extractFaceTensors } from './extractFaceTensors';
import { FaceDetectionNet } from './faceDetectionNet/FaceDetectionNet';
import { FaceLandmarkNet } from './faceLandmarkNet/FaceLandmarkNet';
import { FaceRecognitionNet } from './faceRecognitionNet/FaceRecognitionNet';
import { FullFaceDescription } from './FullFaceDescription';
import { NetInput } from './NetInput';
import { TNetInput } from './types';
export function allFacesFactory(
detectionNet: FaceDetectionNet,
landmarkNet: FaceLandmarkNet,
recognitionNet: FaceRecognitionNet
) {
return async function(
input: tf.Tensor | NetInput | 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)
))
faceTensors.forEach(t => t.dispose())
const alignedFaceBoxes = await Promise.all(faceLandmarksByFace.map(
(landmarks, i) => landmarks.align(detections[i].getBox())
))
const alignedFaceTensors = (await extractFaceTensors(input, alignedFaceBoxes))
const descriptors = await Promise.all(alignedFaceTensors.map(
faceTensor => recognitionNet.computeFaceDescriptor(faceTensor)
))
alignedFaceTensors.forEach(t => t.dispose())
return detections.map((detection, i) =>
new FullFaceDescription(
detection,
faceLandmarksByFace[i].shiftByPoint(detection.getBox()),
descriptors[i]
)
)
}
}
\ No newline at end of file
import { FaceDetectionNet } from './FaceDetectionNet';
export * from './FaceDetectionNet';
export * from './FaceDetection';
export function faceDetectionNet(weights: Float32Array) {
const net = new FaceDetectionNet()
......
import { getCenterPoint } from '../commons/getCenterPoint';
import { FaceDetection } from '../faceDetectionNet/FaceDetection';
import { Point } from '../Point';
import { IPoint, Point } from '../Point';
import { Rect } from '../Rect';
import { Dimensions } from '../types';
......@@ -94,6 +94,10 @@ export class FaceLandmarks {
)
}
public shiftByPoint(pt: IPoint): FaceLandmarks {
return this.shift(pt.x, pt.y)
}
/**
* Aligns the face landmarks after face detection from the relative positions of the faces
* bounding box, or it's current shift. This function should be used to align the face images
......
import { FaceLandmarkNet } from './FaceLandmarkNet';
export * from './FaceLandmarkNet';
export * from './FaceLandmarks';
export function faceLandmarkNet(weights: Float32Array) {
const net = new FaceLandmarkNet()
......
......@@ -77,13 +77,13 @@ export class FaceRecognitionNet {
const result = this.forward(input)
const data = await result.data()
result.dispose()
return data
return data as Float32Array
}
public async computeFaceDescriptorSync(input: tf.Tensor | NetInput | TNetInput) {
const result = this.forward(input)
const data = result.dataSync()
result.dispose()
return data
return data as Float32Array
}
}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { allFacesFactory } from './allFacesFactory';
import { FaceDetection } from './faceDetectionNet/FaceDetection';
import { FaceDetectionNet } from './faceDetectionNet/FaceDetectionNet';
import { FaceLandmarkNet } from './faceLandmarkNet/FaceLandmarkNet';
import { FaceLandmarks } from './faceLandmarkNet/FaceLandmarks';
import { FaceRecognitionNet } from './faceRecognitionNet/FaceRecognitionNet';
import { NetInput } from './NetInput';
import { TNetInput } from './types';
import { FullFaceDescription } from './FullFaceDescription';
export const detectionNet = new FaceDetectionNet()
export const landmarkNet = new FaceLandmarkNet()
export const recognitionNet = new FaceRecognitionNet()
export function loadFaceDetectionModel(url: string) {
return detectionNet.load(url)
}
export function loadFaceLandmarkModel(url: string) {
return landmarkNet.load(url)
}
export function loadFaceRecognitionModel(url: string) {
return recognitionNet.load(url)
}
export function loadModels(url: string) {
return Promise.all([
loadFaceDetectionModel(url),
loadFaceLandmarkModel(url),
loadFaceRecognitionModel(url)
])
}
export function locateFaces(
input: tf.Tensor | NetInput | TNetInput,
minConfidence?: number,
maxResults?: number
): Promise<FaceDetection[]> {
return detectionNet.locateFaces(input, minConfidence, maxResults)
}
export function detectLandmarks(
input: tf.Tensor | NetInput | TNetInput
): Promise<FaceLandmarks> {
return landmarkNet.detectLandmarks(input)
}
export function computeFaceDescriptor(
input: tf.Tensor | NetInput | TNetInput
): Promise<Float32Array> {
return recognitionNet.computeFaceDescriptor(input)
}
export const allFaces: (
input: tf.Tensor | NetInput | TNetInput,
minConfidence: number
) => Promise<FullFaceDescription[]> = allFacesFactory(
detectionNet,
landmarkNet,
recognitionNet
)
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { euclideanDistance } from './euclideanDistance';
import { NetInput } from './NetInput';
import { padToSquare } from './padToSquare';
export {
euclideanDistance,
NetInput,
tf,
padToSquare
tf
}
export * from './FullFaceDescription';
export * from './NetInput';
export * from './Point';
export * from './Rect';
export * from './euclideanDistance';
export * from './extractFaces'
export * from './extractFaceTensors'
export * from './faceDetectionNet';
export * from './faceLandmarkNet';
export * from './faceRecognitionNet';
export * from './globalApi';
export * from './padToSquare';
export * from './utils'
\ No newline at end of file
......@@ -211,7 +211,7 @@ function drawContour(
export function drawLandmarks(
canvasArg: string | HTMLCanvasElement,
faceLandmarks: FaceLandmarks,
faceLandmarks: FaceLandmarks | FaceLandmarks[],
options?: DrawLandmarksOptions & { drawLines: boolean }
) {
const canvas = getElement(canvasArg)
......@@ -229,21 +229,25 @@ export function drawLandmarks(
const ctx = getContext2dOrThrow(canvas)
const { lineWidth, color } = drawOptions
if (drawLines) {
ctx.strokeStyle = color
ctx.lineWidth = lineWidth
drawContour(ctx, faceLandmarks.getJawOutline())
drawContour(ctx, faceLandmarks.getLeftEyeBrow())
drawContour(ctx, faceLandmarks.getRightEyeBrow())
drawContour(ctx, faceLandmarks.getNose())
drawContour(ctx, faceLandmarks.getLeftEye(), true)
drawContour(ctx, faceLandmarks.getRightEye(), true)
drawContour(ctx, faceLandmarks.getMouth(), true)
return
}
const faceLandmarksArray = Array.isArray(faceLandmarks) ? faceLandmarks : [faceLandmarks]
faceLandmarksArray.forEach(landmarks => {
if (drawLines) {
ctx.strokeStyle = color
ctx.lineWidth = lineWidth
drawContour(ctx, landmarks.getJawOutline())
drawContour(ctx, landmarks.getLeftEyeBrow())
drawContour(ctx, landmarks.getRightEyeBrow())
drawContour(ctx, landmarks.getNose())
drawContour(ctx, landmarks.getLeftEye(), true)
drawContour(ctx, landmarks.getRightEye(), true)
drawContour(ctx, landmarks.getMouth(), true)
return
}
// else draw points
const ptOffset = lineWidth / 2
ctx.fillStyle = color
faceLandmarks.getPositions().forEach(pt => ctx.fillRect(pt.x - ptOffset, pt.y - ptOffset, lineWidth, lineWidth))
// else draw points
const ptOffset = lineWidth / 2
ctx.fillStyle = color
landmarks.getPositions().forEach(pt => ctx.fillRect(pt.x - ptOffset, pt.y - ptOffset, lineWidth, lineWidth))
})
}
\ 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