You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
863 lines
38 KiB
JavaScript
863 lines
38 KiB
JavaScript
/**
|
|
* tracking - A modern approach for Computer Vision on the web.
|
|
* @author Eduardo Lundgren <edu@rdo.io>
|
|
* @version v1.1.3
|
|
* @link http://trackingjs.com
|
|
* @license BSD
|
|
*/
|
|
! function(t, r) {
|
|
t.tracking = t.tracking || {}, tracking.inherits = function(t, r) {
|
|
function n() {}
|
|
n.prototype = r.prototype, t.superClass_ = r.prototype, t.prototype = new n, t.prototype.constructor = t, t.base =
|
|
function(t, n) {
|
|
var e = Array.prototype.slice.call(arguments, 2);
|
|
return r.prototype[n].apply(t, e)
|
|
}
|
|
}, tracking.initUserMedia_ = function(r, n) {
|
|
t.navigator.mediaDevices.getUserMedia({
|
|
video: !0,
|
|
audio: !(!n || !n.audio)
|
|
}).then(function(t) {
|
|
r.srcObject = t
|
|
})["catch"](function(t) {
|
|
alert("无法捕获用户照相机,请打开摄像头!");
|
|
return;
|
|
throw Error("Cannot capture user camera.");
|
|
})
|
|
}, tracking.isNode = function(t) {
|
|
return t.nodeType || this.isWindow(t)
|
|
}, tracking.isWindow = function(t) {
|
|
return !!(t && t.alert && t.document)
|
|
}, tracking.one = function(t, r) {
|
|
return this.isNode(t) ? t : (r || document).querySelector(t)
|
|
}, tracking.track = function(t, r, n) {
|
|
if (t = tracking.one(t), !t) throw new Error("Element not found, try a different element or selector.");
|
|
if (!r) throw new Error("Tracker not specified, try `tracking.track(element, new tracking.FaceTracker())`.");
|
|
switch (t.nodeName.toLowerCase()) {
|
|
case "canvas":
|
|
return this.trackCanvas_(t, r, n);
|
|
case "img":
|
|
return this.trackImg_(t, r, n);
|
|
case "video":
|
|
return n && n.camera && this.initUserMedia_(t, n), this.trackVideo_(t, r, n);
|
|
default:
|
|
throw new Error("Element not supported, try in a canvas, img, or video.")
|
|
}
|
|
}, tracking.trackCanvas_ = function(t, r) {
|
|
var n = this,
|
|
e = new tracking.TrackerTask(r);
|
|
return e.on("run", function() {
|
|
n.trackCanvasInternal_(t, r)
|
|
}), e.run()
|
|
}, tracking.trackCanvasInternal_ = function(t, r) {
|
|
var n = t.width,
|
|
e = t.height,
|
|
a = t.getContext("2d"),
|
|
i = a.getImageData(0, 0, n, e);
|
|
r.track(i.data, n, e)
|
|
}, tracking.trackImg_ = function(t, r) {
|
|
var n = t.width,
|
|
e = t.height,
|
|
a = document.createElement("canvas");
|
|
a.width = n, a.height = e;
|
|
var i = new tracking.TrackerTask(r);
|
|
return i.on("run", function() {
|
|
tracking.Canvas.loadImage(a, t.src, 0, 0, n, e, function() {
|
|
tracking.trackCanvasInternal_(a, r)
|
|
})
|
|
}), i.run()
|
|
}, tracking.trackVideo_ = function(r, n) {
|
|
var e, a, i = document.createElement("canvas"),
|
|
o = i.getContext("2d"),
|
|
c = function() {
|
|
e = r.offsetWidth, a = r.offsetHeight, i.width = e, i.height = a
|
|
};
|
|
c(), r.addEventListener("resize", c);
|
|
var s, g = function() {
|
|
s = t.requestAnimationFrame(function() {
|
|
if (r.readyState === r.HAVE_ENOUGH_DATA) {
|
|
try {
|
|
o.drawImage(r, 0, 0, e, a)
|
|
} catch (t) {}
|
|
tracking.trackCanvasInternal_(i, n)
|
|
}
|
|
g()
|
|
})
|
|
},
|
|
h = new tracking.TrackerTask(n);
|
|
return h.on("stop", function() {
|
|
t.cancelAnimationFrame(s)
|
|
}), h.on("run", function() {
|
|
g()
|
|
}), h.run()
|
|
}, t.URL || (t.URL = t.URL || t.webkitURL || t.msURL || t.oURL), navigator.getUserMedia || (navigator.getUserMedia =
|
|
navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia)
|
|
}(window),
|
|
function() {
|
|
tracking.EventEmitter = function() {}, tracking.EventEmitter.prototype.events_ = null, tracking.EventEmitter.prototype
|
|
.addListener = function(t, r) {
|
|
if ("function" != typeof r) throw new TypeError("Listener must be a function");
|
|
return this.events_ || (this.events_ = {}), this.emit("newListener", t, r), this.events_[t] || (this.events_[
|
|
t] = []), this.events_[t].push(r), this
|
|
}, tracking.EventEmitter.prototype.listeners = function(t) {
|
|
return this.events_ && this.events_[t]
|
|
}, tracking.EventEmitter.prototype.emit = function(t) {
|
|
var r = this.listeners(t);
|
|
if (r) {
|
|
for (var n = Array.prototype.slice.call(arguments, 1), e = 0; e < r.length; e++) r[e] && r[e].apply(this, n);
|
|
return !0
|
|
}
|
|
return !1
|
|
}, tracking.EventEmitter.prototype.on = tracking.EventEmitter.prototype.addListener, tracking.EventEmitter.prototype
|
|
.once = function(t, r) {
|
|
var n = this;
|
|
n.on(t, function e() {
|
|
n.removeListener(t, e), r.apply(this, arguments)
|
|
})
|
|
}, tracking.EventEmitter.prototype.removeAllListeners = function(t) {
|
|
return this.events_ ? (t ? delete this.events_[t] : delete this.events_, this) : this
|
|
}, tracking.EventEmitter.prototype.removeListener = function(t, r) {
|
|
if ("function" != typeof r) throw new TypeError("Listener must be a function");
|
|
if (!this.events_) return this;
|
|
var n = this.listeners(t);
|
|
if (Array.isArray(n)) {
|
|
var e = n.indexOf(r);
|
|
if (e < 0) return this;
|
|
n.splice(e, 1)
|
|
}
|
|
return this
|
|
}, tracking.EventEmitter.prototype.setMaxListeners = function() {
|
|
throw new Error("Not implemented")
|
|
}
|
|
}(),
|
|
function() {
|
|
tracking.Canvas = {}, tracking.Canvas.loadImage = function(t, r, n, e, a, i, o) {
|
|
var c = this,
|
|
s = new window.Image;
|
|
s.crossOrigin = "*", s.onload = function() {
|
|
var r = t.getContext("2d");
|
|
t.width = a, t.height = i, r.drawImage(s, n, e, a, i), o && o.call(c), s = null
|
|
}, s.src = r
|
|
}
|
|
}(),
|
|
function() {
|
|
tracking.DisjointSet = function(t) {
|
|
if (void 0 === t) throw new Error("DisjointSet length not specified.");
|
|
this.length = t, this.parent = new Uint32Array(t);
|
|
for (var r = 0; r < t; r++) this.parent[r] = r
|
|
}, tracking.DisjointSet.prototype.length = null, tracking.DisjointSet.prototype.parent = null, tracking.DisjointSet
|
|
.prototype.find = function(t) {
|
|
return this.parent[t] === t ? t : this.parent[t] = this.find(this.parent[t])
|
|
}, tracking.DisjointSet.prototype.union = function(t, r) {
|
|
var n = this.find(t),
|
|
e = this.find(r);
|
|
this.parent[n] = e
|
|
}
|
|
}(),
|
|
function() {
|
|
tracking.Image = {}, tracking.Image.blur = function(t, r, n, e) {
|
|
if (e = Math.abs(e), e <= 1) throw new Error("Diameter should be greater than 1.");
|
|
for (var a = e / 2, i = Math.ceil(e) + (1 - Math.ceil(e) % 2), o = new Float32Array(i), c = (a + .5) / 3, s = c *
|
|
c, g = 1 / Math.sqrt(2 * Math.PI * s), h = -1 / (2 * c * c), k = 0, f = Math.floor(i / 2), u = 0; u <
|
|
i; u++) {
|
|
var l = u - f,
|
|
m = g * Math.exp(l * l * h);
|
|
o[u] = m, k += m
|
|
}
|
|
for (var d = 0; d < o.length; d++) o[d] /= k;
|
|
return this.separableConvolve(t, r, n, o, o, !1)
|
|
}, tracking.Image.computeIntegralImage = function(t, r, n, e, a, i, o) {
|
|
if (arguments.length < 4) throw new Error(
|
|
"You should specify at least one output array in the order: sum, square, tilted, sobel.");
|
|
var c;
|
|
o && (c = tracking.Image.sobel(t, r, n));
|
|
for (var s = 0; s < n; s++)
|
|
for (var g = 0; g < r; g++) {
|
|
var h = s * r * 4 + 4 * g,
|
|
k = ~~(.299 * t[h] + .587 * t[h + 1] + .114 * t[h + 2]);
|
|
if (e && this.computePixelValueSAT_(e, r, s, g, k), a && this.computePixelValueSAT_(a, r, s, g, k * k), i) {
|
|
var f = h - 4 * r,
|
|
u = ~~(.299 * t[f] + .587 * t[f + 1] + .114 * t[f + 2]);
|
|
this.computePixelValueRSAT_(i, r, s, g, k, u || 0)
|
|
}
|
|
o && this.computePixelValueSAT_(o, r, s, g, c[h])
|
|
}
|
|
}, tracking.Image.computePixelValueRSAT_ = function(t, r, n, e, a, i) {
|
|
var o = n * r + e;
|
|
t[o] = (t[o - r - 1] || 0) + (t[o - r + 1] || 0) - (t[o - r - r] || 0) + a + i
|
|
}, tracking.Image.computePixelValueSAT_ = function(t, r, n, e, a) {
|
|
var i = n * r + e;
|
|
t[i] = (t[i - r] || 0) + (t[i - 1] || 0) + a - (t[i - r - 1] || 0)
|
|
}, tracking.Image.grayscale = function(t, r, n, e) {
|
|
for (var a = new Uint8ClampedArray(e ? t.length : t.length >> 2), i = 0, o = 0, c = 0; c < n; c++)
|
|
for (var s = 0; s < r; s++) {
|
|
var g = .299 * t[o] + .587 * t[o + 1] + .114 * t[o + 2];
|
|
a[i++] = g, e && (a[i++] = g, a[i++] = g, a[i++] = t[o + 3]), o += 4
|
|
}
|
|
return a
|
|
}, tracking.Image.horizontalConvolve = function(t, r, n, e, a) {
|
|
for (var i = e.length, o = Math.floor(i / 2), c = new Float32Array(r * n * 4), s = a ? 1 : 0, g = 0; g < n; g++)
|
|
for (var h = 0; h < r; h++) {
|
|
for (var k = g, f = h, u = 4 * (g * r + h), l = 0, m = 0, d = 0, v = 0, p = 0; p < i; p++) {
|
|
var y = k,
|
|
w = Math.min(r - 1, Math.max(0, f + p - o)),
|
|
T = 4 * (y * r + w),
|
|
x = e[p];
|
|
l += t[T] * x, m += t[T + 1] * x, d += t[T + 2] * x, v += t[T + 3] * x
|
|
}
|
|
c[u] = l, c[u + 1] = m, c[u + 2] = d, c[u + 3] = v + s * (255 - v)
|
|
}
|
|
return c
|
|
}, tracking.Image.verticalConvolve = function(t, r, n, e, a) {
|
|
for (var i = e.length, o = Math.floor(i / 2), c = new Float32Array(r * n * 4), s = a ? 1 : 0, g = 0; g < n; g++)
|
|
for (var h = 0; h < r; h++) {
|
|
for (var k = g, f = h, u = 4 * (g * r + h), l = 0, m = 0, d = 0, v = 0, p = 0; p < i; p++) {
|
|
var y = Math.min(n - 1, Math.max(0, k + p - o)),
|
|
w = f,
|
|
T = 4 * (y * r + w),
|
|
x = e[p];
|
|
l += t[T] * x, m += t[T + 1] * x, d += t[T + 2] * x, v += t[T + 3] * x
|
|
}
|
|
c[u] = l, c[u + 1] = m, c[u + 2] = d, c[u + 3] = v + s * (255 - v)
|
|
}
|
|
return c
|
|
}, tracking.Image.separableConvolve = function(t, r, n, e, a, i) {
|
|
var o = this.verticalConvolve(t, r, n, a, i);
|
|
return this.horizontalConvolve(o, r, n, e, i)
|
|
}, tracking.Image.sobel = function(t, r, n) {
|
|
t = this.grayscale(t, r, n, !0);
|
|
for (var e = new Float32Array(r * n * 4), a = new Float32Array([-1, 0, 1]), i = new Float32Array([1, 2, 1]), o =
|
|
this.separableConvolve(t, r, n, a, i), c = this.separableConvolve(t, r, n, i, a), s = 0; s < e.length; s +=
|
|
4) {
|
|
var g = o[s],
|
|
h = c[s],
|
|
k = Math.sqrt(h * h + g * g);
|
|
e[s] = k, e[s + 1] = k, e[s + 2] = k, e[s + 3] = 255
|
|
}
|
|
return e
|
|
}, tracking.Image.equalizeHist = function(t, r, n) {
|
|
for (var e = new Uint8ClampedArray(t.length), a = new Array(256), i = 0; i < 256; i++) a[i] = 0;
|
|
for (var i = 0; i < t.length; i++) e[i] = t[i], a[t[i]]++;
|
|
for (var o = a[0], i = 0; i < 256; i++) a[i] += o, o = a[i];
|
|
for (var c = 255 / t.length, i = 0; i < t.length; i++) e[i] = a[t[i]] * c + .5 | 0;
|
|
return e
|
|
}
|
|
}(),
|
|
function() {
|
|
tracking.ViolaJones = {}, tracking.ViolaJones.REGIONS_OVERLAP = .5, tracking.ViolaJones.classifiers = {}, tracking
|
|
.ViolaJones.detect = function(t, r, n, e, a, i, o, c) {
|
|
var s, g = 0,
|
|
h = [],
|
|
k = new Int32Array(r * n),
|
|
f = new Int32Array(r * n),
|
|
u = new Int32Array(r * n);
|
|
o > 0 && (s = new Int32Array(r * n)), tracking.Image.computeIntegralImage(t, r, n, k, f, u, s);
|
|
for (var l = c[0], m = c[1], d = e * a, v = d * l | 0, p = d * m | 0; v < r && p < n;) {
|
|
for (var y = d * i + .5 | 0, w = 0; w < n - p; w += y)
|
|
for (var T = 0; T < r - v; T += y) o > 0 && this.isTriviallyExcluded(o, s, w, T, r, v, p) || this.evalStages_(
|
|
c, k, f, u, w, T, r, v, p, d) && (h[g++] = {
|
|
width: v,
|
|
height: p,
|
|
x: T,
|
|
y: w
|
|
});
|
|
d *= a, v = d * l | 0, p = d * m | 0
|
|
}
|
|
return this.mergeRectangles_(h)
|
|
}, tracking.ViolaJones.isTriviallyExcluded = function(t, r, n, e, a, i, o) {
|
|
var c = n * a + e,
|
|
s = c + i,
|
|
g = c + o * a,
|
|
h = g + i,
|
|
k = (r[c] - r[s] - r[g] + r[h]) / (i * o * 255);
|
|
return k < t
|
|
}, tracking.ViolaJones.evalStages_ = function(t, r, n, e, a, i, o, c, s, g) {
|
|
var h = 1 / (c * s),
|
|
k = a * o + i,
|
|
f = k + c,
|
|
u = k + s * o,
|
|
l = u + c,
|
|
m = (r[k] - r[f] - r[u] + r[l]) * h,
|
|
d = (n[k] - n[f] - n[u] + n[l]) * h - m * m,
|
|
v = 1;
|
|
d > 0 && (v = Math.sqrt(d));
|
|
for (var p = t.length, y = 2; y < p;) {
|
|
for (var w = 0, T = t[y++], x = t[y++]; x--;) {
|
|
for (var M = 0, _ = t[y++], C = t[y++], E = 0; E < C; E++) {
|
|
var F, B, L, S, A = i + t[y++] * g + .5 | 0,
|
|
I = a + t[y++] * g + .5 | 0,
|
|
R = t[y++] * g + .5 | 0,
|
|
b = t[y++] * g + .5 | 0,
|
|
D = t[y++];
|
|
_ ? (F = A - b + R + (I + R + b - 1) * o, B = A + (I - 1) * o, L = A - b + (I + b - 1) * o, S = A + R + (I +
|
|
R - 1) * o, M += (e[F] + e[B] - e[L] - e[S]) * D) : (F = I * o + A, B = F + R, L = F + b * o, S = L + R,
|
|
M += (r[F] - r[B] - r[L] + r[S]) * D)
|
|
}
|
|
var O = t[y++],
|
|
N = t[y++],
|
|
j = t[y++];
|
|
w += M * h < O * v ? N : j
|
|
}
|
|
if (w < T) return !1
|
|
}
|
|
return !0
|
|
}, tracking.ViolaJones.mergeRectangles_ = function(t) {
|
|
for (var r = new tracking.DisjointSet(t.length), n = 0; n < t.length; n++)
|
|
for (var e = t[n], a = 0; a < t.length; a++) {
|
|
var i = t[a];
|
|
if (tracking.Math.intersectRect(e.x, e.y, e.x + e.width, e.y + e.height, i.x, i.y, i.x + i.width, i.y + i
|
|
.height)) {
|
|
var o = Math.max(e.x, i.x),
|
|
c = Math.max(e.y, i.y),
|
|
s = Math.min(e.x + e.width, i.x + i.width),
|
|
g = Math.min(e.y + e.height, i.y + i.height),
|
|
h = (o - s) * (c - g),
|
|
k = e.width * e.height,
|
|
f = i.width * i.height;
|
|
h / (k * (k / f)) >= this.REGIONS_OVERLAP && h / (f * (k / f)) >= this.REGIONS_OVERLAP && r.union(n, a)
|
|
}
|
|
}
|
|
for (var u = {}, l = 0; l < r.length; l++) {
|
|
var m = r.find(l);
|
|
u[m] ? (u[m].total++, u[m].width += t[l].width, u[m].height += t[l].height, u[m].x += t[l].x, u[m].y += t[l]
|
|
.y) : u[m] = {
|
|
total: 1,
|
|
width: t[l].width,
|
|
height: t[l].height,
|
|
x: t[l].x,
|
|
y: t[l].y
|
|
}
|
|
}
|
|
var d = [];
|
|
return Object.keys(u).forEach(function(t) {
|
|
var r = u[t];
|
|
d.push({
|
|
total: r.total,
|
|
width: r.width / r.total + .5 | 0,
|
|
height: r.height / r.total + .5 | 0,
|
|
x: r.x / r.total + .5 | 0,
|
|
y: r.y / r.total + .5 | 0
|
|
})
|
|
}), d
|
|
}
|
|
}(),
|
|
function() {
|
|
tracking.Brief = {}, tracking.Brief.N = 512, tracking.Brief.randomImageOffsets_ = {}, tracking.Brief
|
|
.randomWindowOffsets_ = null, tracking.Brief.getDescriptors = function(t, r, n) {
|
|
for (var e = new Int32Array((n.length >> 1) * (this.N >> 5)), a = 0, i = this.getRandomOffsets_(r), o = 0, c =
|
|
0; c < n.length; c += 2)
|
|
for (var s = r * n[c + 1] + n[c], g = 0, h = 0, k = this.N; h < k; h++) t[i[g++] + s] < t[i[g++] + s] && (a |=
|
|
1 << (31 & h)), h + 1 & 31 || (e[o++] = a, a = 0);
|
|
return e
|
|
}, tracking.Brief.match = function(t, r, n, e) {
|
|
for (var a = t.length >> 1, i = n.length >> 1, o = new Array(a), c = 0; c < a; c++) {
|
|
for (var s = 1 / 0, g = 0, h = 0; h < i; h++) {
|
|
for (var k = 0, f = 0, u = this.N >> 5; f < u; f++) k += tracking.Math.hammingWeight(r[c * u + f] ^ e[h * u +
|
|
f]);
|
|
k < s && (s = k, g = h)
|
|
}
|
|
o[c] = {
|
|
index1: c,
|
|
index2: g,
|
|
keypoint1: [t[2 * c], t[2 * c + 1]],
|
|
keypoint2: [n[2 * g], n[2 * g + 1]],
|
|
confidence: 1 - s / this.N
|
|
}
|
|
}
|
|
return o
|
|
}, tracking.Brief.reciprocalMatch = function(t, r, n, e) {
|
|
var a = [];
|
|
if (0 === t.length || 0 === n.length) return a;
|
|
for (var i = tracking.Brief.match(t, r, n, e), o = tracking.Brief.match(n, e, t, r), c = 0; c < i.length; c++) o[
|
|
i[c].index2].index2 === c && a.push(i[c]);
|
|
return a
|
|
}, tracking.Brief.getRandomOffsets_ = function(t) {
|
|
if (!this.randomWindowOffsets_) {
|
|
for (var r = 0, n = new Int32Array(4 * this.N), e = 0; e < this.N; e++) n[r++] = Math.round(tracking.Math
|
|
.uniformRandom(-15, 16)), n[r++] = Math.round(tracking.Math.uniformRandom(-15, 16)), n[r++] = Math.round(
|
|
tracking.Math.uniformRandom(-15, 16)), n[r++] = Math.round(tracking.Math.uniformRandom(-15, 16));
|
|
this.randomWindowOffsets_ = n
|
|
}
|
|
if (!this.randomImageOffsets_[t]) {
|
|
for (var a = 0, i = new Int32Array(2 * this.N), o = 0; o < this.N; o++) i[a++] = this.randomWindowOffsets_[4 *
|
|
o] * t + this.randomWindowOffsets_[4 * o + 1], i[a++] = this.randomWindowOffsets_[4 * o + 2] * t + this
|
|
.randomWindowOffsets_[4 * o + 3];
|
|
this.randomImageOffsets_[t] = i
|
|
}
|
|
return this.randomImageOffsets_[t]
|
|
}
|
|
}(),
|
|
function() {
|
|
tracking.Fast = {}, tracking.Fast.THRESHOLD = 40, tracking.Fast.circles_ = {}, tracking.Fast.findCorners = function(t,
|
|
r, n, e) {
|
|
var a = this.getCircleOffsets_(r),
|
|
i = new Int32Array(16),
|
|
o = [];
|
|
void 0 === e && (e = this.THRESHOLD);
|
|
for (var c = 3; c < n - 3; c++)
|
|
for (var s = 3; s < r - 3; s++) {
|
|
for (var g = c * r + s, h = t[g], k = 0; k < 16; k++) i[k] = t[g + a[k]];
|
|
this.isCorner(h, i, e) && (o.push(s, c), s += 3)
|
|
}
|
|
return o
|
|
}, tracking.Fast.isBrighter = function(t, r, n) {
|
|
return t - r > n
|
|
}, tracking.Fast.isCorner = function(t, r, n) {
|
|
if (this.isTriviallyExcluded(r, t, n)) return !1;
|
|
for (var e = 0; e < 16; e++) {
|
|
for (var a = !0, i = !0, o = 0; o < 9; o++) {
|
|
var c = r[e + o & 15];
|
|
if (!this.isBrighter(t, c, n) && (i = !1, a === !1)) break;
|
|
if (!this.isDarker(t, c, n) && (a = !1, i === !1)) break
|
|
}
|
|
if (i || a) return !0
|
|
}
|
|
return !1
|
|
}, tracking.Fast.isDarker = function(t, r, n) {
|
|
return r - t > n
|
|
}, tracking.Fast.isTriviallyExcluded = function(t, r, n) {
|
|
var e = 0,
|
|
a = t[8],
|
|
i = t[12],
|
|
o = t[4],
|
|
c = t[0];
|
|
return this.isBrighter(c, r, n) && e++, this.isBrighter(o, r, n) && e++, this.isBrighter(a, r, n) && e++, this
|
|
.isBrighter(i, r, n) && e++, e < 3 && (e = 0, this.isDarker(c, r, n) && e++, this.isDarker(o, r, n) && e++, this
|
|
.isDarker(a, r, n) && e++, this.isDarker(i, r, n) && e++, e < 3)
|
|
}, tracking.Fast.getCircleOffsets_ = function(t) {
|
|
if (this.circles_[t]) return this.circles_[t];
|
|
var r = new Int32Array(16);
|
|
return r[0] = -t - t - t, r[1] = r[0] + 1, r[2] = r[1] + t + 1, r[3] = r[2] + t + 1, r[4] = r[3] + t, r[5] = r[
|
|
4] + t, r[6] = r[5] + t - 1, r[7] = r[6] + t - 1, r[8] = r[7] - 1, r[9] = r[8] - 1, r[10] = r[9] - t - 1, r[
|
|
11] = r[10] - t - 1, r[12] = r[11] - t, r[13] = r[12] - t, r[14] = r[13] - t + 1, r[15] = r[14] - t + 1, this
|
|
.circles_[t] = r, r
|
|
}
|
|
}(),
|
|
function() {
|
|
tracking.Math = {}, tracking.Math.distance = function(t, r, n, e) {
|
|
var a = n - t,
|
|
i = e - r;
|
|
return Math.sqrt(a * a + i * i)
|
|
}, tracking.Math.hammingWeight = function(t) {
|
|
return t -= t >> 1 & 1431655765, t = (858993459 & t) + (t >> 2 & 858993459), 16843009 * (t + (t >> 4) &
|
|
252645135) >> 24
|
|
}, tracking.Math.uniformRandom = function(t, r) {
|
|
return t + Math.random() * (r - t)
|
|
}, tracking.Math.intersectRect = function(t, r, n, e, a, i, o, c) {
|
|
return !(a > n || o < t || i > e || c < r)
|
|
}
|
|
}(),
|
|
function() {
|
|
tracking.Matrix = {}, tracking.Matrix.forEach = function(t, r, n, e, a) {
|
|
a = a || 1;
|
|
for (var i = 0; i < n; i += a)
|
|
for (var o = 0; o < r; o += a) {
|
|
var c = i * r * 4 + 4 * o;
|
|
e.call(this, t[c], t[c + 1], t[c + 2], t[c + 3], c, i, o)
|
|
}
|
|
}, tracking.Matrix.sub = function(t, r) {
|
|
for (var n = tracking.Matrix.clone(t), e = 0; e < n.length; e++)
|
|
for (var a = 0; a < n[e].length; a++) n[e][a] -= r[e][a];
|
|
return n
|
|
}, tracking.Matrix.add = function(t, r) {
|
|
for (var n = tracking.Matrix.clone(t), e = 0; e < n.length; e++)
|
|
for (var a = 0; a < n[e].length; a++) n[e][a] += r[e][a];
|
|
return n
|
|
}, tracking.Matrix.clone = function(t, r, n) {
|
|
r = r || t[0].length, n = n || t.length;
|
|
for (var e = new Array(n), a = n; a--;) {
|
|
e[a] = new Array(r);
|
|
for (var i = r; i--;) e[a][i] = t[a][i]
|
|
}
|
|
return e
|
|
}, tracking.Matrix.mulScalar = function(t, r) {
|
|
for (var n = tracking.Matrix.clone(r), e = 0; e < r.length; e++)
|
|
for (var a = 0; a < r[e].length; a++) n[e][a] *= t;
|
|
return n
|
|
}, tracking.Matrix.transpose = function(t) {
|
|
for (var r = new Array(t[0].length), n = 0; n < t[0].length; n++) {
|
|
r[n] = new Array(t.length);
|
|
for (var e = 0; e < t.length; e++) r[n][e] = t[e][n]
|
|
}
|
|
return r
|
|
}, tracking.Matrix.mul = function(t, r) {
|
|
for (var n = new Array(t.length), e = 0; e < t.length; e++) {
|
|
n[e] = new Array(r[0].length);
|
|
for (var a = 0; a < r[0].length; a++) {
|
|
n[e][a] = 0;
|
|
for (var i = 0; i < t[0].length; i++) n[e][a] += t[e][i] * r[i][a]
|
|
}
|
|
}
|
|
return n
|
|
}, tracking.Matrix.norm = function(t) {
|
|
for (var r = 0, n = 0; n < t.length; n++)
|
|
for (var e = 0; e < t[n].length; e++) r += t[n][e] * t[n][e];
|
|
return Math.sqrt(r)
|
|
}, tracking.Matrix.calcCovarMatrix = function(t) {
|
|
for (var r = new Array(t.length), n = 0; n < t.length; n++) {
|
|
r[n] = [0];
|
|
for (var e = 0; e < t[n].length; e++) r[n][0] += t[n][e] / t[n].length
|
|
}
|
|
for (var a = tracking.Matrix.clone(r), n = 0; n < a.length; n++)
|
|
for (var e = 0; e < t[0].length - 1; e++) a[n].push(a[n][0]);
|
|
var i = tracking.Matrix.sub(t, a),
|
|
o = tracking.Matrix.transpose(i),
|
|
c = tracking.Matrix.mul(o, i);
|
|
return [c, r]
|
|
}
|
|
}(),
|
|
function() {
|
|
tracking.EPnP = {}, tracking.EPnP.solve = function(t, r, n) {}
|
|
}(),
|
|
function() {
|
|
tracking.Tracker = function() {
|
|
tracking.Tracker.base(this, "constructor")
|
|
}, tracking.inherits(tracking.Tracker, tracking.EventEmitter), tracking.Tracker.prototype.track = function() {}
|
|
}(),
|
|
function() {
|
|
tracking.TrackerTask = function(t) {
|
|
if (tracking.TrackerTask.base(this, "constructor"), !t) throw new Error("Tracker instance not specified.");
|
|
this.setTracker(t)
|
|
}, tracking.inherits(tracking.TrackerTask, tracking.EventEmitter), tracking.TrackerTask.prototype.tracker_ = null,
|
|
tracking.TrackerTask.prototype.running_ = !1, tracking.TrackerTask.prototype.getTracker = function() {
|
|
return this.tracker_
|
|
}, tracking.TrackerTask.prototype.inRunning = function() {
|
|
return this.running_
|
|
}, tracking.TrackerTask.prototype.setRunning = function(t) {
|
|
this.running_ = t
|
|
}, tracking.TrackerTask.prototype.setTracker = function(t) {
|
|
this.tracker_ = t
|
|
}, tracking.TrackerTask.prototype.run = function() {
|
|
var t = this;
|
|
if (!this.inRunning()) return this.setRunning(!0), this.reemitTrackEvent_ = function(r) {
|
|
t.emit("track", r)
|
|
}, this.tracker_.on("track", this.reemitTrackEvent_), this.emit("run"), this
|
|
}, tracking.TrackerTask.prototype.stop = function() {
|
|
if (this.inRunning()) return this.setRunning(!1), this.emit("stop"), this.tracker_.removeListener("track", this
|
|
.reemitTrackEvent_), this
|
|
}
|
|
}(),
|
|
function() {
|
|
tracking.ColorTracker = function(t) {
|
|
tracking.ColorTracker.base(this, "constructor"), "string" == typeof t && (t = [t]), t && (t.forEach(function(t) {
|
|
if (!tracking.ColorTracker.getColor(t)) throw new Error(
|
|
'Color not valid, try `new tracking.ColorTracker("magenta")`.')
|
|
}), this.setColors(t))
|
|
}, tracking.inherits(tracking.ColorTracker, tracking.Tracker), tracking.ColorTracker.knownColors_ = {}, tracking
|
|
.ColorTracker.neighbours_ = {}, tracking.ColorTracker.registerColor = function(t, r) {
|
|
tracking.ColorTracker.knownColors_[t] = r
|
|
}, tracking.ColorTracker.getColor = function(t) {
|
|
return tracking.ColorTracker.knownColors_[t]
|
|
}, tracking.ColorTracker.prototype.colors = ["magenta"], tracking.ColorTracker.prototype.minDimension = 20, tracking
|
|
.ColorTracker.prototype.maxDimension = 1 / 0, tracking.ColorTracker.prototype.minGroupSize = 30, tracking
|
|
.ColorTracker.prototype.calculateDimensions_ = function(t, r) {
|
|
for (var n = -1, e = -1, a = 1 / 0, i = 1 / 0, o = 0; o < r; o += 2) {
|
|
var c = t[o],
|
|
s = t[o + 1];
|
|
c < a && (a = c), c > n && (n = c), s < i && (i = s), s > e && (e = s)
|
|
}
|
|
return {
|
|
width: n - a,
|
|
height: e - i,
|
|
x: a,
|
|
y: i
|
|
}
|
|
}, tracking.ColorTracker.prototype.getColors = function() {
|
|
return this.colors
|
|
}, tracking.ColorTracker.prototype.getMinDimension = function() {
|
|
return this.minDimension
|
|
}, tracking.ColorTracker.prototype.getMaxDimension = function() {
|
|
return this.maxDimension
|
|
}, tracking.ColorTracker.prototype.getMinGroupSize = function() {
|
|
return this.minGroupSize
|
|
}, tracking.ColorTracker.prototype.getNeighboursForWidth_ = function(t) {
|
|
if (tracking.ColorTracker.neighbours_[t]) return tracking.ColorTracker.neighbours_[t];
|
|
var r = new Int32Array(8);
|
|
return r[0] = 4 * -t, r[1] = 4 * -t + 4, r[2] = 4, r[3] = 4 * t + 4, r[4] = 4 * t, r[5] = 4 * t - 4, r[6] = -4, r[
|
|
7] = 4 * -t - 4, tracking.ColorTracker.neighbours_[t] = r, r
|
|
}, tracking.ColorTracker.prototype.mergeRectangles_ = function(t) {
|
|
for (var r, n = [], e = this.getMinDimension(), a = this.getMaxDimension(), i = 0; i < t.length; i++) {
|
|
var o = t[i];
|
|
r = !0;
|
|
for (var c = i + 1; c < t.length; c++) {
|
|
var s = t[c];
|
|
if (tracking.Math.intersectRect(o.x, o.y, o.x + o.width, o.y + o.height, s.x, s.y, s.x + s.width, s.y + s
|
|
.height)) {
|
|
r = !1;
|
|
var g = Math.min(o.x, s.x),
|
|
h = Math.min(o.y, s.y),
|
|
k = Math.max(o.x + o.width, s.x + s.width),
|
|
f = Math.max(o.y + o.height, s.y + s.height);
|
|
s.height = f - h, s.width = k - g, s.x = g, s.y = h;
|
|
break
|
|
}
|
|
}
|
|
r && o.width >= e && o.height >= e && o.width <= a && o.height <= a && n.push(o)
|
|
}
|
|
return n
|
|
}, tracking.ColorTracker.prototype.setColors = function(t) {
|
|
this.colors = t
|
|
}, tracking.ColorTracker.prototype.setMinDimension = function(t) {
|
|
this.minDimension = t
|
|
}, tracking.ColorTracker.prototype.setMaxDimension = function(t) {
|
|
this.maxDimension = t
|
|
}, tracking.ColorTracker.prototype.setMinGroupSize = function(t) {
|
|
this.minGroupSize = t
|
|
}, tracking.ColorTracker.prototype.track = function(t, r, n) {
|
|
var e = this,
|
|
a = this.getColors();
|
|
if (!a) throw new Error('Colors not specified, try `new tracking.ColorTracker("magenta")`.');
|
|
var i = [];
|
|
a.forEach(function(a) {
|
|
i = i.concat(e.trackColor_(t, r, n, a))
|
|
}), this.emit("track", {
|
|
data: i
|
|
})
|
|
}, tracking.ColorTracker.prototype.trackColor_ = function(n, e, a, i) {
|
|
var o, c, s, g, h, k = tracking.ColorTracker.knownColors_[i],
|
|
f = new Int32Array(n.length >> 2),
|
|
u = new Int8Array(n.length),
|
|
l = this.getMinGroupSize(),
|
|
m = this.getNeighboursForWidth_(e),
|
|
d = new Int32Array(n.length),
|
|
v = [],
|
|
p = -4;
|
|
if (!k) return v;
|
|
for (var y = 0; y < a; y++)
|
|
for (var w = 0; w < e; w++)
|
|
if (p += 4, !u[p]) {
|
|
for (o = 0, h = -1, d[++h] = p, d[++h] = y, d[++h] = w, u[p] = 1; h >= 0;)
|
|
if (s = d[h--], c = d[h--], g = d[h--], k(n[g], n[g + 1], n[g + 2], n[g + 3], g, c, s)) {
|
|
f[o++] = s, f[o++] = c;
|
|
for (var T = 0; T < m.length; T++) {
|
|
var x = g + m[T],
|
|
M = c + t[T],
|
|
_ = s + r[T];
|
|
!u[x] && M >= 0 && M < a && _ >= 0 && _ < e && (d[++h] = x, d[++h] = M, d[++h] = _, u[x] = 1)
|
|
}
|
|
} if (o >= l) {
|
|
var C = this.calculateDimensions_(f, o);
|
|
C && (C.color = i, v.push(C))
|
|
}
|
|
} return this.mergeRectangles_(v)
|
|
}, tracking.ColorTracker.registerColor("cyan", function(t, r, n) {
|
|
var e = 50,
|
|
a = 70,
|
|
i = t - 0,
|
|
o = r - 255,
|
|
c = n - 255;
|
|
return r - t >= e && n - t >= a || i * i + o * o + c * c < 6400
|
|
}), tracking.ColorTracker.registerColor("magenta", function(t, r, n) {
|
|
var e = 50,
|
|
a = t - 255,
|
|
i = r - 0,
|
|
o = n - 255;
|
|
return t - r >= e && n - r >= e || a * a + i * i + o * o < 19600
|
|
}), tracking.ColorTracker.registerColor("yellow", function(t, r, n) {
|
|
var e = 50,
|
|
a = t - 255,
|
|
i = r - 255,
|
|
o = n - 0;
|
|
return t - n >= e && r - n >= e || a * a + i * i + o * o < 1e4
|
|
});
|
|
var t = new Int32Array([-1, -1, 0, 1, 1, 1, 0, -1]),
|
|
r = new Int32Array([0, 1, 1, 1, 0, -1, -1, -1])
|
|
}(),
|
|
function() {
|
|
tracking.ObjectTracker = function(t) {
|
|
tracking.ObjectTracker.base(this, "constructor"), t && (Array.isArray(t) || (t = [t]), Array.isArray(t) && t
|
|
.forEach(function(r, n) {
|
|
if ("string" == typeof r && (t[n] = tracking.ViolaJones.classifiers[r]), !t[n]) throw new Error(
|
|
'Object classifier not valid, try `new tracking.ObjectTracker("face")`.')
|
|
})), this.setClassifiers(t)
|
|
}, tracking.inherits(tracking.ObjectTracker, tracking.Tracker), tracking.ObjectTracker.prototype.edgesDensity = .2,
|
|
tracking.ObjectTracker.prototype.initialScale = 1, tracking.ObjectTracker.prototype.scaleFactor = 1.25, tracking
|
|
.ObjectTracker.prototype.stepSize = 1.5, tracking.ObjectTracker.prototype.getClassifiers = function() {
|
|
return this.classifiers
|
|
}, tracking.ObjectTracker.prototype.getEdgesDensity = function() {
|
|
return this.edgesDensity
|
|
}, tracking.ObjectTracker.prototype.getInitialScale = function() {
|
|
return this.initialScale
|
|
}, tracking.ObjectTracker.prototype.getScaleFactor = function() {
|
|
return this.scaleFactor
|
|
}, tracking.ObjectTracker.prototype.getStepSize = function() {
|
|
return this.stepSize
|
|
}, tracking.ObjectTracker.prototype.track = function(t, r, n) {
|
|
var e = this,
|
|
a = this.getClassifiers();
|
|
if (!a) throw new Error('Object classifier not specified, try `new tracking.ObjectTracker("face")`.');
|
|
var i = [];
|
|
a.forEach(function(a) {
|
|
i = i.concat(tracking.ViolaJones.detect(t, r, n, e.getInitialScale(), e.getScaleFactor(), e.getStepSize(), e
|
|
.getEdgesDensity(), a))
|
|
}), this.emit("track", {
|
|
data: i
|
|
})
|
|
}, tracking.ObjectTracker.prototype.setClassifiers = function(t) {
|
|
this.classifiers = t
|
|
}, tracking.ObjectTracker.prototype.setEdgesDensity = function(t) {
|
|
this.edgesDensity = t
|
|
}, tracking.ObjectTracker.prototype.setInitialScale = function(t) {
|
|
this.initialScale = t
|
|
}, tracking.ObjectTracker.prototype.setScaleFactor = function(t) {
|
|
this.scaleFactor = t
|
|
}, tracking.ObjectTracker.prototype.setStepSize = function(t) {
|
|
this.stepSize = t
|
|
}
|
|
}(),
|
|
function() {
|
|
tracking.LandmarksTracker = function() {
|
|
tracking.LandmarksTracker.base(this, "constructor")
|
|
}, tracking.inherits(tracking.LandmarksTracker, tracking.ObjectTracker), tracking.LandmarksTracker.prototype.track =
|
|
function(t, r, n) {
|
|
var e = tracking.ViolaJones.classifiers.face,
|
|
a = tracking.ViolaJones.detect(t, r, n, this.getInitialScale(), this.getScaleFactor(), this.getStepSize(), this
|
|
.getEdgesDensity(), e),
|
|
i = tracking.LBF.align(t, r, n, a);
|
|
this.emit("track", {
|
|
data: {
|
|
faces: a,
|
|
landmarks: i
|
|
}
|
|
})
|
|
}
|
|
}(),
|
|
function() {
|
|
tracking.LBF = {}, tracking.LBF.Regressor = function(t) {
|
|
this.maxNumStages = t, this.rfs = new Array(t), this.models = new Array(t);
|
|
for (var r = 0; r < t; r++) this.rfs[r] = new tracking.LBF.RandomForest(r), this.models[r] = tracking.LBF
|
|
.RegressorData[r].models;
|
|
this.meanShape = tracking.LBF.LandmarksData
|
|
}, tracking.LBF.Regressor.prototype.predict = function(t, r, n, e) {
|
|
var a = [],
|
|
i = [],
|
|
o = [],
|
|
c = tracking.Matrix.clone(this.meanShape);
|
|
a.push({
|
|
data: t,
|
|
width: r,
|
|
height: n
|
|
}), o.push(e), i.push(tracking.LBF.projectShapeToBoundingBox_(c, e));
|
|
for (var s = 0; s < this.maxNumStages; s++) {
|
|
var g = tracking.LBF.Regressor.deriveBinaryFeat(this.rfs[s], a, i, o, c);
|
|
this.applyGlobalPrediction(g, this.models[s], i, o)
|
|
}
|
|
return i[0]
|
|
}, tracking.LBF.Regressor.prototype.applyGlobalPrediction = function(t, r, n, e) {
|
|
for (var a = 2 * n[0].length, i = new Array(a / 2), o = 0; o < a / 2; o++) i[o] = [0, 0];
|
|
for (var o = 0; o < n.length; o++) {
|
|
for (var c = 0; c < a; c++) {
|
|
for (var s = 0, g = 0, h = 0;
|
|
(h = t[o][g].index) != -1; g++) h <= r[c].nr_feature && (s += r[c].data[h - 1] * t[o][g].value);
|
|
c < a / 2 ? i[c][0] = s : i[c - a / 2][1] = s
|
|
}
|
|
var k = tracking.LBF.similarityTransform_(tracking.LBF.unprojectShapeToBoundingBox_(n[o], e[o]), this
|
|
.meanShape),
|
|
f = (tracking.Matrix.transpose(k[0]), tracking.LBF.unprojectShapeToBoundingBox_(n[o], e[o]));
|
|
f = tracking.Matrix.add(f, i), n[o] = tracking.LBF.projectShapeToBoundingBox_(f, e[o])
|
|
}
|
|
}, tracking.LBF.Regressor.deriveBinaryFeat = function(t, r, n, e, a) {
|
|
for (var i = new Array(r.length), o = 0; o < r.length; o++) {
|
|
var c = t.maxNumTrees * t.landmarkNum + 1;
|
|
i[o] = new Array(c);
|
|
for (var s = 0; s < c; s++) i[o][s] = {}
|
|
}
|
|
for (var g = 1 << t.maxDepth - 1, o = 0; o < r.length; o++) {
|
|
for (var h = tracking.LBF.unprojectShapeToBoundingBox_(n[o], e[o]), k = tracking.LBF.similarityTransform_(h, a),
|
|
s = 0; s < t.landmarkNum; s++)
|
|
for (var f = 0; f < t.maxNumTrees; f++) {
|
|
var u = tracking.LBF.Regressor.getCodeFromTree(t.rfs[s][f], r[o], n[o], e[o], k[0], k[1]),
|
|
l = s * t.maxNumTrees + f;
|
|
i[o][l].index = g * l + u, i[o][l].value = 1
|
|
}
|
|
i[o][t.landmarkNum * t.maxNumTrees].index = -1, i[o][t.landmarkNum * t.maxNumTrees].value = -1
|
|
}
|
|
return i
|
|
}, tracking.LBF.Regressor.getCodeFromTree = function(t, r, n, e, a, i) {
|
|
for (var o = 0, c = 0;;) {
|
|
var s = Math.cos(t.nodes[o].feats[0]) * t.nodes[o].feats[2] * t.maxRadioRadius * e.width,
|
|
g = Math.sin(t.nodes[o].feats[0]) * t.nodes[o].feats[2] * t.maxRadioRadius * e.height,
|
|
h = Math.cos(t.nodes[o].feats[1]) * t.nodes[o].feats[3] * t.maxRadioRadius * e.width,
|
|
k = Math.sin(t.nodes[o].feats[1]) * t.nodes[o].feats[3] * t.maxRadioRadius * e.height,
|
|
f = a[0][0] * s + a[0][1] * g,
|
|
u = a[1][0] * s + a[1][1] * g,
|
|
l = Math.floor(f + n[t.landmarkID][0]),
|
|
m = Math.floor(u + n[t.landmarkID][1]);
|
|
l = Math.max(0, Math.min(l, r.height - 1)), m = Math.max(0, Math.min(m, r.width - 1));
|
|
var d = a[0][0] * h + a[0][1] * k,
|
|
v = a[1][0] * h + a[1][1] * k,
|
|
p = Math.floor(d + n[t.landmarkID][0]),
|
|
y = Math.floor(v + n[t.landmarkID][1]);
|
|
p = Math.max(0, Math.min(p, r.height - 1)), y = Math.max(0, Math.min(y, r.width - 1));
|
|
var w = Math.floor(r.data[m * r.width + l]) - Math.floor(r.data[y * r.width + p]);
|
|
if (o = w < t.nodes[o].thresh ? t.nodes[o].cnodes[0] : t.nodes[o].cnodes[1], 1 == t.nodes[o].is_leafnode) {
|
|
c = 1;
|
|
for (var T = 0; T < t.leafnodes.length; T++) {
|
|
if (t.leafnodes[T] == o) return c;
|
|
c++
|
|
}
|
|
return c
|
|
}
|
|
}
|
|
return c
|
|
}
|
|
}(),
|
|
function() {
|
|
tracking.LBF.maxNumStages = 4, tracking.LBF.regressor_ = null, tracking.LBF.align = function(t, r, n, e) {
|
|
null == tracking.LBF.regressor_ && (tracking.LBF.regressor_ = new tracking.LBF.Regressor(tracking.LBF
|
|
.maxNumStages)), t = tracking.Image.grayscale(t, r, n, !1), t = tracking.Image.equalizeHist(t, r, n);
|
|
var a = new Array(e.length);
|
|
for (var i in e) {
|
|
e[i].height = e[i].width;
|
|
var o = {};
|
|
o.startX = e[i].x, o.startY = e[i].y, o.width = e[i].width, o.height = e[i].height, a[i] = tracking.LBF
|
|
.regressor_.predict(t, r, n, o)
|
|
}
|
|
return a
|
|
}, tracking.LBF.unprojectShapeToBoundingBox_ = function(t, r) {
|
|
for (var n = new Array(t.length), e = 0; e < t.length; e++) n[e] = [(t[e][0] - r.startX) / r.width, (t[e][1] - r
|
|
.startY) / r.height];
|
|
return n
|
|
}, tracking.LBF.projectShapeToBoundingBox_ = function(t, r) {
|
|
for (var n = new Array(t.length), e = 0; e < t.length; e++) n[e] = [t[e][0] * r.width + r.startX, t[e][1] * r
|
|
.height + r.startY
|
|
];
|
|
return n
|
|
}, tracking.LBF.similarityTransform_ = function(t, r) {
|
|
for (var n = [0, 0], e = [0, 0], a = 0; a < t.length; a++) n[0] += t[a][0], n[1] += t[a][1], e[0] += r[a][0], e[
|
|
1] += r[a][1];
|
|
n[0] /= t.length, n[1] /= t.length, e[0] /= r.length, e[1] /= r.length;
|
|
for (var i = tracking.Matrix.clone(t), o = tracking.Matrix.clone(r), a = 0; a < t.length; a++) i[a][0] -= n[0], i[
|
|
a][1] -= n[1], o[a][0] -= e[0], o[a][1] -= e[1];
|
|
var c, s, g, h, k = tracking.Matrix.calcCovarMatrix(i);
|
|
c = k[0], g = k[1], k = tracking.Matrix.calcCovarMatrix(o), s = k[0], h = k[1];
|
|
var f = Math.sqrt(tracking.Matrix.norm(c)),
|
|
u = Math.sqrt(tracking.Matrix.norm(s)),
|
|
l = f / u;
|
|
i = tracking.Matrix.mulScalar(1 / f, i), o = tracking.Matrix.mulScalar(1 / u, o);
|
|
for (var m = 0, d = 0, a = 0; a < t.length; a++) m = m + i[a][1] * o[a][0] - i[a][0] * o[a][1], d = d + i[a][0] *
|
|
o[a][0] + i[a][1] * o[a][1];
|
|
var v = Math.sqrt(m * m + d * d),
|
|
p = m / v,
|
|
y = d / v,
|
|
w = [
|
|
[y, -p],
|
|
[p, y]
|
|
];
|
|
return [w, l]
|
|
}, tracking.LBF.RandomForest = function(t) {
|
|
this.maxNumTrees = tracking.LBF.RegressorData[t].max_numtrees, this.landmarkNum = tracking.LBF.RegressorData[t]
|
|
.num_landmark, this.maxDepth = tracking.LBF.RegressorData[t].max_depth, this.stages = tracking.LBF
|
|
.RegressorData[t].stages, this.rfs = new Array(this.landmarkNum);
|
|
for (var r = 0; r < this.landmarkNum; r++) {
|
|
this.rfs[r] = new Array(this.maxNumTrees);
|
|
for (var n = 0; n < this.maxNumTrees; n++) this.rfs[r][n] = new tracking.LBF.Tree(t, r, n)
|
|
}
|
|
}, tracking.LBF.Tree = function(t, r, n) {
|
|
var e = tracking.LBF.RegressorData[t].landmarks[r][n];
|
|
this.maxDepth = e.max_depth, this.maxNumNodes = e.max_numnodes, this.nodes = e.nodes, this.landmarkID = e
|
|
.landmark_id, this.numLeafnodes = e.num_leafnodes, this.numNodes = e.num_nodes, this.maxNumFeats = e
|
|
.max_numfeats, this.maxRadioRadius = e.max_radio_radius, this.leafnodes = e.id_leafnodes
|
|
}
|
|
}();
|