Abstract
In questo post andremo a vedere come utilizzare la Real Sense F200-Front Facing Camera ed il Real Sense SDK 2014 per realizzare una applicazione di ‘voice recognition’.
Short Introduction
Intel RealSense è una tecnologia, un mix fra hardware e software, che permette di trasformare radicalmente il modo in cui gli utenti possono interagire con i device ed il mondo circostante.
Il cuore di RealSense e’ certamente la videocamera RGB 1080p che oltre ad una eccezionale resa video consente di misurare con estrema precisione le distanze degli oggetti ripresi (nel range 0,2-1,2 metri nel caso del modello F200), aprendo a modelli di interazione uomo macchina solo immaginabili senza un dispositivo di questo tipo.
Intel RealSense SDK è invece la ibreria che consente di interagire con la camera ed utilizzarne le potenzialità oltre a contenere un elevato numero di esempi ed applicazioni (in C# e C++) che danno ampia dimostrazione di impieghi avanzati di questa tecnologia.
Grazie all’SDK si ha la possibilità di accedere direttamente ai dati provenienti dai sensori della camera oppure di basare le nostre applicazioni su algoritmi sofisticati (e quasi incredibili) quali hand tracking, facial analysis, voice recognition e molto altro ancora.
Ad oggi il kit di sviluppo è disponibile solo per Windows 8.1 OS 64-bit, ma presto è prevista l’uscita anche della versione per Windows 8.1 New UI e per Android.
Certamente la possibilità di misurare con RealSense le distanze di oggetti reali posti di fronte alla videocamera e’ una delle caratteristiche piu’ appassionanti di questa tecnologia ma parlando di interazione naturale una feature di sicuro interessante ma su cui non si focalizza abbastanza e’ a mio avviso anche la possibilità di utilizzare RealSense per la voice recognition. L’analisi vocale e’ resa possibile dal fatto che la F200 è equipaggiata da un sistema di acquisizione audio di alta qualità e che la SDK mette a disposizione algoritmi efficientissimi in questo campo.
Di seguito andremo a parlare proprio di come utilizzare l’SDK per il riconoscimento di comandi vocali; in particolare vedremo come utilizzare il modulo “Speech Recognition and Synthesis” di RealSense SDK che contiene gli algoritmi per il riconoscimento dei comandi vocali, oltre a quelli per la dettatura e la sintesi vocale.
L’esempio presentato sotto e’ scritto utilizzando il linguaggio C++ (su Windows 8.1 a 64-bit, Visual Studio 2012 e con la cam F200-Front Facing) ed e’ parte di un piu’ largo progetto di un sistema che permette a persone disabili (tetraplegiche nel caso d’uso considerato) di controllare mouse e tastiera del proprio computer con il solo ausilio della RealSense (head tracking, facial expressions e voice commands).
Programming details
L’utilizzo della feature per il riconoscimento dei comandi vocali passa da 4 passi:
- creazione di una sessione, i.e. l’oggettto che consentira’ di comunicare con la sdk e l’hardware;
- caricamento del modulo di riconoscimento vocale e configurazione;
- definizione di un vocabolario personalizzato e sua importazione;
- impostazione degli event handler;
- starting del riconoscimento.
Creazione della sessione
Analogamente a quanto e’ necessario fare ogni volta si voglia interagire con RealSense deve essere creato un oggetto di tipo PXCSession.
PXCSession *session = PXCSession::CreateInstance(); if (session == NULL) { //Errore }
definita in "pxcsession.h".
Creazione di una istanza del modulo di SpeechRecognition e configurazione
PXCSpeechRecognition* g_vrec=0; sts=session->CreateImpl<PXCSpeechRecognition>(&g_vrec); if (sts<PXC_STATUS_NO_ERROR) { //Errore } PXCSpeechRecognition::ProfileInfo pinfo; g_vrec->QueryProfile(0,&pinfo); //Config ... sts = g_vrec->SetProfile(&pinfo); if (sts != pxcStatus::PXC_STATUS_NO_ERROR) { //Errore }
Definizione del vocabolario
Il vocabolario delle parole che la Intel RealSense dovrà riconoscere, deve essere definito all’interno di un file JSpeech Grammar Format (con estensione .jsgf).
L’esempio più semplice di questo tipo di file può essere il seguente:
#JSGF v1.0 grammar Saluto public <Saluto> = Salve | Buongiorno | Buon Pomeriggio | Ciao ;
Che istruisce il sistema a riconoscere 4 espressioni di saluto e solo nel caso che riconosca una di questa chiamare l’opportuno handler.
Le istruzioni da utilizzare per far si che il file sia utilizzato per il riconoscimento vocale dalla RealSense sono:
pxcStatus sts = g_vrec->BuildGrammarFromFile(grammar, PXCSpeechRecognition::GFT_NONE, GrammarFilename); if (sts < PXC_STATUS_NO_ERROR) { //Errore } sts = g_vrec->SetGrammar(grammar); if (sts != PXC_STATUS_NO_ERROR) { //Errore }
dove GrammarFilename è il nome del file che, nella nostra esperienza e’ comodo mantenere nella solita directory dell’eseguibile, e.g. con il medesimo nome ma estensione cambiata:
DWORD l = GetModuleFileNameW(hModule, path, MAX_PATH); path[l - 4] = '\0'; WCHAR grammarFile[MAX_PATH + 1]; std::swprintf(grammarFilename, L"%s.jsgf", path);
Infine per attivare la modalita’ di riconoscimento e’ necessario eseguire la seguente funzione
sts = sr->SetDictation(); if (sts != pxcStatus::PXC_STATUS_NO_ERROR) { //Errore }
Nonostante per il riconoscimento di semplici comandi il file jsgf presentato sia piu’ che sufficiente, il JSpeech Grammar Format, che e’ anche uno standard W3C (http://www.w3.org/TR/jsgf/), permette di definire grammatiche anche estremamente più complesse che possono permettere alla RealSense di comprendere frasi ed espressioni sofisticate.
Starting del riconoscimento
Per far si che il riconoscimento abbia inizio va richiamata la funzione
sts = sr->StartRec(g_source, g_handler); if (sts != pxcStatus::PXC_STATUS_NO_ERROR) { //Errore }
dove g_source è un puntatore ad una struttura PXCAudioSource che definisce la sorgente audio e g_handler è la classe handle che verrà utilizzata per notificare il riconoscimento di una comandi definiti nel vocabolario o eventuali altre condizioni importanti circa la detection, ad esempio:
class TrivialHandler: public PXCSpeechRecognition::Handler { public: virtual void PXCAPI OnRecognition(const PXCSpeechRecognition::RecognitionData *data) { //data contiene il risultato della recognition } virtual void PXCAPI OnAlert(const PXCSpeechRecognition::AlertData *data) { if(data->label == PXCSpeechRecognition::ALERT_SPEECH_BEGIN) { //... } else if (data->label ==PXCSpeechRecognition::ALERT_SPEECH_END){ //... } };
Quando si intende terminare il riconoscimento audio va chiamata la funzione:
sts = sr->StopRec();
dove come di consueto se sts != pxcStatus::PXC_STATUS_NO_ERRORsi e’ verificato un errore nella procedura.
Notiamo anche che nella fase di impostazione del riconoscimento audio, va anche specificata la lingua (che dovrà essere installata ed importata in precedenza) che si intende utilizzare.