Intel Perceptual Computing SDK è una libreria, realizzata da Intel, che fornisce agli sviluppatori una serie di strumenti per la realizzazione di interfacce naturali (Natural User Interface - NUI).
L'SDK è composto da una parte software (librerie, sample e documentazione) e da una parte hardware costituita dalla Creative Gesture Camera realizzata da Creative che fornisce funzionalità di rilevamento 3D e audio tridimensionale. In realtà molte delle funzionalità della libreria sono disponibili anche con le normali webcam.
Una caratteristica dell'SDK è quella di fornire delle implementazioni di base per i principali algoritmi di riconocimento facciale, di gesture e speech recognition ma di permettere anche la possibilità di utilizzare i propri algoritmi di riconoscimento.
Architettura
L'architettura di Intel Perceptual Computing SDK è mostrata nella seguente figura:
La parte sottostante le "SDK Interfaces" rappresenta l'implementazione dei differenti algoritmi di riconoscimento, dei moduli di I/O (ad esempio della scrittura su disco) e dei servizi a supporto di questi (ad esempio l'infrastruttura di caricamento dei moduli oppure la parte di interoperabilità con i driver).
Tutta questa parte è scritta in C/C++ ed è esposta verso lo sviluppatore attraverso uno strato di interfacce. L'utilizzo di interfacce, opportunamente istanziate dal framework di Intel, permette di sostituire le nostre implementazioni dei moduli di riconoscimento a quelle fornite di default da Intel.
Al di sopra dello strato di interfacce troviamo delle classi di utilità, sempre scritte in C/C++, e uno strato di porting (anche se sarebbe più corretto dire di proiezione) verso alcuni framework applicativi utilizzati comunemente nello sviluppo come .NET, Unity o openFramework.
Al top dello stack architetturale troviamo, infine, le nostre applicazioni (scritte in C/C++ o uno degli altri framework) e i samples forniti a corredo con l'SDK.
Entrando in dettaglio della parte relativa allo sviluppo vero e proprio utilizzando l'SDK, lo schema architetturale delle applicazioni è il seguente:
Lo strato inferiore è costituito da librerie scritte in C++ contenenti:
- gli oggetti di base (identificati con Core Framework) in cui troviamo la sessione di riconoscimento, la classe immagine, l'audio e via dicendo;
- l'implementazione fornita dal framework per gli algoritmi di riconoscimento (Gesture, Face Analysis di cui ci occuperemo in questo articolo, Voice Recognition, etc.);
- moduli di I/O per la lettura/scrittura degli stream del framework (ad esempio lo stream delle immagini provenienti dalla webcam).
Le applicazioni scritte in C++ possono utilizzare direttamente questo strato oppure possono servirsi degli altri strati con più funzionalità aggregate e meno di basso livello, indicati con il nome di UtilCapture e UtilPipeline.
Il mondo managed (per i linguaggi VB.NET e C#) utilizza, invece, il porting denominato "C#/VB.NET Port" (libreria libpxcclr.dll
che vedremo in seguito). All'interno di questo troviamo una serie di classi wrapper che ricalcano, più o meno fedelmente, le librerie disponibili per gli sviluppatori C++ (sono riconoscibili dalla presenza di una "M
" dopo il prefisso PXC
nel nome).
In questo articolo utilizzeremo proprio questo porting.
Installare l'SDK
Per iniziare possiamo scaricare il Perceptual Computing SDK. Nel momento in cui si sta scrivendo l'articolo è disponibile la versione 1.0.8779.0.
I requisiti hardware per poter utilizzare il framework sono:
- Processori Intel Core di II, III o IV generazione;
- Sistema operativo Windows 7 SP1 o Windows 8 desktop (32 e 64 bit);
- Spazio di 1GB su hard disk.
Una volta scaricato l'installer (o utilizzato quello web), è sufficiente lanciarlo e seguire la procedura. Alla fine riavviamo il PC.
La Creative Gesture Camera
Prima di proseguire con esempi pratici di programmazione, vediamo quali sono le caratteristiche principali della Creative Gesture Camera:
- una camera 720p (che può essere utilizzata anche come normale webcam con risoluzione
1280x720
); - un sensore di profondità 3D basato su tecnologia ad infrarossi in grado di rilevare gesture delle mani a distanza ravvicinata (con risoluzione
320x240
); - un "array" di due microfoni che consentono di localizzare la provenienza del suono per garantire prestazioni migliori di speech recognition.
Possiamo collegare la periferica al pc con una porta USB 2.0 e le sue dimensioni ci consentono di agganciarla alla parte superiore del display di un notebook o montarla con vite standard su un cavalletto fotografico. È piuttosto importante averla vicino al soggetto da riprendere: il range di utilizzo è compreso tra circa 15 centimetri e un metro.
Vediamo ora come iniziare il primo progetto con Visual Studio.
Il primo progetto Visual Studio
Realizziamo il nostro primo progetto utilizzando Intel Perceptual Computing SDK che ci servirà per capire le funzionalità di Face Detection messe a disposizione dello sviluppatore.
Apriamo Visual Studio 2012 e scegliamo un nuovo progetto Windows Form con C#:
Una volta creato il progetto e referenziamo la libreria libpxcclr.dll
che si trova nelle cartelle:
C:Program Files (x86)IntelPCSDKbinwin32
C:Program Files (x86)IntelPCSDKbinx64
Come abbiamo anticipato, il questa libreria troviamo le classi wrapper che espongono al mondo .NET (C# e VB.NET), le funzionalità del framework scritto in C++.
Per referenziare la libreria utilizziamo il menu contestuale "Add Reference...
" di Visual Studio come mostrato in figura:
Appare una finestra di dialogo per la selezione della dll da collegare al progetto. Cerchiamo il file libpxcclr.dll
con la classica opzione Browse
:
Fatto questo siamo pronti a scrivere la nostra applicazione per il Face Detection.
La classe UtilMPipeline
Il progetto demo allegato all'articolo prevede una form principale in cui verrà visualizzata l'immagine proveniente dalla webcam sulla quale verranno riportate le informazioni ricavate tramite le API del Preceptual Computing SDK.
In sostanza utilizzeremo le seguenti funzionalità:
- Recupero dell'immagine RGB ripresa dalla webcam;
- Recupero delle facce identificate dall'SDK in termini di posizione e identificativo;
- Recupero, per ogni faccia rilevata, dei punti importanti (detti landmark) e della postura della stessa (pose).
La form principale della nostra applicazione utilizzerà una classe, che chiameremo FaceDetector, il cui scopo è quello di interagire con l'SDK e di aggiornare la UI.
public class FaceDetector
{
private IFaceDetectorForm form;
private bool disconnected = false;
public FaceDetector(IFaceDetectorForm form)
{
if (form == null) throw new ArgumentNullException("form");
this.form = form;
}
...
}
Public Class FaceDetector
Private form As IFaceDetectorForm
Private disconnected As Boolean = False
Public Sub New(form As IFaceDetectorForm)
If form Is Nothing Then Throw New ArgumentNullException("form")
Me.form = form
End Sub
...
End Class
Guarda il codice in VB.NET
L'interfaccia IFaceDetectorForm
definisce i metodi che la form deve implementare per fare in modo che la classe FaceDetector
possa aggiornare la stessa con le informazioni recuperate tramite le API dell'SDK.
public interface IFaceDetectorForm
{
void DisplayWebCamImage(System.Drawing.Bitmap bitmap);
void DrawLocation(PXCMFaceAnalysis.Detection.Data detectionData);
void DrawLandmark(PXCMFaceAnalysis.Landmark.LandmarkData[] landmarkData);
void DrawPose(PXCMFaceAnalysis.Landmark.PoseData poseData);
void UpdateStatus(string p);
bool IsDetectionStopped();
void UpdateGUI();
}
Public Interface IFaceDetectorForm
Sub DisplayWebCamImage(bitmap As Bitmap)
Sub DrawLocation(detectionData As PXCMFaceAnalysis.Detection.Data)
Sub DrawLandmark(landmarkData As PXCMFaceAnalysis.Landmark.LandmarkData())
Sub DrawPose(poseData As PXCMFaceAnalysis.Landmark.PoseData)
Sub UpdateStatus(p1 As String)
Function IsDetectionStopped() As Boolean
Sub UpdateGUI()
End Interface
Guarda il codice in VB.NET
Attraverso l'utilizzo dell'interfaccia IFaceDetectorForm cerchiamo di disaccoppiare la finestra Windows Form dalla classe FaceDetector (con la possibilità di utilizzare quest'ultima anche con altre tecnologie come, ad esenpio, WPF).
La classe FaceDetector, come già detto in precedenza, accede alle API dell'SDK e per farlo utilizza la classe UtilMPipeline. Le pipeline sono classi che espongono tutta una serie di metodi predefiniti che facilitano l'accesso al device connesso per recuperare le informazioni, come in questo caso, relative al face detection.
Nel caso di specie, la classe FaceDetector espone un metodo che permette di avviare il processo di recupero dei dati:
public void StartLoop()
{
bool isPipelineStopped=true;
UtilMPipeline pipeline;
disconnected=false;
pipeline = new UtilMPipeline();
pipeline.EnableFaceLocation();
pipeline.EnableFaceLandmark();
form.UpdateStatus("Init Started");
if (pipeline.Init())
{
form.UpdateStatus("Streaming");
while (!form.IsDetectionStopped())
{
if (!pipeline.AcquireFrame(true)) break;
if (!DisplayDeviceConnection(pipeline.IsDisconnected()))
{
PXCMFaceAnalysis faceAnalysis = pipeline.QueryFace();
DisplayImage(pipeline.QueryImage(PXCMImage.ImageType.IMAGE_TYPE_COLOR));
DisplayLocation(faceAnalysis);
form.UpdateGUI();
}
pipeline.ReleaseFrame();
}
}
else
{
form.UpdateStatus("Init Failed");
isPipelineStopped=false;
}
pipeline.Close();
pipeline.Dispose();
if (isPipelineStopped) form.UpdateStatus("Stopped");
}
Public Sub StartLoop()
Dim isPipelineStopped As Boolean = True
Dim pipeline As UtilMPipeline
disconnected = False
pipeline = New UtilMPipeline
pipeline.EnableFaceLocation()
pipeline.EnableFaceLandmark()
form.UpdateStatus("Init Started")
If pipeline.Init() Then
form.UpdateStatus("Streaming")
While Not form.IsDetectionStopped()
If Not pipeline.AcquireFrame(True) Then Exit While
If Not DisplayDeviceConnection(pipeline.IsDisconnected()) Then
Dim faceAnalysis As PXCMFaceAnalysis = pipeline.QueryFace()
DisplayImage(pipeline.QueryImage(PXCMImage.ImageType.IMAGE_TYPE_COLOR))
DisplayLocation(faceAnalysis)
form.UpdateGUI()
End If
pipeline.ReleaseFrame()
End While
Else
form.UpdateStatus("Init Failed")
isPipelineStopped = False
End If
pipeline.Close()
pipeline.Dispose()
If (isPipelineStopped) Then form.UpdateStatus("Stopped")
End Sub
Guarda il codice in VB.NET
Possiamo individuare tre grandi blocchi:
- Creazione della pipeline e abilitazione delle funzionalità di face location e face landmark;
- Loop di recupero dell'immagine RGB, della face locaion e dei landmark;
- Rilascio della pipeline.
Creazione della pipeline
La creazione della UtilMPipeline
avviene tramite un canonico new
seguito dalla chiamata ai due metodi EnableFaceLocation()
e EnableFaceLandmark()
.
È essenziale il richiamo di tali metodi, altrimenti, nel momento in cui andremo a richiedere le informazioni, rispettivamente, della face location o dei face landmark, queste non saranno disponibili.
Il loop che si occupa di recuperare effettivamente le informazioni che ci interessano viene eseguito sino a che l'interfaccia non comunica alla classe FaceDetector
l'intenzione di fermare il processo (valore di ritorno del metodo IsDetectionStopped dell'interfaccia IFaceDetectorForm). All'interno del loop viene eseguito il seguente codice:
if (!pipeline.AcquireFrame(true)) break;
if (!DisplayDeviceConnection(pipeline.IsDisconnected()))
{
DisplayImage(pipeline.QueryImage(PXCMImage.ImageType.IMAGE_TYPE_COLOR));
PXCMFaceAnalysis faceAnalysis = pipeline.QueryFace();
DisplayLocation(faceAnalysis);
form.UpdateGUI();
}
pipeline.ReleaseFrame();
If Not pipeline.AcquireFrame(True) Then Exit While
If Not DisplayDeviceConnection(pipeline.IsDisconnected()) Then
DisplayImage(pipeline.QueryImage(PXCMImage.ImageType.IMAGE_TYPE_COLOR))
Dim faceAnalysis As PXCMFaceAnalysis = pipeline.QueryFace()
DisplayLocation(faceAnalysis)
form.UpdateGUI()
End If
pipeline.ReleaseFrame()
Guarda il codice in VB.NET
Il metodo AcquireFrame
della classe UtilMPipeline
informa il framework di Intel la volontà, da parte del nostro software, di recuperare il frame attuale da parte della web cam.
Se il risultato di questo metodo è false
, allora si è verificato un errore ed il loop termina immediatamente.
Subito dopo aver acquisito il frame corrente ed esserci assicurati che il device sia effettivamente connesso (metodo IsDisconnected
), procediamo con il recupero e, successiva visualizzazione da parte dell'interfaccia, dell'immagine RGB proveniente dalla Web cam
Ottenere le immagini
Il metodo QueryImage
permette di ottenere un oggetto PXCMImage
contenente le informazioni dell'immagine. Il tipo dell'immagine (enumerazione PXCMImage.ImageType
) consente di specificare la tipologia dell'immagine tra IMAGE_TYPE_COLOR
(immagine a colori classica) o IMAGE_TYPE_DEPTH
(immagine in cui ogni punto riporta la distanza del corrispondente punto dell'oggetto che si trova di fronte alla camera dalla camera stessa).
Il metodo DisplayImage
si occupa di convertire l'immagine dal formato Intel Perceptual Computing ad un formato manipolabile dalla nostra GUI (la Bitmap
del framework .NET) e di inviare la stessa alla form (tramite il metodo DisplayWebCamImage
dell'interfaccia IFaceDetectorForm
)
Dopo aver gestito l'immagine proveniente dalla web cam, procediamo con il recuperare l'istanza di PXCMFaceAnalysis
sfruttando il metodo QueryFace
della UtilMPipeline
. La classe PXCMFaceAnalysis
è la classe che ci consente di accedere a tutte le funzionalità di face analysis come posizione delle facce rilevate (se ce ne sono), i landmark e la posizione delle stesse nello spazio.
L'immagine della webcam
La cosa più semplice che possiamo fare con una web cam (e, a volte, anche l'unica) è recuperare l'immagine immortalata dalla stessa.
Nel nostro caso utilizzeremo le API messe a disposizione dal Perceptual Computing SDK come mostrato nel seguente codice:
private void DisplayImage(PXCMImage image)
{
PXCMImage.ImageData data;
var status = image.AcquireAccess(PXCMImage.Access.ACCESS_READ,
PXCMImage.ColorFormat.COLOR_FORMAT_RGB32,
out data);
if (status == pxcmStatus.PXCM_STATUS_NO_ERROR)
{
PXCMImage.ImageInfo imageInfo = image.imageInfo;
var bitmap = data.ToBitmap(imageInfo.width, imageInfo.height);
form.DisplayWebCamImage(bitmap);
image.ReleaseAccess(ref data);
}
}
Private Sub DisplayImage(image As PXCMImage)
Dim data As PXCMImage.ImageData
Dim status = image.AcquireAccess(PXCMImage.Access.ACCESS_READ,
PXCMImage.ColorFormat.COLOR_FORMAT_RGB32, data)
If status = pxcmStatus.PXCM_STATUS_NO_ERROR Then
Dim width As UInt32
Dim height As UInt32
Dim colorFormat As PXCMImage.ColorFormat
If image.GetImageInfo(width, height, colorFormat) Then
Dim bitmap As Bitmap = data.ToBitmap(width, height)
form.DisplayWebCamImage(bitmap)
image.ReleaseAccess(data)
End If
End If
End Sub
Guarda il codice in VB.NET
La struttura PXCMImage.ImageData
contiene l'immagine recuperata dalla camera ed espone alcuni metodi per convertirla in Bitmap
o WritableBitmap
.
Il confronto tra i due pezzi di codice scritti in C# e VB.NET mette in evidenza anche un ulteriore fatto che deve essere tenuto in dovuto conto dagli sviluppatori VB.NET nel momento in cui approcciano all'utilizzo delle API.
Il framework è organizzato secondo classi innestate anzichè sfruttare i namespace come normalmente accade nelle librerie .NET. Le strutture ImageData
o ImageInfo
si trovano, infatti, innestate nella classe PXCMImage
anzichè appartenere ad un namespace specifico per le immagini (ad esempio Intel.PerceptualComputing.Imaging
). Il problema per coloro che lavorano con i linguaggi "case insensitive" come VB.NET è che, se esistono membri della classe contenitore e classi innestate con lo stesso nome, entrambi spariscono. È il caso, ad esempio, della proprietà imageInfo
della classe PXCMImage
e della struttura PXCMImage.ImageInfo
contenuta nella stessa: lo sventurato programmatore VB.NET non le vedrà e sarà costretto ad usare la tecnica della Reflection per recuperare i dati (o a creare un apposito progetto C# per implementare degli extension method atti a recuperare i dati). Nel progetto allegato come esempio viene utilizzata la reflection.
Recuperare le facce rilevate
Una volta ottenuta l'istanza di PXCMFaceAnalysis, possiamo andare alla ricerca delle facce eventualmente rilevate dalla piattaforma.
Per recuperare l'identificativo delle eventuali facce rilevate (nel caso ce ne fossero), possiamo utilizzare il metodo QueryFace
della classe PXCMFaceAnalysis
for (UInt32 faceIndex = 0; ; faceIndex++)
{
Int32 faceId;
ulong faceTimestamp;
if (faceAnalysis.QueryFace(faceIndex, out faceId, out faceTimestamp) == pxcmStatus.PXCM_STATUS_NO_ERROR)
{
/* Retrieve face data */
}
else break;
}
Dim faceIndex As UInt32 = 0
Do
Dim faceId As Integer
Dim faceTimestamp As ULong
If faceAnalysis.QueryFace(faceIndex, faceId, faceTimestamp) = pxcmStatus.PXCM_STATUS_NO_ERROR Then
' Retrieve Face Data
Else
Exit Do
End If
faceIndex = faceIndex + CUInt(1)
Loop While True
Guarda il codice in VB.NET
Come si nota nel codice, non sappiamo a priori quante facce sono state identificate dal framework, ma dobbiamo procedere iterando su un indice (faceIndex
nel nostro caso) fino a ottenere un risultato diverso da pxcmStatus.PXCM_STATUS_NO_ERROR
.
Se, per l'indice in esame, la piattaforma ha rilevato una faccia, il metodo QueryFace
di PXCMFaceAnalysis
ci fornisce il sui identificativo univoco (faceId
) e il timestamp in cui è stata rilevata.
L'identificativo univoco ci permette di recuperare tutte le altre informazioni relative alla faccia.
Face detection
Utilizzando le funzionalità di Face detection siamo in grado di conoscere le coordinate, rispetto all'immagine recuperata dalla camera, in cui si trova la faccia rilevata.
La posizione di una faccia si può recuperare grazie all'identificativo univoco della stessa visto in precedenza.
PXCMFaceAnalysis.Detection faceDetection = faceAnalysis.DynamicCast(PXCMFaceAnalysis.Detection.CUID);
PXCMFaceAnalysis.Detection.Data detectionData;
if (faceDetection.QueryData(faceId, out detectionData) == pxcmStatus.PXCM_STATUS_NO_ERROR)
form.DrawLocation(detectionData);
Dim faceDetection As PXCMFaceAnalysis.Detection = faceAnalysis.DynamicCast(Of PXCMFaceAnalysis.Detection)(PXCMFaceAnalysis.Detection.CUID)
Dim detectionData As PXCMFaceAnalysis.Detection.Data
If faceDetection.QueryData(faceId, detectionData) = pxcmStatus.PXCM_STATUS_NO_ERROR Then
form.DrawLocation(detectionData)
End If
Guarda il codice in VB.NET
La classe PXCMFaceAnalysis.Detection
espone le funzionalità di face detection ed è fornita dal framework richiamando il metodo DynamicCast
(comune a molte classi di Perceptual Computing). DynamicCast
è un metodo generico che restituisce l'istanza del tipo voluto a partire dal proprio CUID (Class Unique IDentifier).
Una volta recuperata l'istanza di PXCMFaceAnalysis.Detection
, utilizziamo il metodo QueryData
per ottenere la struttura PXCMFaceAnalysis.Detection.Data
mostrata nella seguente figura:
La struttura contiene il rettangolo (campo rectangle di tipo PXCMRectU32
) in cui il framework ha rilevato la faccia, il valore di confidence (cioè quanto il framework pensa sia attendibile il rilevamento) e l'angolo che la faccia stessa forma con il piano della camera (campo viewAngle
di tipo PXCMFaceAnalysis.Detection.ViewAngle
. Ad esempio il valore VIEW_ANGLE_0 indica che l'utente si trova con la faccia che forma un angolo di 90 gradi verso sinistra rispetto alla perpendicolare del piano frontale della camera.
Le funzionalità di face detection sono disponibili anche con una normale webcam al posto della Creative Gesture Camera anche se limitatamente alla posizione e non all'angolo.
Face landmark e pose
I landmark sono i punti salienti di un volto. Intel Perceptual Computing SDK consente di recuperare 6 o 7 punti (ognuno dei quali nelle tre cordinate spaziali) come mostrato nella seguente figura:
Contestualmente al recupero di tali punti vengono fornite anche le informazioni relative alla posizione del volto nello spazio:
Valore | Descrizione |
---|---|
Pitch (beccheggio) | La rotazione della testa lungo il proprio asse trasversale (quello, per intenderci, che passa per le orecchie) |
Roll (rollio) | La rotazione della testa lungo il proprio asse longitudinale (quello che esce dal naso) |
Yaw (imbardata) | La rotazione della testa lungo il suo asse verticale (quello, che esce dalla parte superiore della testa) |
Tutte queste informazioni (landmark e pose) ci permettono di poter esattamente sapere come è posizionata la testa nello spazio. Per ottenere l'insieme di landmark e pose, a partire dall'identificativo della faccia (già visto in precedenza), possiamo procedere nel seguente modo:
1. Recuperare un'istanza della classe PXCMFaceAnalysis.Landmark
(equivalente per i landmark della classe PXCMFaceAnalysis.Detection
vista in precedenza);
PXCMFaceAnalysis.Landmark faceLandmark =
faceAnalysis.DynamicCast(PXCMFaceAnalysis.Landmark.CUID);
Dim faceLandmark As PXCMFaceAnalysis.Landmark = faceAnalysis.DynamicCast(Of PXCMFaceAnalysis.Landmark)(PXCMFaceAnalysis.Landmark.CUID)
Guarda il codice in VB.NET
2. Impostare le informazioni di profilo della stessa per recuperare il numero di punti landmark che ci interessano (ad esempio tutti e 7);
PXCMFaceAnalysis.Landmark.ProfileInfo landmarkProfile;
faceLandmark.QueryProfile(out landmarkProfile);
landmarkProfile.labels = PXCMFaceAnalysis.Landmark.Label.LABEL_7POINTS;
faceLandmark.SetProfile(ref landmarkProfile);
Dim landmarkProfile As PXCMFaceAnalysis.Landmark.ProfileInfo
faceLandmark.QueryProfile(landmarkProfile)
landmarkProfile.labels = PXCMFaceAnalysis.Landmark.Label.LABEL_7POINTS
faceLandmark.SetProfile(landmarkProfile)
Guarda il codice in VB.NET
3. Recuperare le informazioni dei landmark utilizzando il metodo QueryLandmarkData
della classe PXCMFaceAnalysis.Landmark
:
int landmarkSize = (int) (landmarkProfile.labels & PXCMFaceAnalysis.Landmark.Label.LABEL_SIZE_MASK);
PXCMFaceAnalysis.Landmark.LandmarkData[] landmarkData = new PXCMFaceAnalysis.Landmark.LandmarkData[landmarkSize];
if (faceLandmark.QueryLandmarkData(faceId, landmarkProfile.labels, landmarkData) == pxcmStatus.PXCM_STATUS_NO_ERROR)
form.DrawLandmark(landmarkData);
Dim landmarkSize As Integer = landmarkProfile.labels And PXCMFaceAnalysis.Landmark.Label.LABEL_SIZE_MASK
Dim landmarkData() = New PXCMFaceAnalysis.Landmark.LandmarkData(landmarkSize) {}
If faceLandmark.QueryLandmarkData(faceId, landmarkProfile.labels, landmarkData) = pxcmStatus.PXCM_STATUS_NO_ERROR Then
form.DrawLandmark(landmarkData)
End If
Guarda il codice in VB.NET
4. Recuperare le informazioni relative a pose utilizzando il metodo QueryPoseData della classe PXCMFaceAnalysis.Landmark:
PXCMFaceAnalysis.Landmark.PoseData poseData;
if (faceLandmark.QueryPoseData(faceId, out poseData) == pxcmStatus.PXCM_STATUS_NO_ERROR)
form.DrawPose(poseData);
Dim poseData As PXCMFaceAnalysis.Landmark.PoseData
If faceLandmark.QueryPoseData(faceId, poseData) = pxcmStatus.PXCM_STATUS_NO_ERROR Then
form.DrawPose(poseData)
End If
Guarda il codice in VB.NET
Osserviamo che l'istanza dela classe PXCMFaceAnalysis.Landmark
è ottenuta, ancora una volta, utilizzando il metodo DynamicCast
(come abbiamo già visto in precedenza per la classe PXCMFaceAnalysis.Detection
).
Le informazioni relative ai landmark sono contenute in un array di oggetti di tipo PXCMFaceAnalysis.Landmark.LandmarkData
. La struttura PXCMFaceAnalysis.Landmark.LandmarkData
espone, tra gli altri, i campi label
e position
che contengono, rispettivamente, l'identificazione del punto (ad esempio PXCMFaceAnalysis.Landmark.Label.LABEL_NOSE_TIP
per la punta del naso) e il punto dello spazio corrispondente (con coordinate x
, y
e z
).
Le coordinate x
e y
sono disponibili anche utilizzando una normale webcam, mentre la z
è disponibile solo se si utilizza una camera dotata di sensore di profondità coma la Creative Gesture Camera.
La struttura PXCMFaceAnalysis.Landmark.PoseData
contiene le informazioni relative ed espone le tre grandezze già descritte in precedenza.
Conclusioni
Intel Perceptual Computing è un ottimo strumento per poter realizzare applicazioni NUI senza doversi concentrare su quegli algoritmi percettivi la cui implementazione "di serie" fornita da Intel è già ottima.
D'altro canto, la sua modularità ne fa uno strumento che può adattarsi alle esigenze di chi tali algoritmi li ha già e vuole semplicemente farli lavorare in un aframework robusto e performante.
In questo articolo ci siamo limitati a dare un'occhiata alla sole funzionalità di Face Detector ma l'SDK mette a disposizione API per il Face Recognition, Text to Speech, Gesture Recognition e Speech Recognition.