Recuperare dati da stringa

martedì 06 luglio 2010 - 12.09

atsap Profilo | Newbie

Saluti a tutti i dotnettisti!
Sto facendo un weekend project che prevede il riconoscimento vocale. Sto usando le librerie System.speech e funziona tutto, l'unica cosa è questa:

Diciamo di avere tre trackbar. Se dico "Trackbar 1" questa viene impostata al suo valore massimo (lo stesso per le altre due trackbar). Ma... se volessi invece spostare la trackbar al 50%? Come dovrei operare?
Il risultato del riconoscimento finisce in una stringa. Si tratterebbe quindi di estrarre da questa stringa delle parole chiave, tipo "trackbar1", "numero", "percento", seguendo una frase del tipo "Attiva la trackbar1 al 70%".

Questo è il codice:
private void AnalyzeText(RecognitionResult res) { //Ottiene il testo, ossia la parola pronunciata string Text = res.Text; { MessageBox.Show("Ricevuto " + Text); if (Text == "trackbar1") { trackBar1.Value = 120; } else if (Text == "trackbar2") { trackBar2.Value = 120; } } // e via dicendo
Aggiungo che le parole sono inserite in un dizionario, per cui se la parola pronunciata non viene riconosciuta, non c'è problema, viene semplicemente ignorata.
Spero di essere stato chiaro!

Grazie!

luigidibiasi Profilo | Guru

Supponendo che le parole siano separate da spazi puoi usare il metodo Split di string per separare tutte le parole...

da li, poi, devi analizzare il contenuto dell'array che ti ritorna per determinare il comando da eseguire.

In linea di massima credo tu debba fissare bene la struttura dei vari comandi:

ad esempio:
[aumenta] =>([oggetto], [valore])

però devi far riferimento a nozioni di IA o qualcosa del genere per effettuare un'analisi complessa del contenuto della stringa....




Luigi Di Biasi
http://blogs.dotnethell.it/luigidibiasi/
http://www.dibiasi.it/

atsap Profilo | Newbie

Hey ma io ti conosco! :-D
Sono il tipo del progetto con webcam (directshow, ricordi?)! Solo che non mi hai più risposto... :)

Bene per il metodo split. In effetti il problema è che i numeri, ad esempio, vengono interpretati come "one", "two", "three" e via dicendo. Per cui, bisogna creare un dizionario apposta con un motore che gestisca le corrispondenze tra valore letterale e valore numerico. Ci sarebbe IsNumber... e mi sarebbe d'aiuto. Solo che non mi è molto chiara la logica di interpretazione... e sulla guida non c'è molto, purtroppo. Tra l'altro il riconoscimento è sensibilissimo: La frase "You have selected Microsoft Mike as the computer default voice" diventa "you have to lie to die totals off to the idea that and the owners default volley" :-D

luigidibiasi Profilo | Guru

>Hey ma io ti conosco! :-D
>Sono il tipo del progetto con webcam (directshow, ricordi?)!
>Solo che non mi hai più risposto... :)
cavolo non avrò letto una tua successiva e-mail .... scusami :X
cmq quando ho letto (weekend-project) ammetto di aver pensato a te :D

>
>Bene per il metodo split. In effetti il problema è che i numeri,
>ad esempio, vengono interpretati come "one", "two", "three" e
>via dicendo. Per cui, bisogna creare un dizionario apposta con
>un motore che gestisca le corrispondenze tra valore letterale
>e valore numerico. Ci sarebbe IsNumber... e mi sarebbe d'aiuto.
non conosco le api speech ma forse, cercando, trovi il modo di configurarle in modo da farti restituire i numeri "in formato numerico"...

>Solo che non mi è molto chiara la logica di interpretazione...
>e sulla guida non c'è molto, purtroppo. Tra l'altro il riconoscimento
>è sensibilissimo: La frase "You have selected Microsoft Mike
>as the computer default voice" diventa "you have to lie to die
>totals off to the idea that and the owners default volley" :-D
quale guida stai utilizzando?
Luigi Di Biasi
http://blogs.dotnethell.it/luigidibiasi/
http://www.dibiasi.it/

atsap Profilo | Newbie

Figurati, non c'è problema. :)

Può essere che ci sia qualche metodo che "scriva" i numeri in formato, appunto, numerico. Ma quello diciamo che è il minore dei problemi... quello più grosso è prendere la stringa, dividerla ed interpretarla! Diciamo, ad esempio, così: "Aumenta trackbar1 di 100 punti". Ora: ammesso che il riconoscimento sia andato a buon fine, ovvero che abbia effettivamente recepito perfettamente quanto ho detto, avrei esattamente quella stringa. Dovrei muovermi così, tipo:

//PseudoCodice if stringaRecepita.Contains("aumenta") { if stringaRecepita.Contains("trackbar1") { if stringaRecepita.Contains(aNumber) { trackbar1.aggiungi(aNumber); } } else if stringaRecepita.contains("trackbar2") { if stringaRecepita.Contains(aNumber) { trackbar2.aggiungi(aNumber); } //////e via dicendo }

mi chiedo: esiste un metodo simile a quello che ho scritto su (stringaRecepita.contains("qualcosa"))?
Mi pare un po' troppo complicata la gestione a livello algoritmico...

luigidibiasi Profilo | Guru

Non vorrei sembrare pessimista ma se non decidi in anticipo il formato dei comandi che andrai ad impartire (magari più formati per lo stesso comando così rendi più flessibile il riconoscimento) vai ad entrare nel problema dell'analisi e comprensione del linguaggio naturale.

Stasera cerco se trovo qualche algoritmo per lo scopo e lo posto.

Comunque in linea di massima potresti procedere così:

- scrivi una function per ogni comando che farai gestire del tipo:

function _incrementa(valore,oggetto) {};
function _decrementa(valore,oggetto) {};
function _comandoX(parametri) {};

poi potresti fare una cosa del tipo:

frase[] = stringa.split(" ");
cerchi negli elementi frase[i] un valore che corrisponda ad un comando
se lo trovi ancora in frase[i] cerchi il nome dell'oggetto sul quale fare applicare il comando
infine escludendo i due parametri trovati prima cerchi in frase[i] il valore
ignori tutto il resto in frase[i]

però mi sembra proprio brutta come soluzione.... :(



Luigi Di Biasi
http://blogs.dotnethell.it/luigidibiasi/
http://www.dibiasi.it/

atsap Profilo | Newbie

Brutta o bella l'importante è che funzioni! :)
Forse è troppo macchinosa.
Io ho fatto così:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Diciamo che come logica può andare. Qual'è il problema ora? Semplice! Se la stringa è stata splittata, il secondo if (quello nell'else) non si verificherà mai, in quanto la stringa non può essere contemporaneamente una parola e un numero. Questo perché il foreach divide la stringa in parole singole, per cui nello stesso momento è impossibile che "Text" assuma due valori diversi. Qualche idea?

*****Aggiorno:***** mi rispondo da solo. In realtà, il secondo if non serve. Basta settare il valore della trackBar2 a numeroContenuto, stop. Così va. L'unica cosa è che effettivamente alcuni numeri vengono "tradotti" esattamente come numeri, altri invece (le centinaia, ad esempio) come forma letterale: 15 diventa fifteen, 200 come 2 hundred. Argh! Questo è il vero scoglio...
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5