webgazer
Version:
WebGazer.js is an eye tracking library that uses common webcams to infer the eye-gaze locations of web visitors on a page in real time. The eye tracking model it contains self-calibrates by watching web visitors interact with the web page and trains a map
105 lines (89 loc) • 2.77 kB
JavaScript
import util from './util.mjs';
import util_regression from './util_regression.mjs';
import params from './params.mjs';
const reg = {};
/**
* Constructor of RidgeReg object,
* this object allow to perform ridge regression
* @constructor
*/
reg.RidgeReg = function() {
this.init();
};
/**
* Initialize new arrays and initialize Kalman filter.
*/
reg.RidgeReg.prototype.init = util_regression.InitRegression
/**
* Add given data from eyes
* @param {Object} eyes - eyes where extract data to add
* @param {Object} screenPos - The current screen point
* @param {Object} type - The type of performed action
*/
reg.RidgeReg.prototype.addData = util_regression.addData
/**
* Try to predict coordinates from pupil data
* after apply linear regression on data set
* @param {Object} eyesObj - The current user eyes object
* @returns {Object}
*/
reg.RidgeReg.prototype.predict = function(eyesObj) {
if (!eyesObj || this.eyeFeaturesClicks.length === 0) {
return null;
}
var acceptTime = performance.now() - this.trailTime;
var trailX = [];
var trailY = [];
var trailFeat = [];
for (var i = 0; i < this.trailDataWindow; i++) {
if (this.trailTimes.get(i) > acceptTime) {
trailX.push(this.screenXTrailArray.get(i));
trailY.push(this.screenYTrailArray.get(i));
trailFeat.push(this.eyeFeaturesTrail.get(i));
}
}
var screenXArray = this.screenXClicksArray.data.concat(trailX);
var screenYArray = this.screenYClicksArray.data.concat(trailY);
var eyeFeatures = this.eyeFeaturesClicks.data.concat(trailFeat);
var coefficientsX = util_regression.ridge(screenXArray, eyeFeatures, this.ridgeParameter);
var coefficientsY = util_regression.ridge(screenYArray, eyeFeatures, this.ridgeParameter);
var eyeFeats = util.getEyeFeats(eyesObj);
var predictedX = 0;
for(var i=0; i< eyeFeats.length; i++){
predictedX += eyeFeats[i] * coefficientsX[i];
}
var predictedY = 0;
for(var i=0; i< eyeFeats.length; i++){
predictedY += eyeFeats[i] * coefficientsY[i];
}
predictedX = Math.floor(predictedX);
predictedY = Math.floor(predictedY);
if (params.applyKalmanFilter) {
// Update Kalman model, and get prediction
var newGaze = [predictedX, predictedY]; // [20200607 xk] Should we use a 1x4 vector?
newGaze = this.kalman.update(newGaze);
return {
x: newGaze[0],
y: newGaze[1]
};
} else {
return {
x: predictedX,
y: predictedY
};
}
};
reg.RidgeReg.prototype.setData = util_regression.setData;
/**
* Return the data
* @returns {Array.<Object>|*}
*/
reg.RidgeReg.prototype.getData = function() {
return this.dataClicks.data;
}
/**
* The RidgeReg object name
* @type {string}
*/
reg.RidgeReg.prototype.name = 'ridge';
export default reg;