Commit 3f4aa56d by vincent

merge with master

parents 896371af 661f228b
...@@ -2,7 +2,8 @@ node_modules ...@@ -2,7 +2,8 @@ node_modules
.rpt2_cache .rpt2_cache
examples examples
test
proto proto
weights weights
weights_uncompressed
test
tools tools
\ No newline at end of file
...@@ -10,7 +10,10 @@ export declare class Rect implements IRect { ...@@ -10,7 +10,10 @@ export declare class Rect implements IRect {
width: number; width: number;
height: number; height: number;
constructor(x: number, y: number, width: number, height: number); constructor(x: number, y: number, width: number, height: number);
readonly right: number;
readonly bottom: number;
toSquare(): Rect; toSquare(): Rect;
pad(padX: number, padY: number): Rect; pad(padX: number, padY: number): Rect;
floor(): Rect; floor(): Rect;
clipAtImageBorders(imgWidth: number, imgHeight: number): Rect;
} }
...@@ -7,6 +7,20 @@ var Rect = /** @class */ (function () { ...@@ -7,6 +7,20 @@ var Rect = /** @class */ (function () {
this.width = width; this.width = width;
this.height = height; this.height = height;
} }
Object.defineProperty(Rect.prototype, "right", {
get: function () {
return this.x + this.width;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rect.prototype, "bottom", {
get: function () {
return this.y + this.height;
},
enumerable: true,
configurable: true
});
Rect.prototype.toSquare = function () { Rect.prototype.toSquare = function () {
var _a = this, x = _a.x, y = _a.y, width = _a.width, height = _a.height; var _a = this, x = _a.x, y = _a.y, width = _a.width, height = _a.height;
var diff = Math.abs(width - height); var diff = Math.abs(width - height);
...@@ -27,6 +41,16 @@ var Rect = /** @class */ (function () { ...@@ -27,6 +41,16 @@ var Rect = /** @class */ (function () {
Rect.prototype.floor = function () { Rect.prototype.floor = function () {
return new Rect(Math.floor(this.x), Math.floor(this.y), Math.floor(this.width), Math.floor(this.height)); return new Rect(Math.floor(this.x), Math.floor(this.y), Math.floor(this.width), Math.floor(this.height));
}; };
Rect.prototype.clipAtImageBorders = function (imgWidth, imgHeight) {
var _a = this, x = _a.x, y = _a.y, right = _a.right, bottom = _a.bottom;
var clippedX = Math.max(x, 0);
var clippedY = Math.max(y, 0);
var newWidth = right - clippedX;
var newHeight = bottom - clippedY;
var clippedWidth = Math.min(newWidth, imgWidth - clippedX);
var clippedHeight = Math.min(newHeight, imgHeight - clippedY);
return (new Rect(clippedX, clippedY, clippedWidth, clippedHeight)).floor();
};
return Rect; return Rect;
}()); }());
exports.Rect = Rect; exports.Rect = Rect;
......
{"version":3,"file":"Rect.js","sourceRoot":"","sources":["../src/Rect.ts"],"names":[],"mappings":";;AAOA;IAME,cAAY,CAAS,EAAE,CAAS,EAAE,KAAa,EAAE,MAAc;QAC7D,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAEM,uBAAQ,GAAf;QACM,IAAA,SAA8B,EAA5B,QAAC,EAAE,QAAC,EAAE,gBAAK,EAAE,kBAAM,CAAS;QAClC,IAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,CAAA;QACrC,IAAI,KAAK,GAAG,MAAM,EAAE;YAClB,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAA;YACf,KAAK,IAAI,IAAI,CAAA;SACd;QACD,IAAI,MAAM,GAAG,KAAK,EAAE;YAClB,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAA;YACf,MAAM,IAAI,IAAI,CAAA;SACf;QACD,OAAO,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;IACtC,CAAC;IAEM,kBAAG,GAAV,UAAW,IAAY,EAAE,IAAY;QAC/B,IAAA,SAA8B,EAA5B,QAAC,EAAE,QAAC,EAAE,gBAAK,EAAE,kBAAM,CAAS;QAClC,OAAO,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,CAAA;IAC9E,CAAC;IAEM,oBAAK,GAAZ;QACE,OAAO,IAAI,IAAI,CACb,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAClB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAClB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EACtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CACxB,CAAA;IACH,CAAC;IACH,WAAC;AAAD,CAAC,AAxCD,IAwCC;AAxCY,oBAAI"} {"version":3,"file":"Rect.js","sourceRoot":"","sources":["../src/Rect.ts"],"names":[],"mappings":";;AAOA;IAME,cAAY,CAAS,EAAE,CAAS,EAAE,KAAa,EAAE,MAAc;QAC7D,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED,sBAAW,uBAAK;aAAhB;YACE,OAAO,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAA;QAC5B,CAAC;;;OAAA;IAED,sBAAW,wBAAM;aAAjB;YACE,OAAO,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAA;QAC7B,CAAC;;;OAAA;IAEM,uBAAQ,GAAf;QACM,IAAA,SAA8B,EAA5B,QAAC,EAAE,QAAC,EAAE,gBAAK,EAAE,kBAAM,CAAS;QAClC,IAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,CAAA;QACrC,IAAI,KAAK,GAAG,MAAM,EAAE;YAClB,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAA;YACf,KAAK,IAAI,IAAI,CAAA;SACd;QACD,IAAI,MAAM,GAAG,KAAK,EAAE;YAClB,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAA;YACf,MAAM,IAAI,IAAI,CAAA;SACf;QACD,OAAO,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;IACtC,CAAC;IAEM,kBAAG,GAAV,UAAW,IAAY,EAAE,IAAY;QAC/B,IAAA,SAA8B,EAA5B,QAAC,EAAE,QAAC,EAAE,gBAAK,EAAE,kBAAM,CAAS;QAClC,OAAO,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,CAAA;IAC9E,CAAC;IAEM,oBAAK,GAAZ;QACE,OAAO,IAAI,IAAI,CACb,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAClB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAClB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EACtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CACxB,CAAA;IACH,CAAC;IAEM,iCAAkB,GAAzB,UAA0B,QAAgB,EAAE,SAAiB;QACrD,IAAA,SAA8B,EAA5B,QAAC,EAAE,QAAC,EAAE,gBAAK,EAAE,kBAAM,CAAS;QACpC,IAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAC/B,IAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAE/B,IAAM,QAAQ,GAAG,KAAK,GAAG,QAAQ,CAAA;QACjC,IAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAA;QACnC,IAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC,CAAA;QAC5D,IAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,GAAG,QAAQ,CAAC,CAAA;QAE/D,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,EAAE,CAAA;IAC5E,CAAC;IACH,WAAC;AAAD,CAAC,AA7DD,IA6DC;AA7DY,oBAAI"}
\ No newline at end of file \ No newline at end of file
import { BoundingBox } from '../BoundingBox';
export declare function iou(box1: BoundingBox, box2: BoundingBox, isIOU?: boolean): number;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function iou(box1, box2, isIOU) {
if (isIOU === void 0) { isIOU = true; }
var width = Math.max(0.0, Math.min(box1.right, box2.right) - Math.max(box1.left, box2.left) + 1);
var height = Math.max(0.0, Math.min(box1.bottom, box2.bottom) - Math.max(box1.top, box2.top) + 1);
var interSection = width * height;
return isIOU
? interSection / (box1.area + box2.area - interSection)
: interSection / Math.min(box1.area, box2.area);
}
exports.iou = iou;
//# sourceMappingURL=iou.js.map
\ No newline at end of file
{"version":3,"file":"iou.js","sourceRoot":"","sources":["../../src/commons/iou.ts"],"names":[],"mappings":";;AAEA,aAAoB,IAAiB,EAAE,IAAiB,EAAE,KAAqB;IAArB,sBAAA,EAAA,YAAqB;IAC7E,IAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IAClG,IAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;IACnG,IAAM,YAAY,GAAG,KAAK,GAAG,MAAM,CAAA;IAEnC,OAAO,KAAK;QACV,CAAC,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACvD,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;AACnD,CAAC;AARD,kBAQC"}
\ No newline at end of file
...@@ -16,11 +16,13 @@ function getModelUris(uri, defaultModelName) { ...@@ -16,11 +16,13 @@ function getModelUris(uri, defaultModelName) {
manifestUri: "/" + defaultManifestFilename manifestUri: "/" + defaultManifestFilename
}; };
} }
var protocol = uri.startsWith('http://') ? 'http://' : uri.startsWith('https://') ? 'https://' : '';
uri = uri.replace(protocol, '');
var parts = uri.split('/').filter(function (s) { return s; }); var parts = uri.split('/').filter(function (s) { return s; });
var manifestFile = uri.endsWith('.json') var manifestFile = uri.endsWith('.json')
? parts[parts.length - 1] ? parts[parts.length - 1]
: defaultManifestFilename; : defaultManifestFilename;
var modelBaseUri = (uri.endsWith('.json') ? parts.slice(0, parts.length - 1) : parts).join('/'); var modelBaseUri = protocol + (uri.endsWith('.json') ? parts.slice(0, parts.length - 1) : parts).join('/');
modelBaseUri = uri.startsWith('/') ? "/" + modelBaseUri : modelBaseUri; modelBaseUri = uri.startsWith('/') ? "/" + modelBaseUri : modelBaseUri;
return { return {
modelBaseUri: modelBaseUri, modelBaseUri: modelBaseUri,
......
{"version":3,"file":"loadWeightMap.js","sourceRoot":"","sources":["../../src/commons/loadWeightMap.ts"],"names":[],"mappings":";;;AAAA,0CAA4C;AAE5C,sBAA6B,GAAuB,EAAE,gBAAwB;IAC5E,IAAM,uBAAuB,GAAM,gBAAgB,2BAAwB,CAAA;IAE3E,IAAI,CAAC,GAAG,EAAE;QACR,OAAO;YACL,YAAY,EAAE,EAAE;YAChB,WAAW,EAAE,uBAAuB;SACrC,CAAA;KACF;IAED,IAAI,GAAG,KAAK,GAAG,EAAE;QACf,OAAO;YACL,YAAY,EAAE,GAAG;YACjB,WAAW,EAAE,MAAI,uBAAyB;SAC3C,CAAA;KACF;IAED,IAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,EAAD,CAAC,CAAC,CAAA;IAE3C,IAAM,YAAY,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;QACxC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QACzB,CAAC,CAAC,uBAAuB,CAAA;IAE3B,IAAI,YAAY,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC/F,YAAY,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAI,YAAc,CAAC,CAAC,CAAC,YAAY,CAAA;IAEtE,OAAO;QACL,YAAY,cAAA;QACZ,WAAW,EAAE,YAAY,KAAK,GAAG,CAAC,CAAC,CAAC,MAAI,YAAc,CAAC,CAAC,CAAI,YAAY,SAAI,YAAc;KAC3F,CAAA;AACH,CAAC;AA9BD,oCA8BC;AAED,uBACE,GAAuB,EACvB,gBAAwB;;;;;;oBAGlB,KAAgC,YAAY,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAAjE,WAAW,iBAAA,EAAE,YAAY,kBAAA,CAAwC;oBAEjD,qBAAM,KAAK,CAAC,WAAW,CAAC,EAAA;wBAA/B,qBAAM,CAAC,SAAwB,CAAC,CAAC,IAAI,EAAE,EAAA;;oBAAlD,QAAQ,GAAG,SAAuC;oBAExD,sBAAO,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAA;;;;CACjD;AAVD,sCAUC"} {"version":3,"file":"loadWeightMap.js","sourceRoot":"","sources":["../../src/commons/loadWeightMap.ts"],"names":[],"mappings":";;;AAAA,0CAA4C;AAE5C,sBAA6B,GAAuB,EAAE,gBAAwB;IAC5E,IAAM,uBAAuB,GAAM,gBAAgB,2BAAwB,CAAA;IAE3E,IAAI,CAAC,GAAG,EAAE;QACR,OAAO;YACL,YAAY,EAAE,EAAE;YAChB,WAAW,EAAE,uBAAuB;SACrC,CAAA;KACF;IAED,IAAI,GAAG,KAAK,GAAG,EAAE;QACf,OAAO;YACL,YAAY,EAAE,GAAG;YACjB,WAAW,EAAE,MAAI,uBAAyB;SAC3C,CAAA;KACF;IACD,IAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IACtG,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAEhC,IAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,EAAD,CAAC,CAAC,CAAA;IAE3C,IAAM,YAAY,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;QACxC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QACzB,CAAC,CAAC,uBAAuB,CAAA;IAE3B,IAAI,YAAY,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC1G,YAAY,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAI,YAAc,CAAC,CAAC,CAAC,YAAY,CAAA;IAEtE,OAAO;QACL,YAAY,cAAA;QACZ,WAAW,EAAE,YAAY,KAAK,GAAG,CAAC,CAAC,CAAC,MAAI,YAAc,CAAC,CAAC,CAAI,YAAY,SAAI,YAAc;KAC3F,CAAA;AACH,CAAC;AAhCD,oCAgCC;AAED,uBACE,GAAuB,EACvB,gBAAwB;;;;;;oBAGlB,KAAgC,YAAY,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAAjE,WAAW,iBAAA,EAAE,YAAY,kBAAA,CAAwC;oBAEjD,qBAAM,KAAK,CAAC,WAAW,CAAC,EAAA;wBAA/B,qBAAM,CAAC,SAAwB,CAAC,CAAC,IAAI,EAAE,EAAA;;oBAAlD,QAAQ,GAAG,SAAuC;oBAExD,sBAAO,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAA;;;;CACjD;AAVD,sCAUC"}
\ No newline at end of file \ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
export declare function normalize(x: tf.Tensor4D, meanRgb: number[]): tf.Tensor4D;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tf = require("@tensorflow/tfjs-core");
function normalize(x, meanRgb) {
return tf.tidy(function () {
var r = meanRgb[0], g = meanRgb[1], b = meanRgb[2];
var avg_r = tf.fill(x.shape.slice(0, 3).concat([1]), r);
var avg_g = tf.fill(x.shape.slice(0, 3).concat([1]), g);
var avg_b = tf.fill(x.shape.slice(0, 3).concat([1]), b);
var avg_rgb = tf.concat([avg_r, avg_g, avg_b], 3);
return tf.sub(x, avg_rgb);
});
}
exports.normalize = normalize;
//# sourceMappingURL=normalize.js.map
\ No newline at end of file
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/commons/normalize.ts"],"names":[],"mappings":";;AAAA,0CAA4C;AAE5C,mBAA0B,CAAc,EAAE,OAAiB;IACzD,OAAO,EAAE,CAAC,IAAI,CAAC;QACN,IAAA,cAAC,EAAE,cAAC,EAAE,cAAC,CAAW;QACzB,IAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,SAAE,CAAC,IAAG,CAAC,CAAC,CAAA;QACrD,IAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,SAAE,CAAC,IAAG,CAAC,CAAC,CAAA;QACrD,IAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,SAAE,CAAC,IAAG,CAAC,CAAC,CAAA;QACrD,IAAM,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;QAEnD,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;IAC3B,CAAC,CAAC,CAAA;AACJ,CAAC;AAVD,8BAUC"}
\ No newline at end of file
...@@ -32,8 +32,9 @@ function extractFaceTensors(input, detections) { ...@@ -32,8 +32,9 @@ function extractFaceTensors(input, detections) {
var imgTensor = netInput.inputs[0].expandDims().toFloat(); var imgTensor = netInput.inputs[0].expandDims().toFloat();
var _a = imgTensor.shape.slice(1), imgHeight = _a[0], imgWidth = _a[1], numChannels = _a[2]; 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 var boxes = detections.map(function (det) { return det instanceof FaceDetection_1.FaceDetection
? det.forSize(imgWidth, imgHeight).getBox().floor() ? det.forSize(imgWidth, imgHeight).getBox()
: det; }); : det; })
.map(function (box) { return box.clipAtImageBorders(imgWidth, imgHeight); });
var faceTensors = boxes.map(function (_a) { var faceTensors = boxes.map(function (_a) {
var x = _a.x, y = _a.y, width = _a.width, height = _a.height; 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]); return tf.slice(imgTensor, [0, y, x, 0], [1, height, width, numChannels]);
......
{"version":3,"file":"extractFaceTensors.js","sourceRoot":"","sources":["../src/extractFaceTensors.ts"],"names":[],"mappings":";;;AAAA,0CAA4C;AAE5C,iDAAgD;AAEhD,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"} {"version":3,"file":"extractFaceTensors.js","sourceRoot":"","sources":["../src/extractFaceTensors.ts"],"names":[],"mappings":";;;AAAA,0CAA4C;AAE5C,iDAAgD;AAEhD,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;gCAC3C,CAAC,CAAC,GAAG,EAFA,CAEA,CACR;iCACE,GAAG,CAAC,UAAA,GAAG,IAAI,OAAA,GAAG,CAAC,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,EAA3C,CAA2C,CAAC,CAAA;4BAE1D,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;AAnCD,gDAmCC"}
\ No newline at end of file \ No newline at end of file
...@@ -39,7 +39,8 @@ function extractFaces(input, detections) { ...@@ -39,7 +39,8 @@ function extractFaces(input, detections) {
ctx = utils_1.getContext2dOrThrow(canvas); ctx = utils_1.getContext2dOrThrow(canvas);
boxes = detections.map(function (det) { return det instanceof FaceDetection_1.FaceDetection boxes = detections.map(function (det) { return det instanceof FaceDetection_1.FaceDetection
? det.forSize(canvas.width, canvas.height).getBox().floor() ? det.forSize(canvas.width, canvas.height).getBox().floor()
: det; }); : det; })
.map(function (box) { return box.clipAtImageBorders(canvas.width, canvas.height); });
return [2 /*return*/, boxes.map(function (_a) { return [2 /*return*/, boxes.map(function (_a) {
var x = _a.x, y = _a.y, width = _a.width, height = _a.height; var x = _a.x, y = _a.y, width = _a.width, height = _a.height;
var faceImg = utils_1.createCanvas({ width: width, height: height }); var faceImg = utils_1.createCanvas({ width: width, height: height });
......
{"version":3,"file":"extractFaces.js","sourceRoot":"","sources":["../src/extractFaces.ts"],"names":[],"mappings":";;;AAAA,iDAAgD;AAEhD,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;oBAEtD,IAAI,QAAQ,CAAC,SAAS,EAAE;wBACtB,QAAQ,CAAC,OAAO,EAAE,CAAA;qBACnB;;;oBAGG,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;AArCD,oCAqCC"} {"version":3,"file":"extractFaces.js","sourceRoot":"","sources":["../src/extractFaces.ts"],"names":[],"mappings":";;;AAAA,iDAAgD;AAEhD,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;oBAEtD,IAAI,QAAQ,CAAC,SAAS,EAAE;wBACtB,QAAQ,CAAC,OAAO,EAAE,CAAA;qBACnB;;;oBAGG,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;yBACE,GAAG,CAAC,UAAA,GAAG,IAAI,OAAA,GAAG,CAAC,kBAAkB,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAnD,CAAmD,CAAC,CAAA;oBAElE,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;AAvCD,oCAuCC"}
\ No newline at end of file \ No newline at end of file
import { BoundingBox } from './BoundingBox';
export declare function iou(box1: BoundingBox, box2: BoundingBox, isIOU?: boolean): number;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function iou(box1, box2, isIOU) {
if (isIOU === void 0) { isIOU = true; }
var width = Math.max(0.0, Math.min(box1.right, box2.right) - Math.max(box1.left, box2.left) + 1);
var height = Math.max(0.0, Math.min(box1.bottom, box2.bottom) - Math.max(box1.top, box2.top) + 1);
var interSection = width * height;
return isIOU
? interSection / (box1.area + box2.area - interSection)
: interSection / Math.min(box1.area, box2.area);
}
exports.iou = iou;
//# sourceMappingURL=iou.js.map
\ No newline at end of file
{"version":3,"file":"iou.js","sourceRoot":"","sources":["../src/iou.ts"],"names":[],"mappings":";;AAEA,aAAoB,IAAiB,EAAE,IAAiB,EAAE,KAAqB;IAArB,sBAAA,EAAA,YAAqB;IAC7E,IAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IAClG,IAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;IACnG,IAAM,YAAY,GAAG,KAAK,GAAG,MAAM,CAAA;IAEnC,OAAO,KAAK;QACV,CAAC,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACvD,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;AACnD,CAAC;AARD,kBAQC"}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
export declare function normalize(x: tf.Tensor4D): tf.Tensor4D;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tf = require("@tensorflow/tfjs-core");
function normalize(x) {
return tf.tidy(function () {
var avg_r = tf.fill(x.shape.slice(0, 3).concat([1]), 117.001);
var avg_g = tf.fill(x.shape.slice(0, 3).concat([1]), 114.697);
var avg_b = tf.fill(x.shape.slice(0, 3).concat([1]), 97.404);
var avg_rgb = tf.concat([avg_r, avg_g, avg_b], 3);
return tf.sub(x, avg_rgb);
});
}
exports.normalize = normalize;
//# sourceMappingURL=normalize.js.map
\ No newline at end of file
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/tinyYolov2/normalize.ts"],"names":[],"mappings":";;AAAA,0CAA2C;AAE3C,mBAA0B,CAAc;IACtC,OAAO,EAAE,CAAC,IAAI,CAAC;QACb,IAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,SAAE,CAAC,IAAG,OAAO,CAAC,CAAA;QAC3D,IAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,SAAE,CAAC,IAAG,OAAO,CAAC,CAAA;QAC3D,IAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,SAAE,CAAC,IAAG,MAAM,CAAC,CAAA;QAC1D,IAAM,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;QAEnD,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;IAC3B,CAAC,CAAC,CAAA;AACJ,CAAC;AATD,8BASC"}
\ No newline at end of file
...@@ -242,6 +242,20 @@ ...@@ -242,6 +242,20 @@
this.width = width; this.width = width;
this.height = height; this.height = height;
} }
Object.defineProperty(Rect.prototype, "right", {
get: function () {
return this.x + this.width;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rect.prototype, "bottom", {
get: function () {
return this.y + this.height;
},
enumerable: true,
configurable: true
});
Rect.prototype.toSquare = function () { Rect.prototype.toSquare = function () {
var _a = this, x = _a.x, y = _a.y, width = _a.width, height = _a.height; var _a = this, x = _a.x, y = _a.y, width = _a.width, height = _a.height;
var diff = Math.abs(width - height); var diff = Math.abs(width - height);
...@@ -262,6 +276,16 @@ ...@@ -262,6 +276,16 @@
Rect.prototype.floor = function () { Rect.prototype.floor = function () {
return new Rect(Math.floor(this.x), Math.floor(this.y), Math.floor(this.width), Math.floor(this.height)); return new Rect(Math.floor(this.x), Math.floor(this.y), Math.floor(this.width), Math.floor(this.height));
}; };
Rect.prototype.clipAtImageBorders = function (imgWidth, imgHeight) {
var _a = this, x = _a.x, y = _a.y, right = _a.right, bottom = _a.bottom;
var clippedX = Math.max(x, 0);
var clippedY = Math.max(y, 0);
var newWidth = right - clippedX;
var newHeight = bottom - clippedY;
var clippedWidth = Math.min(newWidth, imgWidth - clippedX);
var clippedHeight = Math.min(newHeight, imgHeight - clippedY);
return (new Rect(clippedX, clippedY, clippedWidth, clippedHeight)).floor();
};
return Rect; return Rect;
}()); }());
...@@ -1178,11 +1202,13 @@ ...@@ -1178,11 +1202,13 @@
manifestUri: "/" + defaultManifestFilename manifestUri: "/" + defaultManifestFilename
}; };
} }
var protocol = uri.startsWith('http://') ? 'http://' : uri.startsWith('https://') ? 'https://' : '';
uri = uri.replace(protocol, '');
var parts = uri.split('/').filter(function (s) { return s; }); var parts = uri.split('/').filter(function (s) { return s; });
var manifestFile = uri.endsWith('.json') var manifestFile = uri.endsWith('.json')
? parts[parts.length - 1] ? parts[parts.length - 1]
: defaultManifestFilename; : defaultManifestFilename;
var modelBaseUri = (uri.endsWith('.json') ? parts.slice(0, parts.length - 1) : parts).join('/'); var modelBaseUri = protocol + (uri.endsWith('.json') ? parts.slice(0, parts.length - 1) : parts).join('/');
modelBaseUri = uri.startsWith('/') ? "/" + modelBaseUri : modelBaseUri; modelBaseUri = uri.startsWith('/') ? "/" + modelBaseUri : modelBaseUri;
return { return {
modelBaseUri: modelBaseUri, modelBaseUri: modelBaseUri,
...@@ -1514,7 +1540,8 @@ ...@@ -1514,7 +1540,8 @@
ctx = getContext2dOrThrow(canvas); ctx = getContext2dOrThrow(canvas);
boxes = detections.map(function (det) { return det instanceof FaceDetection boxes = detections.map(function (det) { return det instanceof FaceDetection
? det.forSize(canvas.width, canvas.height).getBox().floor() ? det.forSize(canvas.width, canvas.height).getBox().floor()
: det; }); : det; })
.map(function (box) { return box.clipAtImageBorders(canvas.width, canvas.height); });
return [2 /*return*/, boxes.map(function (_a) { return [2 /*return*/, boxes.map(function (_a) {
var x = _a.x, y = _a.y, width = _a.width, height = _a.height; var x = _a.x, y = _a.y, width = _a.width, height = _a.height;
var faceImg = createCanvas({ width: width, height: height }); var faceImg = createCanvas({ width: width, height: height });
...@@ -1555,8 +1582,9 @@ ...@@ -1555,8 +1582,9 @@
var imgTensor = netInput.inputs[0].expandDims().toFloat(); var imgTensor = netInput.inputs[0].expandDims().toFloat();
var _a = imgTensor.shape.slice(1), imgHeight = _a[0], imgWidth = _a[1], numChannels = _a[2]; 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 var boxes = detections.map(function (det) { return det instanceof FaceDetection
? det.forSize(imgWidth, imgHeight).getBox().floor() ? det.forSize(imgWidth, imgHeight).getBox()
: det; }); : det; })
.map(function (box) { return box.clipAtImageBorders(imgWidth, imgHeight); });
var faceTensors = boxes.map(function (_a) { var faceTensors = boxes.map(function (_a) {
var x = _a.x, y = _a.y, width = _a.width, height = _a.height; var x = _a.x, y = _a.y, width = _a.width, height = _a.height;
return slice(imgTensor, [0, y, x, 0], [1, height, width, numChannels]); return slice(imgTensor, [0, y, x, 0], [1, height, width, numChannels]);
......
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.
{ {
"name": "face-api.js", "name": "face-api.js",
"version": "0.10.0", "version": "0.10.1",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
......
{ {
"name": "face-api.js", "name": "face-api.js",
"version": "0.10.0", "version": "0.10.1",
"description": "JavaScript API for face detection and face recognition in the browser with tensorflow.js", "description": "JavaScript API for face detection and face recognition in the browser with tensorflow.js",
"main": "./build/index.js", "main": "./build/index.js",
"typings": "./build/index.d.ts", "typings": "./build/index.d.ts",
......
...@@ -19,6 +19,14 @@ export class Rect implements IRect { ...@@ -19,6 +19,14 @@ export class Rect implements IRect {
this.height = height this.height = height
} }
public get right() {
return this.x + this.width
}
public get bottom() {
return this.y + this.height
}
public toSquare(): Rect { public toSquare(): Rect {
let { x, y, width, height } = this let { x, y, width, height } = this
const diff = Math.abs(width - height) const diff = Math.abs(width - height)
...@@ -50,4 +58,17 @@ export class Rect implements IRect { ...@@ -50,4 +58,17 @@ export class Rect implements IRect {
public toBoundingBox(): BoundingBox { public toBoundingBox(): BoundingBox {
return new BoundingBox(this.x, this.y, this.x + this.width, this.y + this.height) return new BoundingBox(this.x, this.y, this.x + this.width, this.y + this.height)
} }
public clipAtImageBorders(imgWidth: number, imgHeight: number): Rect {
const { x, y, right, bottom } = this
const clippedX = Math.max(x, 0)
const clippedY = Math.max(y, 0)
const newWidth = right - clippedX
const newHeight = bottom - clippedY
const clippedWidth = Math.min(newWidth, imgWidth - clippedX)
const clippedHeight = Math.min(newHeight, imgHeight - clippedY)
return (new Rect(clippedX, clippedY, clippedWidth, clippedHeight)).floor()
}
} }
\ No newline at end of file
...@@ -16,6 +16,8 @@ export function getModelUris(uri: string | undefined, defaultModelName: string) ...@@ -16,6 +16,8 @@ export function getModelUris(uri: string | undefined, defaultModelName: string)
manifestUri: `/${defaultManifestFilename}` manifestUri: `/${defaultManifestFilename}`
} }
} }
const protocol = uri.startsWith('http://') ? 'http://' : uri.startsWith('https://') ? 'https://' : '';
uri = uri.replace(protocol, '');
const parts = uri.split('/').filter(s => s) const parts = uri.split('/').filter(s => s)
...@@ -23,7 +25,7 @@ export function getModelUris(uri: string | undefined, defaultModelName: string) ...@@ -23,7 +25,7 @@ export function getModelUris(uri: string | undefined, defaultModelName: string)
? parts[parts.length - 1] ? parts[parts.length - 1]
: defaultManifestFilename : defaultManifestFilename
let modelBaseUri = (uri.endsWith('.json') ? parts.slice(0, parts.length - 1) : parts).join('/') let modelBaseUri = protocol + (uri.endsWith('.json') ? parts.slice(0, parts.length - 1) : parts).join('/')
modelBaseUri = uri.startsWith('/') ? `/${modelBaseUri}` : modelBaseUri modelBaseUri = uri.startsWith('/') ? `/${modelBaseUri}` : modelBaseUri
return { return {
......
...@@ -36,9 +36,11 @@ export async function extractFaceTensors( ...@@ -36,9 +36,11 @@ export async function extractFaceTensors(
const boxes = detections.map( const boxes = detections.map(
det => det instanceof FaceDetection det => det instanceof FaceDetection
? det.forSize(imgWidth, imgHeight).getBox().floor() ? det.forSize(imgWidth, imgHeight).getBox()
: det : det
) )
.map(box => box.clipAtImageBorders(imgWidth, imgHeight))
const faceTensors = boxes.map(({ x, y, width, height }) => const faceTensors = boxes.map(({ x, y, width, height }) =>
tf.slice(imgTensor, [0, y, x, 0], [1, height, width, numChannels]) tf.slice(imgTensor, [0, y, x, 0], [1, height, width, numChannels])
) )
......
...@@ -42,6 +42,8 @@ export async function extractFaces( ...@@ -42,6 +42,8 @@ export async function extractFaces(
? det.forSize(canvas.width, canvas.height).getBox().floor() ? det.forSize(canvas.width, canvas.height).getBox().floor()
: det : det
) )
.map(box => box.clipAtImageBorders(canvas.width, canvas.height))
return boxes.map(({ x, y, width, height }) => { return boxes.map(({ x, y, width, height }) => {
const faceImg = createCanvas({ width, height }) const faceImg = createCanvas({ width, height })
getContext2dOrThrow(faceImg) getContext2dOrThrow(faceImg)
......
...@@ -59,6 +59,14 @@ describe('loadWeightMap', () => { ...@@ -59,6 +59,14 @@ describe('loadWeightMap', () => {
expect(result.modelBaseUri).toEqual('/path/to/modelfiles') expect(result.modelBaseUri).toEqual('/path/to/modelfiles')
}) })
it('returns correct uris, given external path', () => {
const uri = 'https://example.com/path/to/modelfiles';
const result = getModelUris(uri, FAKE_DEFAULT_MODEL_NAME)
expect(result.manifestUri).toEqual(`${uri}/${FAKE_DEFAULT_MODEL_NAME}-weights_manifest.json`)
expect(result.modelBaseUri).toEqual(uri)
})
}) })
}) })
import { extractFaceTensors, Rect } from '../../src';
import { bufferToImage } from '../../src/utils';
describe('extractFaceTensors', () => {
let imgEl: HTMLImageElement
beforeAll(async () => {
const img = await (await fetch('base/test/images/face1.png')).blob()
imgEl = await bufferToImage(img)
})
describe('extracts tensors', () => {
it('single box', async () => {
const rect = new Rect(0, 0, 50, 60)
const tensors = await extractFaceTensors(imgEl, [rect])
expect(tensors.length).toEqual(1)
expect(tensors[0].shape).toEqual([1, 60, 50, 3])
tensors[0].dispose()
})
it('multiple boxes', async () => {
const rects = [
new Rect(0, 0, 50, 60),
new Rect(50, 50, 70, 80),
]
const tensors = await extractFaceTensors(imgEl, rects)
expect(tensors.length).toEqual(2)
expect(tensors[0].shape).toEqual([1, 60, 50, 3])
expect(tensors[1].shape).toEqual([1, 80, 70, 3])
tensors[0].dispose()
tensors[1].dispose()
})
})
describe('box out of image borders', () => {
it('clips upper left corner', async () => {
const rect = new Rect(-10, -10, 110, 110)
const tensors = await extractFaceTensors(imgEl, [rect])
expect(tensors[0].shape).toEqual([1, 100, 100, 3])
tensors[0].dispose()
})
it('clips bottom right corner', async () => {
const rect = new Rect(imgEl.width - 100, imgEl.height - 100, 110, 110)
const tensors = await extractFaceTensors(imgEl, [rect])
expect(tensors[0].shape).toEqual([1, 100, 100, 3])
tensors[0].dispose()
})
it('clips upper left and bottom right corners', async () => {
const rect = new Rect(-10, -10, imgEl.width + 20, imgEl.height + 20)
const tensors = await extractFaceTensors(imgEl, [rect])
expect(tensors[0].shape).toEqual([1, imgEl.height, imgEl.width, 3])
tensors[0].dispose()
})
})
})
import { extractFaces, Rect } from '../../src';
import { bufferToImage, createCanvasFromMedia } from '../../src/utils';
describe('extractFaces', () => {
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('extracts canvases', () => {
it('HTMLImageElement, single box', async () => {
const rect = new Rect(0, 0, 50, 60)
const canvases = await extractFaces(imgEl, [rect])
expect(canvases.length).toEqual(1)
expect(canvases[0] instanceof HTMLCanvasElement).toBe(true)
expect(canvases[0].width).toEqual(50)
expect(canvases[0].height).toEqual(60)
})
it('HTMLImageElement, multiple boxes', async () => {
const rects = [
new Rect(0, 0, 50, 60),
new Rect(50, 50, 70, 80),
]
const canvases = await extractFaces(imgEl, rects)
expect(canvases.length).toEqual(2)
expect(canvases[0] instanceof HTMLCanvasElement).toBe(true)
expect(canvases[0].width).toEqual(50)
expect(canvases[0].height).toEqual(60)
expect(canvases[1] instanceof HTMLCanvasElement).toBe(true)
expect(canvases[1].width).toEqual(70)
expect(canvases[1].height).toEqual(80)
})
it('HTMLCanvasElement, single box', async () => {
const rect = new Rect(0, 0, 50, 60)
const canvases = await extractFaces(canvasEl, [rect])
expect(canvases.length).toEqual(1)
expect(canvases[0] instanceof HTMLCanvasElement).toBe(true)
expect(canvases[0].width).toEqual(50)
expect(canvases[0].height).toEqual(60)
})
it('HTMLCanvasElement, multiple boxes', async () => {
const rects = [
new Rect(0, 0, 50, 60),
new Rect(50, 50, 70, 80),
]
const canvases = await extractFaces(canvasEl, rects)
expect(canvases.length).toEqual(2)
expect(canvases[0] instanceof HTMLCanvasElement).toBe(true)
expect(canvases[0].width).toEqual(50)
expect(canvases[0].height).toEqual(60)
expect(canvases[1] instanceof HTMLCanvasElement).toBe(true)
expect(canvases[1].width).toEqual(70)
expect(canvases[1].height).toEqual(80)
})
})
describe('box out of image borders', () => {
it('clips upper left corner', async () => {
const rect = new Rect(-10, -10, 110, 110)
const canvases = await extractFaces(imgEl, [rect])
expect(canvases[0].width).toEqual(100)
expect(canvases[0].height).toEqual(100)
})
it('clips bottom right corner', async () => {
const rect = new Rect(imgEl.width - 100, imgEl.height - 100, 110, 110)
const canvases = await extractFaces(imgEl, [rect])
expect(canvases[0].width).toEqual(100)
expect(canvases[0].height).toEqual(100)
})
it('clips upper left and bottom right corners', async () => {
const rect = new Rect(-10, -10, imgEl.width + 20, imgEl.height + 20)
const canvases = await extractFaces(imgEl, [rect])
expect(canvases[0].width).toEqual(imgEl.width)
expect(canvases[0].height).toEqual(imgEl.height)
})
})
})
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