2010-11-19 32 views
6

Quiero saber la frecuencia de los datos. Tenía una pequeña idea de que se puede hacer usando FFT, pero no estoy seguro de cómo hacerlo. Una vez que pasé todos los datos a FFT, me está dando 2 picos, pero ¿cómo puedo obtener la frecuencia?¿Cómo calcular la frecuencia de los datos usando FFT?

Gracias mucho por adelantado.

+0

FFT le dará la frecuencia de componentes sinusoidales de su señal. Si desea medir la frecuencia de la señal real (cualquier forma) de lo que debe olvidarse sobre FFT y usar escaneo de muestra para cruce por cero, o pico de búsqueda pico etc ... dependen bastante de la forma y el desplazamiento de su señal. Por cierto, en FFT tienes 2 peeks, uno es el espejo del primero si la señal de entrada está en el dominio real) así que ignora la segunda mitad de FFT – Spektre

Respuesta

-6

Frecuencia = velocidad/longitud de onda.

La longitud de onda es la distancia entre los dos picos.

+0

Dos picos en el dominio * frequency *. –

+0

Steve: No del todo. Si sus datos son realmente periódicos con un solo máximo, entonces la distancia entre los picos le dará exactamente 1/f. Sin embargo, generalmente se trata de datos semiperiódicos, para los cuales el análisis matemático estándar aplicado a los datos periódicos no funciona. –

+0

Lo que quise decir en mi comentario anterior fue que el autor ha obtenido dos picos en el dominio de la frecuencia. Esta respuesta interpreta incorrectamente dos picos para estar en el dominio del tiempo. –

8

Supongamos x[n] = cos(2*pi*f0*n/fs) donde f0 es la frecuencia de su sinusoide en Hertz, n=0:N-1, y fs es la tasa de muestreo de x en muestras por segundo.

Deje X = fft(x). Ambos x y X tienen longitud N. Supongamos que X tiene dos picos en n0 y N-n0.

Entonces la frecuencia sinusoidal es f0 = fs*n0/N Hertz.

Ejemplo: fs = 8000 muestras por segundo, N = 16000 muestras. Por lo tanto, x dura dos segundos.

Supongamos que X = fft(x) tiene picos en 2000 y 14000 (= 16000-2000). Por lo tanto, f0 = 8000 * 2000/16000 = 1000 Hz.

+0

Esto es correcto. Sin embargo, tenga en cuenta que a menudo los datos proporcionados por los algoritmos fft están desalineados debido al diseño fft (red mariposa). Tiene que ser cambiado primero antes de interpretar los valores. – ypnos

4

Si está viendo los resultados de magnitud de una FFT del tipo más común utilizado, entonces un componente de frecuencia sinusoidal fuerte de datos reales se mostrará en dos lugares, una vez en la mitad inferior, más su imagen de espejo conjugado complejo en la mitad superior. Esos dos picos representan el mismo pico espectral y la misma frecuencia (para datos estrictamente reales). Si los números del contenedor de resultados de FFT comienzan en 0 (cero), entonces la frecuencia del componente sinusoidal representado por el contenedor en la mitad inferior del resultado de FFT es más probable.

Frequency_of_Peak = Data_Sample_Rate * Bin_number_of_Peak/Length_of_FFT ; 

Asegúrese de resolver sus unidades adecuadas dentro de la ecuación anterior (para obtener unidades de ciclos por segundo, por quincena, por kiloparsec, etc.)

Tenga en cuenta que a menos que la longitud de onda de los datos es un exacto submúltiplo entero de la longitud de FFT, el pico real estará entre los contenedores, distribuyendo así la energía entre múltiples contenedores de resultados de FFT cercanos. Por lo tanto, puede que tenga que interpolar para estimar mejor el pico de frecuencia. Los métodos comunes de interpolación para encontrar una estimación de frecuencia más precisa son la convolución parabólica de 3 puntos y Sinc (que es casi lo mismo que usar una FFT de duración cero más larga).

6

Aquí es lo que usted está probablemente en busca de:

Cuando se habla de cálculo de la frecuencia de una señal, es probable que no está tan interesado en las ondas sinusoidales componentes. Esto es lo que la FFT te brinda. Por ejemplo, si sumas sin (2 * pi * 10x) + sin (2 * pi * 15x) + sin (2 * pi * 20x) + sin (2 * pi * 25x), es probable que desees detectar la "frecuencia" "como 5 (mire la gráfica de esta función). Sin embargo, la FFT de esta señal detectará la magnitud de para la frecuencia 5.

Lo que probablemente le interese más es periodicidad de la señal. Es decir, el intervalo en el que la señal se parece más a sí misma. Lo más probable es que lo que quiere es la autocorrelación . Búscalo. Esto esencialmente le dará una medida de cuán similar se parece a sí mismo la señal después de haber sido desplazada en una cierta cantidad. Entonces, si encuentra un pico en la autocorrelación, eso indicaría que la señal coincide bien con sí misma cuando se desplaza sobre esa cantidad. Hay una gran cantidad de matemáticas fresco detrás de ella, mira para arriba si usted está interesado, pero si sólo quiere que funcione, a hacer esto:

  1. ventana la señal, utilizando una ventana lisa (un coseno hará La ventana debe ser al menos dos veces más grande que el período más grande que desea detectar. 3 veces más grande dará mejores resultados. (Consulte http://zone.ni.com/devzone/cda/tut/p/id/4844 si está confundido).

  2. Tome FFT (sin embargo, asegúrese de que el tamaño de FFT sea dos veces más grande que la ventana, con la segunda mitad rellenada con ceros. Si el tamaño de FFT es solo del tamaño de la ventana, estará tomando la circular autocorrelación, que no es lo que quiere. ver https://en.wikipedia.org/wiki/Discrete_Fourier_transform#Circular_convolution_theorem_and_cross-correlation_theorem)

  3. Reemplazar todos los coeficientes de la FFT con su valor efectivo (real^2 + imag^2). Esto efectivamente está tomando la autocorrelación.

  4. Take IFFT

  5. Encuentre el pico más grande de IFFT. Esta es la periodicidad más fuerte de la forma de onda. En realidad, puede ser un poco más inteligente en el pico que elige, pero para la mayoría de los propósitos, esto debería ser suficiente. Para encontrar la frecuencia, simplemente toma f = 1/T.

+0

Gracias por la clara respuesta aquí, miré mucha información sobre este tema y esto me ayudó a aclarar un poco más. – Adamski

5

Si usted tiene una señal con una frecuencia (por ejemplo:

y = sin(2 pi f t) 

Con:

  • señal y el tiempo
  • f la frecuencia central
  • tiempo t

Luego obtendrá dos picos, uno a la frecuencia correspondiente a f, y uno a la frecuencia correspondiente a -f.

Por lo tanto, para obtener una frecuencia, puede descartar la parte de frecuencia negativa. Se encuentra después de la parte de frecuencia positiva. Además, el primer elemento del conjunto es un desplazamiento dc, por lo que la frecuencia es 0. (Tenga en cuenta que este desplazamiento suele ser mucho mayor que 0, por lo que los otros componentes de frecuencia pueden quedar enano).

En código : (lo he escrito en Python, pero debería ser igual de simple en C#):

import numpy as np 
from pylab import * 
x = np.random.rand(100) # create 100 random numbers of which we want the fourier transform 
x = x - mean(x) # make sure the average is zero, so we don't get a huge DC offset. 
dt = 0.1 #[s] 1/the sampling rate 
fftx = np.fft.fft(x) # the frequency transformed part 
# now discard anything that we do not need.. 
fftx = fftx[range(int(len(fftx)/2))] 
# now create the frequency axis: it runs from 0 to the sampling rate /2 
freq_fftx = np.linspace(0,2/dt,len(fftx)) 
# and plot a power spectrum 
plot(freq_fftx,abs(fftx)**2) 
show() 

Ahora la frecuencia se encuentra en el pico más grande.

+0

+1 para restar el promedio para dominar el desplazamiento de CC. En mi opinión, sería más claro si usa la frecuencia de muestreo para indexar la frecuencia y no el período de muestreo. –

+1

¡Agradable! Pero hay un error tipográfico en la respuesta: la línea de trama debe ser trama (freq_fftx, abs (fftx) ** 2) –

+0

¡Gracias! Arreglado. – Dirklinux

1

Suponiendo que usa una transformada discreta de Fourier para observar las frecuencias, debe tener cuidado con la forma de interpretar las frecuencias normalizadas en las físicas (es decir, Hz).

De acuerdo con la FFTW tutorial sobre cómo calcular el espectro de potencia de una señal:

#include <rfftw.h> 
... 
{ 
    fftw_real in[N], out[N], power_spectrum[N/2+1]; 
    rfftw_plan p; 
    int k; 
    ... 
    p = rfftw_create_plan(N, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE); 
    ... 
    rfftw_one(p, in, out); 
    power_spectrum[0] = out[0]*out[0]; /* DC component */ 
    for (k = 1; k < (N+1)/2; ++k) /* (k < N/2 rounded up) */ 
      power_spectrum[k] = out[k]*out[k] + out[N-k]*out[N-k]; 
    if (N % 2 == 0) /* N is even */ 
      power_spectrum[N/2] = out[N/2]*out[N/2]; /* Nyquist freq. */ 
    ... 
    rfftw_destroy_plan(p); 
} 

Nota Maneja longitudes de datos que no son siquiera. Tenga en cuenta especialmente si se da la longitud de los datos, FFTW le dará un "contenedor" correspondiente a la frecuencia de Nyquist (frecuencia de muestreo dividido por 2). De lo contrario, no lo obtiene (es decir, el último contenedor está justo debajo de Nyquist).

A MATLAB example es similar, pero que están eligiendo la longitud de 1000 (un número par) para el ejemplo:

N = length(x); 
xdft = fft(x); 
xdft = xdft(1:N/2+1); 
psdx = (1/(Fs*N)).*abs(xdft).^2; 
psdx(2:end-1) = 2*psdx(2:end-1); 
freq = 0:Fs/length(x):Fs/2; 

En general, puede ser la implementación (de la DFT) dependiente. Debería crear una onda sinusoidal pura de prueba a una frecuencia conocida y luego asegurarse de que el cálculo arroje el mismo número.

Cuestiones relacionadas