Scrivere il mio codice di riconoscimento vocale [chiuso]

17

Descrizione del problema

Desidero utilizzare il riconoscimento vocale come parte di un progetto hardware, che mi piacerebbe essere completamente autonomo (uso piccoli dispositivi a bassa potenza e bassa velocità come Arduino e Raspberry Pi, Kinectet ecc. è coinvolto un computer tradizionale con un sistema operativo, quindi un progetto chiuso / auto contenente).

Il riconoscimento vocale può essere molto complicato a seconda del livello di sofisticazione desiderato. Ho quello che credo un insieme relativamente semplice di requisiti. Voglio solo riconoscere la mia voce e ho un piccolo dizionario di circa 20 parole che vorrei riconoscere. Quindi non ho bisogno di complesse librerie di riconoscimento vocale e di testo o di uno qualsiasi degli eccellenti software di terze parti che trovo tramite i motori di ricerca di Internet (non mancano questi!). Credo che i miei requisiti siano "abbastanza semplici" (entro limiti ragionevoli) da poter codificare la mia soluzione. Mi chiedo se qualcuno ha scritto il proprio processo in questo modo, e il mio metodo è gravemente imperfetto? C'è un modo migliore per farlo senza richiedere un alto livello di matematica o dover scrivere un algoritmo complesso? Questa è la soluzione che ho cercato di pensare in basso.

Descrizione della soluzione

Scriverò questo in C ma desidero discutere un processo agnostico linguistico, concentrandomi sul processo stesso. Quindi lascia che se lo possiamo ignorare.

1. Pre-registrerò il mio dizionario di parole in modo che corrisponda a quelli che vengono pronunciati. Possiamo immaginare di avere 20 registrazioni delle mie 20 parole diverse, o forse brevi frasi o frasi di due o tre parole. Credo che questo faciliti il processo di confronto tra due file di registrazione piuttosto che la conversione dell'audio in testo e il confronto di due stringhe.

2. Un microfono è collegato al mio dispositivo hardware che esegue il mio codice. [1]. Il codice prende continuamente campioni di lunghezza fissa, ad esempio 10msec di lunghezza per esempio, e memorizza 10 campioni consecutivi, ad esempio, in uno stile di registrazione circolare. [2]. (Sto inventando queste figure in cima alla mia testa, quindi sono solo degli esempi per descrivere il processo).

[1] Questo probabilmente verrebbe collegato tramite un filtro passa-banda e un amplificatore operazionale, così come le registrazioni del dizionario, per mantenere i campioni audio archiviati e raccolti più piccoli.

[2] Non sono sicuro di come prenderò un campione, ho bisogno di elaborare un metodo anche se producessi una figura numerica (integer / float / double) che rappresenta l'audio di un 10msec campione (forse un valore CRC o somma MD5 ecc. del campione audio), o un flusso di figure (forse un flusso di letture audio di frequenze). In definitiva un "campione" sarà una cifra o una cifra numerica. Questa parte sarà molto più coinvolta dall'hardware, quindi non è molto utile per la discussione qui.

3. Il codice esamina i 10 campioni consecutivi memorizzati e cerca un aumento di volume per indicare che una parola o una frase viene detta (una pausa dal silenzio) e quindi aumenta il campionamento consecutivo in ad esempio 500 campioni. Ciò significherebbe catturare 5 secondi di audio in campioni da 10 msec.

Sono questi campioni o "fette" che vengono confrontati tra il suono memorizzato e il suono catturato. Se una percentuale sufficientemente alta di campioni catturati corrisponde a quelli memorizzati equivalenti, il codice assume la stessa parola.

The start of a store recording of the world "hello" for example,
stored words are split into 10 msec samples also

Stored Sample No           | 1| 2| 3| 4| 5| 6| 7|  8|
Stored Sample Value        |27|38|41|16|59|77|200|78|

Incoming audio (me saying "hello") with some "blank" samples
at the start to symbolise silence

Incoming Sample No         | 1| 2| 3| 4| 5| 6| 7| 8| 9|10| 11|12|
Incoming Sample Value      |  |  |  |20|27|38|46|16|59|77|200|78|

4. Una volta che il codice ha raccolto un flusso di esempio completo, ritaglia i campioni degli spazi vuoti all'inizio per produrre la seguente registrazione audio. Potrebbe anche spostare il campione in avanti e indietro di alcuni punti per allinearlo meglio con il campione memorizzato.

Questo produce un campionamento come il seguente:

Stored Sample No           | 1| 2| 3| 4| 5| 6|  7| 8|
Stored Sample Value        |27|38|41|16|59|77|200|78|

Incoming Sample No      |-1| 1| 2| 3| 4| 5| 6|  7| 8|
Incoming Sample Value   |20|27|38|46|16|59|81|201|78|

5. Credo che avendo un valore percentuale per quanto deve essere chiuso ogni campione, quindi il campione 7 differisce di un valore di 1 che è inferiore a% 1 e un valore percentuale per il numero totale di campioni che devono rientrare nella percentuale di corrispondenza del campione, il codice ha un livello di precisione facilmente sintonizzabile.

Non ho mai fatto nulla di simile con l'audio prima, potrebbe essere molto lavoro. Questo è il motivo per cui ti sto ponendo questa domanda, se forse già sai che la risposta a questa domanda è ovvia (quale possa mai essere questa risposta). Spero che questo non sia un compito computazionalmente impegnativo in quanto parte dell'hardware che userò sarà materiale di bassa qualità. Nelle centinaia di Megahertz (Forse 1 GHz usando un Rasp Pi oltrepassato). Quindi questo è un modo piuttosto crudo per abbinare campioni audio usando una potenza di calcolo inferiore. Non sto puntando a risultati immediati, ma a meno di 30 secondi per una dimostrazione del concetto decente.

PS Non ho il rappresentante per taggare questo con un nuovo tag come "audio", "riconoscimento audio", "voce", "riconoscimento vocale" ecc.

    
posta jwbensley 12.08.2013 - 02:12
fonte

2 risposte

3

Beh, non credo che l'Arduino abbia il potere del cavallo per farlo. è operativo a 16Mhz Un Arduino ha circa 32K di memoria. Anche 20 parole campionate in Mp3 (più piccole di quelle wav) non si adattano a questo, nonostante sia solo la tua stessa voce.

Il rasberi pi potrebbe fare il trucco, funziona a 700Mhz a seconda della versione che potrebbe avere una memoria di 512 MB. Non è ancora un sacco di pasta.

Potresti aver bisogno di un fourier ( link )

O se intendi usare il volume, fai qualche media con esempi precedenti come
x = (x + x [n-1] + x [n-2] + x [n-3]) / 4 // questo è abbastanza semplice potrebbe aver bisogno di più

Una prossima cosa che devi fare è che penso che dovresti tracciare questi valori X. Allora hai bisogno di una sorta di rilevamento della pendenza di quella linea Perché il rilevamento di comandi basati sul volume dipende altrimenti molto dalla distanza Mentre preferisci rilevare lo schema delle parole

Quindi dipende un po 'come registrare la pendenza in modo che il pattern si adatti ad un'altra volta. Intendo dire che non si parla nel tempo esatto che un computer può eguagliare e la pendenza può essere un po 'più ripida. Alla fine penso che questo sia un po 'ripido quanto quelle linee sono e la loro lunghezza y asse, dovrebbe essere all'interno di una media

    
risposta data 27.08.2013 - 09:39
fonte
1
  1. Arduino e Raspberry Pi sono prototipi di schede con pochi chip su di loro. Dovresti concentrarti prima sul chip. Cerca qualcosa con una toolbox DSP (elaborazione del segnale digitale), forse hai già una cassetta degli attrezzi DSP e non la conosci. Gli strumenti DSP dispongono di algoritmi su chiamata come fft (trasformata veloce di Fourier) e ifft (inversa fft) per l'analisi del dominio di frequenza veloce.

  2. Concentrati sul tuo stile programmatico: I tuoi campioni sono in pila o in coda? Vorresti una coda per questo tipo di dati. Sembra una coda:

    Position NO --|1|2|3|4|5|6|7|8|
    Sample Value  |5|7|9|1|2|2|9|8|
    

    Prossima iterazione:

    Position NO --|1|2|3|4|5|6|7|8|
    Sample Value  |0|5|7|9|1|2|2|9|
    ->  First in First out (FIFO)
    

    Nota come le cose si spostano verso il "giusto"? Penso che tu abbia descritto un algoritmo "circolare". Basta sovrascrivere i campioni più vecchi con i secondi campioni più vecchi, quindi sovrascrivere i secondi campioni più vecchi con il terzo più vecchio, ..., fino all'inizio della coda in cui inserisci i tuoi dati più recenti.

  3. "Il codice acquisisce continuamente campioni di lunghezza fissa, ad esempio 10msec" < - errati Pensa in questo modo: il codice preleva in modo discreto campioni quantizzati (altezza), ad una frequenza di campionamento di 10000 campioni al secondo, il che rende ogni campione a 0,1 ms di distanza.

    Qual è la tua frequenza di campionamento? Qual è il bitrate sul tuo quantizzatore? Numeri più bassi ti aiuteranno a liberare memoria. Suggerirei una bassa frequenza di campionamento come 6600 campioni al secondo (Nyquist). Sospetto che 4 bit (16 livelli) siano sufficienti per il riconoscimento. Quindi sono 3300 byte di registrazione al secondo. Ora fai fft e cancella tutto sopra 3300 Hz (filtro di telefonia). Ora hai 1650 byte usati per un secondo di suono. Questi trucchi DSP faranno risparmiare molta memoria.

    Non so chi pensi che 512 MB siano piccoli. Con le informazioni di cui sopra che sono più di 300.000 secondi di registrazione ... su 3 giorni solidi.

  4. Penso che troverai il dominio della frequenza (usando fft) per essere un ambiente migliore per eseguire il riconoscimento vocale.

Spero di non averti confuso di peggio:)

    
risposta data 18.01.2015 - 03:28
fonte

Leggi altre domande sui tag