Quantcast
Channel: C#
Viewing all articles
Browse latest Browse all 1853

Intel RealSense SDK – Face Tracking

$
0
0

In questo articolo daremo un’occhiata alle funzionalità di Face Tracking fornite di serie dall’Intel RealSense SDK.
L’articolo si riferisce alla versione 6.0.x dell’SDK di Intel® RealSense™ attualmente scaricabile all’indirizzo https://software.intel.com/en-us/intel-realsense-sdk/download

Abilitare il modulo di Face

Prima di poter utilizzare effettivamente una o più delle funzionalità relative al face tracking che l’SDK ci mette a disposizione, è necessario attivare il modulo stesso attraverso l’istanza di PXCMSenseManager ed in particolare utilizzando il metodo EnableFace:

SenseManager = PXCMSenseManager.CreateInstance();
SenseManager.EnableStream(PXCMCapture.StreamType.STREAM_TYPE_COLOR, 1280, 720);
SenseManager.EnableFace();

Una volta abilitato l’utilizzo del modulo di face tracking, è necessario recuperare l’istanza del modulo stesso e lo possiamo fare utilizzando il metodo QueryFace della PXCMSenseManager:

FaceModule = SenseManager.QueryFace();

Il valore di ritorno del metodo è un’istanza della classe PXCMFaceModule.

Il modulo PXCMFaceModule

La classe PXCMFaceModule incapsula tutte le funzionalità che riguardano il face tracking degli utenti.
La sua struttura è la seguente:
 

 
La classe espone due metodi il cui utilizzo è il seguente:

  • CreateActiveConfiguration: restituisce un oggetto di tipo che ci consente di configurare il modulo per decidere quali funzionalità vogliamo utilizzare (ad esempio il tracking o i landmarks);
  • CreateOutput: permette di ottenere un oggetto di tipo che è l’handler attraverso il quale recuperare effettivamente i dati del viso che ci interessano.

Configurare il modulo di face tracking

La configurazione del modulo di face tracking (una volta abilitato tramite la PXCMSenseManager) avviene attraverso l’istanza della classe PXCMFaceConfiguration recuperata grazie al metodo CreateActiveConfiguration della classe PXCMFaceModule.
 

 
La classe di configurazione espone una serie di metodi che ci permettono di gestire gli alerts (che saranno presi in esame in un futuro articolo), gestire la tipologia di tracking (SetTrackingMode) e abilitare la funzionalità di face detection (proprietà detection).
Nel caso di face detection, argomento di questo articolo, possiamo configurare il modulo nel seguente modo:

var config = FaceModule.CreateActiveConfiguration();
config.detection.isEnabled = true;
config.landmarks.isEnabled = false;
config.pose.isEnabled = false;
config.strategy = PXCMFaceConfiguration.TrackingStrategyType. STRATEGY_CLOSEST_TO_FARTHEST;
if (config.ApplyChanges().IsSuccessful())
{
    if (SenseManager.Init().IsError())
    {
        MessageBox.Show("Errore nell'inizializzazione della camera");
        Close();
    }
}
config.Dispose();

Nella fattispecie, abilitiamo il face detection e disabilitiamo i landmarks e le face pose (che vedremo in un altro articolo) e scegliamo come strategia di tracking quella che prevede un tracciamento dei volti dal piu’ vicino al più lontano.
La classe DetectionConfiguration (classe innestata nella PXCMFaceConfiguration) ha la seguente struttura:
 

 
L’attributo isEnabled permette di abilitare la funzionalità, maxTrackedFaces definisce il numero massimo di facce che possono essere tracciate (fino a 4) e smoothingLevel definisce il livello di attenuazione del riconoscimento.
Se la configurazione viene applicata con successo (metodo ApplyChanges) possiamo cominciare a recuperare i frame ed analizzarli alla scoperta di eventuali facce rilevate.

Gestire i frame

Come già visto in precedenti articoli, abbiamo due approcci possibili per gestire il recupero dei frame (in questo caso quelli del modulo di face tracking) e l’analisi degli stessi.
Data l’istanza di PXCMSenseManager, possimo:

  1. Implementare un loop all’interno del quale eseguiamo le opportune query ed analizziamo i frame;
  2. Ci afidiamo agli “eventi” sollevati dalla PXCMSenseManager.

Nell’esempio di questo articolo useremo il primo dei due approcci.
Per prima cosa, dunque, è necessario creare un task al cui “interno” faremo girare il nostro loop:

private Task PollingTask;
private CancellationTokenSource TaskCancellationTokenSource;
private CancellationToken PollingTaskCancellationToken;

private void ConfigurePollingTask()
{
    TaskCancellationTokenSource = new CancellationTokenSource();
    PollingTaskCancellationToken = TaskCancellationTokenSource.Token;
    PollingTask = new Task(PollingCode);
    PollingTask.Start();
}

Il metodo PollingCode contiene l’effettivo codice di recupero dei frame (il loop) e utilizza il CancellationTokenSource per essere informato del momento in cui deve chiudersi (ad esempio perché’ l’applicazione si sta chiudendo).

private void PollingCode()
{
    PXCMFaceData faceData = FaceModule.CreateOutput();
    List<PXCMFaceData.Face> faces = new List<PXCMFaceData.Face>();

    while (!PollingTaskCancellationToken.IsCancellationRequested)
    {
        if (SenseManager.AcquireFrame().IsSuccessful())
        {
            faceData.Update();
            faces.Clear();
            for (int i = 0; i < faceData.QueryNumberOfDetectedFaces(); i++)
            {
                faces.Add(faceData.QueryFaceByIndex(i));
            }

            var sample = SenseManager.QuerySample();
            ElaborateSample(sample, faces);
            if (!PollingTaskCancellationToken.IsCancellationRequested) SenseManager.ReleaseFrame();
        }
    }
}

Il primo step fondamentale per poter recuperare i dati relativi al face tracking è quello di ottenere l’istanza di PXCMFaceData che ci occorre per effettuare le opportune query allo scopo di ottenere i dati del tracking:

PXCMFaceData faceData = FaceModule.CreateOutput();

La classe PXCMFaceData ha la seguente struttura:
 

 
I metodi che ci interessano in questo caso sono:

  • Update: permette di aggiornare l’handler PXCMFaceData con i dati correnti recuperati dalla camera relativamente ai volti tracciati;
  • QueryNumberOfDetectedFaces: permette di conoscere il numero di visi che la camera ha tracciato per un determinato frame;
  • QueryFaceByIndex: permette di recuperare i dati di tracciatura (contenuti in un oggetto di classe PXCMFaceData.Face) del viso i-esimo.

In particolare per prima cosa abbiamo la necessità di dire all’SDK di eseguire l’acquisizione del frame attraverso la PXCMSenseManager:

if (SenseManager.AcquireFrame().IsSuccessful())
{
    //
    // .....
    //
}

In caso di acquisizione avvenuta con successo, possiamo aggiornare i dati relativi ai volti tramite il metodo Update:

faceData.Update();

ed iterare sulle eventuali facce riconosciute dal framework per recuperare effettivamente i dati delle stesse:

for (int i = 0; i < faceData.QueryNumberOfDetectedFaces(); i++)
{
    faces.Add(faceData.QueryFaceByIndex(i));
}

O, in alternativa, richiamare il metodo QueryFaces per recuperare tutti dati dei visi tracciati in un solo colpo:

var faces = faceData.QueryFaces();

Il metodo QueryFaceByIndex (o l’omologo QuaryFaceByID) è utile quando vogliamo soffermare l’attenzione su un volto specifico (per esempio vogliamo fare in modo che il nostro applicativo prenda sempre e solo in considerazione il primo volto rilevato) mentre QueryFaces è comodo per avere tutte le informazioni in un sol colpo.
Tutti questi metodi restituiscono, come già detto, oggetti di classe PXCMFaceData.Face la cui struttura è la seguente:
 

 
Come possiamo vedere dalla precedente figura, la classe espone solamente dei metodi che ci consentono di recuperare le più svariate informazioni per la singola faccia.
Nel nostro caso, utilizzeremo il metodo QueryDetection:

PXCMFaceData.DetectionData detectionData = face.QueryDetection();

La classe PXCMFaceDetection.DetectionData permette l’accesso alle informazioni relative al face tracking (o detection) ed ha la seguente struttura:
 

 
Il metodo QueryBoundingRect restituisce il rettangolo, nello spazio, dove è posizionato il viso tracciato mentre il metodo QueryFaceAverageDepth restituisce la distanza media del viso (espressa in millimetri) rispetto al piano focale della camera.
Tutti e due i metodi prevedono la restituzione di un valore booleano che indica se l’operazione è stata eseguita con successo e restituiscono il valore richiesto come out del metodo stesso.

PXCMRectI32 faceBound;
if (detectionData != null && detectionData.QueryBoundingRect(out faceBound))
{
    imageRGB.DrawRectangle(faceBound.x, faceBound.y,
        faceBound.x + faceBound.w, faceBound.y + faceBound.h,
        GetColorByIndex(i), 4);
}

Nell’esempio precedente viene disegnato il rettangolo contenente il viso utilizzando la struttura PXCMRectI32 restituita da QueryBoundigRect.

Conclusioni

Il modulo di face detection espone molte funzionalità interessanti e di pronto utilizzo nelle nostre applicazioni. Nei prossimi articoli andremo a vedere una per una le funzionalità. Il modo con cui si approccia a ciascuna di esse è esattamente lo stesso, l’unica variazione è l’impostazione della configurazione (in modo da abilitare le funzionalità che ci servono) e l’utilizzo degli opportuni metodi della classe Face.
L’esempio riportato in questo articolo è disponibile all’indirizzo https://github.com/massimobonanni/RealSenseSamples in cui potete trovare tutte le demo presenti nei miei articoli su RealSense.

  • Sviluppatori
  • Partner
  • Professori
  • Studenti
  • Microsoft Windows* 10
  • Microsoft Windows* 8.x
  • Tecnologia Intel® RealSense™
  • .NET*
  • C#
  • Principiante
  • SDK Intel® RealSense™
  • Tecnologia Intel® RealSense™
  • Videocamera anteriore F200
  • Videocamera R200
  • Laptop
  • Tablet
  • Desktop
  • URL
  • Esempio di codice
  • Per iniziare

  • Viewing all articles
    Browse latest Browse all 1853

    Trending Articles



    <script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>