Non è facile coniugare la vita circense con jQuery, HTML5 e facial recognition. Ma noi ci abbiamo provato lo stesso, sviluppando un piccolissimo sistema per riconoscere i volti nelle foto e aggiungere naso, occhiali e baffi finti. Vediamo come abbiamo fatto.

Il tool che abbiamo utilizzato

Fra i tanti tool di facial detection (riconoscimento facciale) presenti sul web quello che abbiamo scelto è http://facedetection.jaysalvat.com/. Abbiamo fatto un bel po' di prove prima di deciderci definitivamente e questo ci è sembrato lo strumento più affidabile e veloce.

Per prima cosa, quindi, dobbiamo scaricarlo e inserirlo nel nostro codice, come si fa per qualsiasi altro script (ovviamente usate il path giusto dove avete salvato i file):

<!-- face detection --><br /><script src="/js/facedetection/ccv.js"></script><br /><script src="/js/facedetection/face.js"></script><br /><script src="/js/jquery.facedetection.js"></script>

Face detection

Dopo aver caricato lo script siamo pronti ad eseguirlo con la solita sintassi jQuery:

var coords = $('#id_immagine').faceDetection()

Con questa funzione otteniamo un array con le posizioni (top, left, width, height) dei vari rettangoli che includono le facce riconosciute nell'immagine che stiamo processando. In sostanza otteniamo una cosa del genere:

Possiamo quindi a questo punto scorrere l'array per processare queste facce come vogliamo:

for (var i = 0; i < coords.length; i++)<br />{<br />    $('#facesquare' + i).css({<br />        'top'         : parseInt(coords[i].positionY) + 'px',<br />        'left'        : parseInt(coords[i].positionX) + 'px',<br />        'height'      : parseInt(coords[i].height) + 'px',<br />        'width'       : parseInt(coords[i].width) + 'px',<br />    });<br />}

Ipotizzando di avere dei div così:

<div id="facesquare0"></div><br /><div id="facesquare1"></div><br />...

che siano posizionati in maniera assoluta e con un bordo rosso, in questa maniera otteniamo il risultato dell'immagine di cui sopra, ovvero il posizionamento dei div dove il sistema di facial recognition pensa di aver trovato delle facce.

Semplice, no? 😉

Clownify!

Ora, il passo dall'individuazione del rettangolo alla trasformazione di qualunque volto in quello di un clown è breve.

Prima di tutto definiamo il "naso", in CSS:

.nose {<br />    background: black;<br />    border-radius: 50%;<br />    margin: 0;<br />    background: -webkit-radial-gradient(33% 33%, circle, #ff1100, #900700);<br />    background: -moz-radial-gradient(33% 33%, circle, #ff1100, #900700);<br />    background: radial-gradient(33% 33%, circle, #ff1100, #900700);<br />    box-shadow: 1px 1px 2px #555;<br />}

Dopo di che posizionamolo più o meno nel centro del rettangolo (il "più o meno" è frutto di un po' di prove, questi numeri sono quelli che danno il risultato migliore su un campione piuttosto ampio di foto):

for (var i = 0; i < coords.length; i++)<br />{<br />    var top_nose = parseInt(coords[i].positionY) + parseInt(coords[i].height / 2) + diff_top;<br />    var left_nose = parseInt(coords[i].positionX) + parseInt(coords[i].width / 2) - parseInt(coords[i].width * 0.15) + diff_left;<br />    var width_nose = parseInt(coords[i].height / 3);<br />    var nose = $("<div class='nose todelete' style='position: absolute; top: " + top_nose + "px; left: " + left_nose + "px; width: " + width_nose + "px; height: " + width_nose + "px;'></div>");<br />    $("body").append(nose);<br />}

Come si può vedere qui abbiamo creato un div ogni volta, "appendendolo" al body.

Ora non ci resta altro da fare che far eseguire lo script per processare l'immagine che desideriamo – noi in questo caso lo abbiamo legato all'evento "load" dell'immagine di destinazione:

$(function () {<br />    $('#result_img').load(function () {<br />        // aspettiamo un attimo per essere sicuri che l'immagine sia caricata    <br />        var coords = $(this).delay(200).faceDetection();<br /><br />        // poi per ogni faccia trovata...<br />        for (var i = 0; i < coords.length; i++)<br />        {<br />            // ...verifichiamo di essere abbastanza sicuri...<br />            if (coords[i].confidence > -5)<br />            {<br />                // ... e poi piazziamo il naso<br />                var top_nose = parseInt(coords[i].positionY) + parseInt(coords[i].height / 2);<br />                var left_nose = parseInt(coords[i].positionX) + parseInt(coords[i].width / 2) - parseInt(coords[i].width * 0.15);<br />                var width_nose = parseInt(coords[i].height / 3);<br />                var nose = $("<div class='nose' style='position: absolute; top: " + top_nose + "px; left: " + left_nose + "px; width: " + width_nose + "px; height: " + width_nose + "px;'></div>");<br />                $("body").append(nose);<br />            }<br />        }<br />    }<br />});

Il risultato finale

Ecco qua, in questo iFrame, il risultato finale (con qualche elemento in più… 😉

Diteci che ve ne pare – e giocateci pure come volete cliccando sulle varie facce della galleria – e ovviamente, attendiamo commenti, suggerimenti e idee!

The following two tabs change content below.
Silvio Porcellana
Silvio Porcellana è il fondatore di mob.is.it, il tool che centinaia di agenzie e professionisti di tutto il mondo utilizzano per creare con semplicità siti mobili e applicazioni native per i loro clienti. Tiene anche un podcast dove racconta ogni venerdì le sue avventure imprenditoriali, senza veli o segreti: Opus Digitalis