martes, mayo 15, 2012

Reconocimiento de voz con AVR de 8 bits


Desde hace unas semanas estoy trabajando en un experimento que espero se convierta en proyecto.

El objetivo es dotar del poder del entendimiento del habla a un robot que estoy armando, muy lentamente, con microcontroladores AVR de gama baja (ATMega8/16/128).

Estos micros poseen entre 0.5KB a 4KB de Memoria SRAM y entre 8KB a 128KB de Flash corriendo de unos pocos Mhz, el reconocimiento del habla típico en PCs requiere de una cantidad de memoria considerable y de una velocidad de proceso de varios GHz.

Debido a estas restricciones me limitaré a reconocer una x cantidad de comandos de voz, como podrían ser "Avanzar", "Retroceder", etc, o bien dígitos, "1", "2", etc.

Bien, comienzo esta locura de experimento y espero llegar a algo.. :D

La voz humana


La voz de una persona se emite en un rango de frecuencias entre 60Hz a 7000Hz, sin embargo podemos considerar que las frecuencias más usuales están entre los 120Hz a 2000Hz. Para capturar este  espectro de frecuencia por la teoría de Nyquist se debe hacer muestras a por lo menos el doble de rápido que la frecuencia más alta de la señal, por lo que nos da unos 4000 muestras por segundo.

El éxito de este experimento estará en lograr esas 4000 muestras/segundo con un uC a, digamos, 16Mhz.

Bueno lo primero que hice fue abordar el problema por partes, he aquí la primera parte, la analógica.

Filtro de frecuencias
Implementé esto en la protoboard, digamos que se trata de un amplificador operacional cuádruple (LM324N) con un filtro pasa alta a la entrada y un pasa bajos a la salida.


Alimenté el circuito con 5v y me puse a disfrutar como bailaba la gráfica en el osciloscopio mientras pensaba como digitalizar esa importante cantidad de información analógica, entonces activé la función Math del osciloscopio, puse FFT y salió esto:

Aquí digo "UNO"

Y aquí "DOS"

En la web encontré una implementación de la FFT (Transformada Rápida de Fourier) escrita por ChaN.

Y hasta aquí llegué por ahora, voy a probar la biblioteca de FFT e intentaré capturar/procesar los valores del ADC, si lo logro el paso siguiente será determinar el comando dictado, ahí el truco estará en hacerlo por correlación (estadística), alguna red neuronal, o ... ya se verá..

18/05/2012 - Captura y procesamiento de ADC

Realicé una prueba sencilla conectando la salida de audio a la entrada ADC0 de un ATmega8A ejecutandose a 16Mhz, con una referencia de voltaje de 5v y enviando datos de captura por puerto serie a la pc.
La velocidad del AVR es más que suficiente para cubrir con la tarea del sampleado, la biblioteca FFT en uso a 64 puntos(muestras) permite un throughput de hasta 19kbps con un tiempo de procesamiento de 3.4ms.
Estos 64 puntos los sumé en un vector de 32 bytes (la mitad útil del resultado de la FFT), la suma la realizo 20 veces y envío el vector de sumas por puerto serie.
Desde la PC tiré los valores a una planilla de cálculo con un gráfico simple que muestra el espectro de audio (de las sumas en realidad).
Capturé los valores de diferentes palabras y estos son los gráficos resultantes, los colores que corresponden a cada uno de los conjuntos obtenidos son:

UNO

DOS

ADELANTE

RETROCEDER



Nota: Aunque la línea azul (dato 1) parezca similar en algunas gráficas, es muy diferente (ver la escala del eje y).

Para hacer el código de la correlación usando tipos de datos flotantes el ATmega8 me queda corto de memoria, voy a tener que armar una plaquita para un ATmega16/32 o 128.

Como pensaba el reconocimiento es totalmente factible utilizando una correlación estadística o una red neuronal.


23/05/2012 - Prueba 001 - Clasificación por distancia

La prueba fue relativamente exitosa (~70% de acierto), como se puede ver en este video:
Lo que está funcionando es un muestreo a 7800Hz, recolectando 16 muestras del espectro (salida del FFT) y su respectiva comparación por distancia con respecto a un patrón almacenado en la flash (atributo PROGMEM en AVR). Como se puede ver depende mucho del tono, duración de la palabra, ruido, etc, estos factores son los que espero mejorar con el algoritmo de redes neuronales del modelo oculto de Markov.


Continuará...