face-recognition.js/public_html/js/action-script.js

338 lines
11 KiB
JavaScript

/**************************
* action-script.js *
* 08-09-16 *
***************************
* Designed & Developed by *
* xdrm-brackets *
* & *
* SeekDaSky *
***************************
* https://xdrm.io/ *
* http://seekdasky.ovh/ *
**************************/
{ /* [0] Initialisation
=========================================================*/
/* (1) Elements du DOM */
var DOM = {
body: $('body'),
canvas: $('canvas'),
imageLoader: $('#image-loader')
};
/* (3) Canvas initialisation */
var _CAN = DOM.canvas;
_CAN.width = _CAN.height = 1000;
var _CON = _CAN.getContext('2d');
/* (4) Image Loader + Définitions */
var iL;
var filterManager;
var process = function(){};
var exec = false;
var last;
var Controller, CFolder = {},
init,
initialized = false;
}
var ControllerRememberer = new PermanentStorage();
ControllerRememberer.fetch(function(loaded_data){
log('Preset loaded.', '[PermanentStorage]')
{ /* [1] Initialisation du process
=========================================================*/
/* (1) dat.GUI initialization */
Controller = new dat.GUI({ load: JSON.parse(loaded_data), preset: 'default' });
init = function(){
/* (1) Image par défaut */
this.src = 'front/male/1.jpg';
/* (2) Initialization */
last = this.src;
initialized = true;
/* (3) Attachment to dat.GUI */
CFolder.src = Controller.addFolder('Source Picture');
Controller.remember(this);
CFolder.src.add(this, 'src', this._images).listen();
};
}
/* [2] Routine principale
=========================================================*/
LOADER.init();
process = function(){
// Si erreur de `bind()`, on quitte
if( !initialized || !(this instanceof HTMLImageElement) )
return;
console.time('PROCESS');
LOADER.start();
/* [0.0] Gestion du changement d'image
=========================================================*/
if( this.src != last ){
reactiveFaceTracking.zones = [];
reactiveFeatureTracking.zones = [];
exec = false;
last = this.src;
}
/* [0.1] Gestion de la première exécution (par image)
=========================================================*/
if( !exec ){
/* (1) On enregistre les dimensions par défaut
---------------------------------------------------------*/
this.defaultWidth = this.width;
this.defaultHeight = this.height;
// log('Image copied', '[Canvas]');
// On change la valeur de `exec` pour qu'il n'entre plus dans ce `if`
exec = true;
}
/* [1] On initialise/efface le `<canvas>`
=========================================================*/
_CON.clearRect(0, 0, _CAN.width, _CAN.height);
{ /* [2] Copie sur le `<canvas>`
=========================================================*/
/* (1) Resolution */
filterManager.get('resolution').apply();
}
{ /* [3] Filtrage pre-processing
=========================================================*/
/* (1) Contraste */
filterManager.get('contrast').apply();
/* (2) Contraste */
filterManager.get('grayscale').apply();
/* (3) Sobel */
filterManager.get('sobel').apply();
/* (4) Gaussian Filter */
filterManager.get('gaussian').apply();
/* (5) Canny Filter */
filterManager.get('canny').apply();
}
{ /* [4] Tracking.js
=========================================================*/
/* (1) On reporte chaque zone trackée sur le `<canvas>` */
var i, il, x, y, w, h, a, c, cur, lst, ncollision;
c = 0;
for( i = 0, il = reactiveFeatureTracking.zones.length ; i < il ; i++ ){
// {2} Inclusion verification //
if( c <= 3 ){
ncollision = true;
for( a = 0 ; a < i ; a++ ){
lst = reactiveFeatureTracking.zones[a];
cur = reactiveFeatureTracking.zones[i];
ncollision = (lst.x >= cur.x+cur.w) // if no collision (@lst away from @cur)
|| (lst.y >= cur.y+cur.h)
|| (lst.x+lst.w <= cur.x)
|| (lst.y+lst.h <= cur.y);
if( !ncollision ) // if collision, we know
break;
// else, check other previous rects
}
}
(ncollision) && c++;
(c>3) && (ncollision=false);
// {3} Storing rects //
x = reactiveFeatureTracking.zones[i].x * _CAN.width;
y = reactiveFeatureTracking.zones[i].y * _CAN.height;
w = reactiveFeatureTracking.zones[i].w * _CAN.width;
h = reactiveFeatureTracking.zones[i].h * _CAN.height;
_CON.lineWidth = 5;
_CON.strokeStyle = !ncollision ? 'rgba(0, 255, 0, .3)' : '#0f0';
_CON.strokeRect(x, y, w, h);
}
c = 0;
for( i = 0, il = reactiveFaceTracking.zones.length ; i < il ; i++ ){
// {2} Inclusion verification //
if( c <= 1 ){
ncollision = true;
for( a = 0 ; a < i ; a++ ){
lst = reactiveFaceTracking.zones[a];
cur = reactiveFaceTracking.zones[i];
ncollision = (lst.x >= cur.x+cur.w) // if no collision (@lst away from @cur)
|| (lst.y >= cur.y+cur.h)
|| (lst.x+lst.w <= cur.x)
|| (lst.y+lst.h <= cur.y);
if( !ncollision ) // if collision, we know
break;
// else, check other previous rects
}
}
// 3 rects maximum
(ncollision) && c++;
(c>1) && (ncollision=false);
// {3} Storing rects //
x = reactiveFaceTracking.zones[i].x * _CAN.width;
y = reactiveFaceTracking.zones[i].y * _CAN.height;
w = reactiveFaceTracking.zones[i].w * _CAN.width;
h = reactiveFaceTracking.zones[i].h * _CAN.height;
_CON.lineWidth = 5;
_CON.strokeStyle = !ncollision ? 'rgba(0, 0, 255, .3)' : '#00f';
_CON.strokeRect(x, y, w, h);
}
}
{ /* [5] Filtrage post-processing
=========================================================*/
}
console.timeEnd('PROCESS');
LOADER.stop();
};
{ /* [3] Gestion des `ReactiveFilter`
=========================================================*/
/* (1) Création du Manager */
filterManager = new ReactiveFilterManager(DOM.imageLoader, _CAN, process);
/* (2) Ajout des filtres */
filterManager.add('feature_tracking', reactiveFeatureTracking);
filterManager.add('face_tracking', reactiveFaceTracking);
filterManager.add('resolution', reactiveResolution);
filterManager.add('contrast', reactiveContrast);
filterManager.add('grayscale', reactiveGrayscale);
filterManager.add('sobel', reactiveSobel);
filterManager.add('gaussian', reactiveGaussianBlur);
filterManager.add('canny', reactiveCanny);
filterManager.add('haar_face', reactiveHaarFace);
/* (3) Gestion des backups */
Controller.remember(filterManager.get('face_tracking'));
Controller.remember(filterManager.get('feature_tracking'));
Controller.remember(filterManager.get('resolution'));
Controller.remember(filterManager.get('contrast'));
Controller.remember(filterManager.get('grayscale'));
Controller.remember(filterManager.get('sobel'));
Controller.remember(filterManager.get('canny'));
Controller.remember(filterManager.get('gaussian'));
Controller.remember(filterManager.get('haar_face'));
/* (4) On attache tout à dat.GUI */
CFolder.custom = Controller.addFolder('custom');
CFolder.resolution = CFolder.custom.addFolder('Image Resolution');
CFolder.resolution.add(filterManager.get('resolution'), 'width', 0, 2).step(0.1);
CFolder.resolution.add(filterManager.get('resolution'), 'height', 0, 2).step(0.1);
CFolder.basic = CFolder.custom.addFolder('Basic Image Processing');
CFolder.basic.add(filterManager.get('contrast'), 'contrast', 0, 100);
CFolder.basic.add(filterManager.get('grayscale'), 'grayscale');
CFolder.tracking = Controller.addFolder('Tracking.js');
CFolder.face_tracking = CFolder.tracking.addFolder('Face tracking');
CFolder.face_tracking.add(filterManager.get('face_tracking'), 'apply');
CFolder.face_tracking.add(filterManager.get('face_tracking'), 'initial_scale', 1, 10).step(0.5);
CFolder.face_tracking.add(filterManager.get('face_tracking'), 'step_size', -.1, 5).step(0.1);
CFolder.face_tracking.add(filterManager.get('face_tracking'), 'edges_density', 0.1, 0.5).step(0.01);
CFolder.feature_tracking = CFolder.tracking.addFolder('Feature tracking');
CFolder.feature_tracking.add(filterManager.get('feature_tracking'), 'apply');
CFolder.feature_tracking.add(filterManager.get('feature_tracking'), 'initial_scale', 1, 10).step(0.5);
CFolder.feature_tracking.add(filterManager.get('feature_tracking'), 'step_size', -.1, 5).step(0.1);
CFolder.feature_tracking.add(filterManager.get('feature_tracking'), 'edges_density', 0.1, 0.5).step(0.01);
CFolder.jsfeat = Controller.addFolder('jsfeat');
CFolder.haar_face = CFolder.jsfeat.addFolder('Haar Face Detection');
CFolder.haar_face.add(filterManager.get('haar_face'), 'apply');
CFolder.haar_face.add(filterManager.get('haar_face'), 'min_scale', 1, 4).step(0.1);
CFolder.haar_face.add(filterManager.get('haar_face'), 'scale_factor', 1.1, 2).step(0.025);
CFolder.haar_face.add(filterManager.get('haar_face'), 'equalize_histogram');
CFolder.haar_face.add(filterManager.get('haar_face'), 'use_canny');
CFolder.haar_face.add(filterManager.get('haar_face'), 'edges_density', 0.01, 1.0).step(0.005);
CFolder.gaussian = CFolder.jsfeat.addFolder('Gaussian Blur');
CFolder.gaussian.add(filterManager.get('gaussian'), 'active');
CFolder.gaussian.add(filterManager.get('gaussian'), 'sigma', 0, 10).step(0.5);
CFolder.gaussian.add(filterManager.get('gaussian'), 'radius', 1, 11).step(1);
CFolder.sobel = CFolder.jsfeat.addFolder('Sobel Filter');
CFolder.sobel.add(filterManager.get('sobel'), 'sobelActive');
CFolder.canny = CFolder.jsfeat.addFolder('Canny Filter');
CFolder.canny.add(filterManager.get('canny'), 'active');
CFolder.canny.add(filterManager.get('canny'), 'radius', 0, 4).step(1);
CFolder.canny.add(filterManager.get('canny'), 'low_threshold', 1, 127).step(1);
CFolder.canny.add(filterManager.get('canny'), 'high_threshold', 1, 127).step(1);
CFolder.process = Controller.addFolder('Process');
CFolder.process.add({render: process}, 'render');
/* (5) Gestion du @PermanentStorage */
Controller.__save_row.children[2].addEventListener('click', function(){
/* (1) Update properties */
Controller.save();
/* (2) Get stored data */
try{
var stored = JSON.stringify( Controller.getSaveObject() );
ControllerRememberer.store(stored, function(){ log('dat.GUI preset stored.', '[PermanentStorage]'); return true; });
}catch(e){ log('Corrupted data.', '[PermanentStorage]'); }
}, false);
}
/* [x] Chargement image
=========================================================*/
iL = new ImageLoader( DOM.imageLoader, init, process );
return true;
});