transformada rapida magnitud graficar fourier espectro ejemplos discreta matlab fft speech-recognition octave

matlab - magnitud - transformada rapida de fourier pdf



Obtener picos de FFT a partir de datos (2)

Puede usar la función findpeaks del paquete de señal de octava:

http://octave.sourceforge.net/signal/function/findpeaks.html

Estoy desarrollando un sistema de reconocimiento de voz desde cero usando Octave. Estoy tratando de detectar fonemas al detectar diferencias en la frecuencia. Actualmente he leído en un archivo wav, organizado los valores en bloques y aplicado fft a los datos generales. Después, trazo los nuevos datos con plot(abs(real(fft(q)))) que crea este gráfico:

¿Cómo podría obtener los valores de frecuencia (los picos del gráfico)?


Si no tiene acceso a findpeaks , la premisa básica detrás de cómo funciona es que para cada punto de su señal, busca una ventana de tres elementos centrada en este punto y verifica si el centro de esta ventana es más grande que el elemento izquierdo y derecho de esta ventana. Desea poder encontrar picos positivos y negativos, por lo que deberá verificar el valor absoluto.

Como tal, lo que puede hacer es hacer dos señales adicionales que desplacen la señal a la izquierda en 1 y a la derecha en 1. Cuando hacemos esto, en realidad estaremos verificando los picos que comienzan en el segundo elemento de su señal, en para dejar espacio para mirar a la izquierda. Seguimos revisando hasta el segundo último elemento , para dejar espacio para mirar a la derecha. Por lo tanto, en realidad estaremos buscando picos en una versión N - 2 de la señal donde N es la longitud de su señal. Por lo tanto, cuando creamos la señal desplazada hacia la izquierda, extraemos el primer elemento de la señal hasta el tercer último elemento . Cuando creamos la señal desplazada hacia la derecha, extraemos del tercer elemento hasta el último elemento. La señal original simplemente tendrá sus primeros y últimos elementos eliminados.

Por lo tanto, al verificar los picos de esta manera, perderemos el primer y último punto de sus datos, pero eso debería ser adecuado, ya que lo más probable es que no haya picos al principio y al final. Después de crear todas estas señales, simplemente use la indexación lógica para ver si los valores correspondientes en la señal original (sin el primer y el último elemento) son mayores que las otras dos señales en sus posiciones correspondientes.

Como tal, suponiendo que su señal se haya almacenado en f , haría lo siguiente:

f1 = abs(f(2:end-1)); %// Original signal f2 = abs(f(1:end-2)); %// Left shift f3 = abs(f(3:end)); %// Right shift idx = find(f1 > f2 & f1 > f3) + 1; %// Get the locations of where we find our peaks

idx contendrá las ubicaciones de índice de donde ocurren los picos. Tenga en cuenta que comenzamos a buscar picos en la segunda posición, por lo que debe agregar 1 para acomodar este cambio. Si quisiera encontrar los valores de tiempo real (o frecuencia en su caso), simplemente usaría idx para indexar en la matriz de tiempo (o frecuencia) que se utilizó para generar su señal y encontrarlos. Como tal, usemos un caso artificial donde genero una sinusoide de 0 a 3 segundos con una frecuencia de 1 Hz. Por lo tanto:

t = 0 : 0.01 : 3; f = sin(2*pi*t);

Ahora, si ejecutamos el código anterior con esta señal, encontraríamos la ubicación de nuestros picos. Luego podemos usar estas ubicaciones para indexar en t y f y graficar la señal, así como dónde hemos detectado nuestros picos. Por lo tanto:

plot(t, f, t(idx), f(idx), ''r.'')

Esto es lo que obtengo:

Tenga en cuenta que esta es una forma muy simple de detectar picos, pero eso es lo que se hace esencialmente en findpeaks . Si utilizó el código anterior, básicamente encontraría todos los picos . Como tal, el código encontraría docenas de picos en el gráfico anterior, porque hay máximos locales en todo su espectro. Probablemente desee determinar dónde se encuentran los picos fuertes . Lo que la gente suele hacer es usar un umbral para indicar qué tan grande debe ser el pico antes de decidir si es un pico válido. Como tal, puede imponer un umbral y hacer algo como esto:

thresh = ... ; %// Define threshold here idx = find(f1 > f2 & f1 > f3 & f1 > thresh) + 1; %// Get the locations of where we find our peaks

En su caso para su gráfico, es posible que desee establecer esto para que encuentre picos cuya magnitud sea mayor que 10 tal vez.

Hay muchas otras cosas que hace findpeaks , como filtrar picos ruidosos y algunas otras medidas robustas. Si desea utilizar findpeaks , debe asegurarse de instalar el paquete de señal. Simplemente puede usar pkg install desde el símbolo del sistema de octava e instalar el paquete de signal . Específicamente, intente esto:

pkg install -forge signal

Una vez que instale el paquete de signal , puede cargarlo en el entorno de Octave haciendo:

pkg load signal

Si tiene que instalar dependencias, le indicará cuándo intenta instalar el paquete de signal . Consulte este enlace para obtener más detalles: https://www.gnu.org/software/octave/doc/interpreter/Installing-and-Removing-Packages.html

mkoctfile significa hacer / compilar un archivo Octave. Si no tiene mkoctfile , asegúrese de tener instalada la versión más reciente de Octave. Lo que le recomiendo que haga para simplificar las cosas es instalar Homebrew o MacPorts y obtener Octave de esa manera. Una vez que lo instale, debería poder hacer que mkoctfile funcione. Sin embargo, si aún no puede, es posible que necesite tener un compilador compatible instalado. El enfoque fácil es instalar las herramientas de desarrollo de línea de comandos desde Xcode. Vaya a este enlace y luego vaya a Herramientas adicionales.

¡Buena suerte!