Riconoscimento facciale in C#
Vediamo passo dopo passo come fare ad implementare il riconoscimento del volto in C#.
Negli ultimi anni, il riconoscimento del volto ha attirato molta attenzione e la sua ricerca si è rapidamente estesa, non solo interessando l’ambito ingegneristico, ma anche quello della neuroscienza, dato che ha molte potenziali applicazioni in nella comunicazione basata sulla computer vision, in ambito medicale e di imaging medica e nello sviluppo di sistemi automatici di controllo degli accessi sempre più perfezionati.
Tuttavia, il riconoscimento dei volti non è semplice, perché l’immagine del volto ha numerose variazioni di aspetto, come ad esempio la variazione della “messa in posa” (anteriore, frontale, laterale), l’occlusione, l’orientamento dell’immagine, la condizione dell’illuminazione, l’espressione facciale (triste, seria, normale, sorridente, allegra, ecc.).
Il primo passo di un sistema per il riconoscimento facciale è l’acquisizione del volto, che può essere presa o tramite upload di una fotografia, oppure tramite fotocamera collegata direttamente al PC o tramite webcam. In questo articolo spiegheremo come si può realizzare un sistema di riconoscimento dei volti in C# utilizzando le librerie open source OpenCV.
OpenCV è una libreria orientata alla computer vision. Originariamente è stata sviluppata da Intel, mentre attualmente è sotto licenza open source BSD. È una libreria multipiattaforma e quindi è compilabile sotto molti sistemi operativi (Windows, Mac OS X, Linux, PSP, VCRT).
Il linguaggio di programmazione utilizzato per sviluppare questa libreria è C++, ma può essere utilizzata con C++ così come con altri linguaggi come C#, C e Python. Useremo il wrapper Emgu CV invece di opencvdotnet.
Cosa è Emgu CV? Emgu CV è un wrapper .Net della famosa libreria Intel OpenCV. Tra i punti di forza di Emgu CV sicuramente il fatto che sia cross platform. Inoltre è migliore di opencvdotnet, in fase di sviluppo. Due trucchi:
- Non è necessario installare OpenCV, ma invece bisogna copiare le dll rilevanti (incluso con il CV Emgu download) per la cartella in cui il codice viene eseguito.
- Aperto CV e X64 non sono amici. Se si sta eseguendo Windows x64 è necessario assicurarsi che la vostra applicazione è compilata per X86, invece dei soliti "Any CPU".
- Ricordarsi di aggiungere l’oggetto PictureBox in cui verrà caricata l’immagine su cui riconoscere il volto.
Nel nostro progetto, cattureremo le immagini da una webcam collegata al PC, quindi le immagini saranno inserite in tempo reale. Istante per istante le immagini catturate verranno visualizzate in un oggetto picturebox e nella quale verrà evidenziato il volto dell’utente in webcam.
Creiamo un nuovo progetto e inseriamo i seguenti oggetti:
- un oggetto timer nominato timer1 che servirà a temporizzare l’algoritmo, in modo che istante per istante operi e evidenzi il volto mostrandolo nella picturebox;
- un oggetto PictureBox nominato pictureBox1 dove verrà catturata l’immagine webcam ed evidenziato il volto.
Quindi passiamo al codice e includiamo le librerie Emgu:
using Emgu.CV;using Emgu.Util;using Emgu.CV.Structure;using Emgu.CV.CvEnum;
Imponiamo la temporizzazione del timer a 100, ovvero ogni decimo di secondo (dato che l’oggetto timer lavora in millesimi di secondo) viene effettuato il controllo sull’immagine catturata da webcam utilizzando un filtro Haar per il rilevare il contorno del viso.
Di seguito il codice di esempio scritto in C#:
using System;using System.Windows.Forms;using System.Drawing;using Emgu.CV;using Emgu.Util;using Emgu.CV.Structure;using Emgu.CV.CvEnum;namespace opencvtut{ public partial class Form1 : Form { private Capture cap; private HaarCascade haar; public Form1() {InitializeComponent(); } private void timer1_Tick(object sender, EventArgs e) { using (Image nextFrame = cap.QueryFrame()) {if (nextFrame != null){// Esiste un solo canale (scala di grigi), quindi imponiamo come indice del frame zero //var faces = nextFrame.DetectHaarCascade(haar)[0]; Image grayframe = nextFrame.Convert(); var faces = grayframe.DetectHaarCascade(haar, 1.4, 4,HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,new Size(nextFrame.Width/8, nextFrame.Height/8))[0]; foreach (var face in faces) { nextFrame.Draw(face.rect, new Bgr(0,double.MaxValue,0), 3); } pictureBox1.Image = nextFrame.ToBitmap();} } } private void Form1_Load(object sender, EventArgs e) {// Passando 0 otteniamo la webcamcap = new Capture(0);// aaggiustiamo il path in modo da trovare il file xml (haarcascade_frontalface_alt2.xml)haar = new HaarCascade( "..\..\..\..\lib\haarcascade_frontalface_alt2.xml"); } }}
- Articolo precedente Ricavare Browser utente con ASP.NET: ottenere e leggere l’user agent del browser
- Articolo successivo Algoritmi di ordinamento in C# : Exchange Sort