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!