Está en la página 1de 10

14/7/2020 Lab_Clase11_part1.

ipynb - Colaboratory

Transformada de Fourier

Transformada de Fourier para señales discretas


La transformada discreta Fourier para la señal x[n] se de ne de acuerdo con la siguiente
ecuación.
N −1 N −1
−j⋅2πk⋅n

X[k] = ∑ x[n] ⋅ e N = ∑ x[n] ⋅ U[k, n]

n=0 n=0

Donde U ∈ R
N ×K
representa una matriz de transformación, que se puede de nir con la
siguiente ecuación.
1 j ⋅ 2πk ⋅ n
U = [exp( )]


√N N
n∈{0,N −1},k∈0,N F F T

Donde N es el número de muestras de la señal, y NFFT es el número de puntos de la


transformada de Fourier que se desea calcular (debe ser una potencia de 2).

El número de puntos de la transformada de Fourier de ne la resolución en frecuencia, donde


cada índice mapea el contenido de frecuencia de la señal en un rango normalizado entre 0 y 2π
rad/seg. Cada índice también mapea la frecuencia de muestreo entre 0 y f s , por lo tanto, para
encontrar la equivalencia entre la frecuencia normalizada, y la frecuencia en Hz, se debe
multiplicar la frecuencia normalizada por (f s/2).

Luego de de nir la matriz, se puede rede nir la transformada de Fourier como una
multiplicación de una matriz y un vector (columna).

X = U ⋅ x

import numpy as np
import matplotlib.pyplot as plt

La siguiente función construye la matriz 𝐔 de transformación.

def dftmatrix(N, Nfft):


#construct DFT matrix
k= np.arange(Nfft)
if N is None: N = Nfft
n = np.arange(N)
U = np.matrix(np.exp(1j* 2*np.pi/Nfft *k*n[:,None]))
return U/np.sqrt(Nfft)

Para calcular la transformada de Fourier de la señal 𝑥[𝑛] se usa la siguiente expresión: 𝑋=𝑈.𝐻∗𝐱
#donde U.H signi ca el complejo conjugado de la matriz 𝐔
https://colab.research.google.com/drive/14GmyEZRA4BX5x145piIvxgKRdn2FrLr6?authuser=1#scrollTo=K49aU4NVzBBh&printMode=true 1/10
14/7/2020 Lab_Clase11_part1.ipynb - Colaboratory

Calcular la frecuencia de una señal sinusoidal

Se va a generar una señal sinusoidal con una frecuencia de 330 Hz una frecuencia de muestreo
de 4000 Hz

f=330
fs=4000
tmax=1

t= np.arange(0,tmax, 1/fs)

x=np.sin(2*np.pi*f*t)
print(len(x))
plt.figure(figsize=(15,5))
plt.plot(t,x)
#plt.plot(t[0:100],x[0:100])
plt.xlabel("Tiempo (s)")
plt.ylabel("Amplitud")
plt.grid()
plt.show()

4000

Calculamos la transformada de Fourier de la señal sinusoidal creada, de acuerdo con la


explicacion anterior

U =dftmatrix(N=len(x), Nfft=fs) #calculo la matriz de transformacion


print(U.shape)
x.shape=(len(x),1) # Convierto en vector columna para poder multiplicar con la matriz

X=U.H*x # X es la transformada de Fourier de x

(4000, 4000)

https://colab.research.google.com/drive/14GmyEZRA4BX5x145piIvxgKRdn2FrLr6?authuser=1#scrollTo=K49aU4NVzBBh&printMode=true 2/10
14/7/2020 Lab_Clase11_part1.ipynb - Colaboratory

En terminos simples, la DFT toma una señal y calcula cuales frecuencias estan presentes en
ella. En términos mas tecnicos, la DFT transforma la señal del dominio del tiempo al dominio de
la frecuencia.

X es un arreglo que contiene las distintas frecuencias presentes en la señal sinusoidal original.

En nuestro caso particular tenemos una resolucion de 1Hz, lo que quiere decir que cada valor
del arreglo X contiene la informacion de cada componente en frecuencia separadas 1 Hz (X[1]
corresponde a la informacion a 1Hz, X[20] la informacion a 20 Hz, etc), por que?

Sin embargo, nos encontramos con un pequeño problema, La DFT retorna un arreglo de
numeros complejos, que parece no tener mucho sentido inicialmente. Si imprimimos los
primeros 8 valores de X, podemos ver los siguiente

print(X[0:8])

[[ 1.21153088e-14+0.00000000e+00j]
[-8.84015083e-15-3.74469878e-15j]
[ 5.17641485e-15-1.26233659e-15j]
[-4.06619183e-15+8.76935243e-15j]
[ 1.80619408e-14+5.44269491e-17j]
[-8.61810623e-15-4.91598949e-15j]
[ 2.51187959e-15+7.06422768e-15j]
[-1.80133686e-14+9.21485110e-15j]]

Que signi can estos valores especi cos?

Vamos a considerar por ahora solo la informacion de amplitud de la DFT

Xabs=np.abs(X)
print(X.shape)

(4000, 1)

Nuevamente, consideramos solo los primeros 8 valores de la DFT, tenemos lo siguiente

print(Xabs[0:8])

https://colab.research.google.com/drive/14GmyEZRA4BX5x145piIvxgKRdn2FrLr6?authuser=1#scrollTo=K49aU4NVzBBh&printMode=true 3/10
14/7/2020 Lab_Clase11_part1.ipynb - Colaboratory

[[1.21153088e-14]
[9.60057476e-15]
[5.32811077e-15]
[9.66620184e-15]
[1.80620228e-14]
[9.92162828e-15]
Por que estos valores son pequeños?
[7.49752304e-15]
[2.02335100e-14]]

Por el contrario, si vemos X[330] podemos ver un valor grande, por que?

print(Xabs[330])

print(np.argmax(Xabs))

[[31.6227766]]
330

plt.figure(figsize=(15,5))
plt.subplot(2,1,1)
plt.plot(t[:100], x[:100])
plt.title("Senal original")
plt.grid()
plt.subplot(2,1,2)
plt.plot(Xabs)
plt.xlabel("Frecuencia (Hz)")
plt.xlim(0,1200)
plt.grid()
plt.show()

Y de esta forma se encuentran las frecuencias presentes en una señal.

https://colab.research.google.com/drive/14GmyEZRA4BX5x145piIvxgKRdn2FrLr6?authuser=1#scrollTo=K49aU4NVzBBh&printMode=true 4/10
14/7/2020 Lab_Clase11_part1.ipynb - Colaboratory

A continuacion veremos que sucede cuando se tienen varias frecuencias presentes en la señal y
queremos separar las señales originales.

Eliminacion de ruido de una señal sinusoidal En este ejemplo, adcionaremos una señal de ruido
con una frecuencia de 60 Hz (ruido electrico AC) a nuestra señal original, y posteriormente lo
vamos a eliminar usando solo la DFT

f= #frecuencia de señal
fnoise= #frecuencia de ruido
fs=4000 #frecuencia de muestreo
tmax=1 #tiempo de muestra

t= np.arange(0,tmax, 1/fs)

x=np.sin(2*np.pi*f*t)+0.5*np.sin(2*np.pi*fnoise*t) #señal original + ruido generado

plt.figure(figsize=(15,5))
plt.plot(t[0:400],x[0:400])
plt.xlabel("Tiempo (s)")
plt.ylabel("Amplitud")
plt.grid()
plt.show()

¿Cuantos elementos tiene el arreglo t?

Calculamos la DFT de la señal con ruido obtenida (Usamos el metodo de numpy)

X = np.fft.fft(x)

X = (np.abs(X[:len(X)]))
https://colab.research.google.com/drive/14GmyEZRA4BX5x145piIvxgKRdn2FrLr6?authuser=1#scrollTo=K49aU4NVzBBh&printMode=true 5/10
14/7/2020 Lab_Clase11_part1.ipynb - Colaboratory
X (np.abs(X[:len(X)]))

Gra car la FFT determinada.

plt.figure(figsize=(15,5))

#escribir el código

plt.title("Antes de filtrarse: Se tienen dos picos (330 Hz) + frecuencia de ruido (60Hz)")
plt.grid()
plt.xlim(0,1200)

(0.0, 1200.0)

Ahora vamos a eliminar el ruido, usando solamente la DFT.

index=0
filtered_X=[]
for f in X:
# Filtro entre los limites bajo y alto
# Se escoge entre 325 y 335, Tan cercanos a 330. En aplicaciones reales no se tienen n
if index > 325 and index < 335:
# Aqui se busca las frecuencias que superen cierta amplitud en la DFT
if f > 1:
filtered_X.append(f)
else:
filtered_X.append(0)
else:
filtered_X.append(0)
index += 1

#filtered_X = np.asarray([f if (325 < index < 335 and f > 1) else 0 for index, f in enumer

https://colab.research.google.com/drive/14GmyEZRA4BX5x145piIvxgKRdn2FrLr6?authuser=1#scrollTo=K49aU4NVzBBh&printMode=true 6/10
14/7/2020 Lab_Clase11_part1.ipynb - Colaboratory

plt.figure(figsize=(15,5))

# graficar la señal filtrada


plt.title("Despues de filtrarse: Se tienen solo el pico a 330 Hz")
plt.grid()
plt.xlim(0,1200)

(0.0, 1200.0)

Para recuperar la señal original, se utiliza la transformada inversa de Fourier

recovered_x = np.real(np.fft.ifft(filtered_X))

plt.figure(figsize=(15,10))
plt.subplot(2,1,1)
plt.plot(t[0:400],x[0:400])
plt.xlabel("Tiempo (s)")
plt.ylabel("Amplitud")
plt.grid()

plt.subplot(2,1,2)
plt.plot(t[0:400],recovered_x[0:400])
plt.xlabel("Tiempo (s)")
plt.ylabel("Amplitud")
plt.grid()
plt.show()

https://colab.research.google.com/drive/14GmyEZRA4BX5x145piIvxgKRdn2FrLr6?authuser=1#scrollTo=K49aU4NVzBBh&printMode=true 7/10
14/7/2020 Lab_Clase11_part1.ipynb - Colaboratory

Parte 2. Efecto de la resolucion en frecuencia

Genere una señal de acuerdo con el último número de su DNI , de acuerdo con la siguiente lista.

0. Tren de impulsos con una frecuencia de 100 Hz, y una frecuencia de muestreo de 600 Hz
1. Señal diente de sierra con una frecuencia de 200 Hz, y una frecuencia de muestreo de
1000 Hz
2. sin(2π ∗ 60 ∗ t) + sin(2π ∗ 200 ∗ t) + sin(2π ∗ 500 ∗ t) con fs=1500 Hz
3. Señal cuadrada con una frecuencia de 300 Hz, y fs=1800 Hz
4. sin(2π ∗ 20 ∗ t) ∗ sin(2π ∗ 200 ∗ t) con fs=1500 Hz
5. sin(2π ∗ 1000 ∗ t) + N (0, 1) , N (0, 1) es ruido aleatorio con media cero y desviación
estandar 0.1, con fs=3000 Hz
6. |sin(2π ∗ 100 ∗ t)| con fs=300 Hz
7. sin(2π ∗ t ∗ t) con fs=100 Hz, la señal con una duración de 10 segundos
8. sin(2π ∗ 10 ∗ sin(2 ∗ pi ∗ 300 ∗ t) ∗ t) con fs=1000 Hz
9. (sin(2π ∗ 100 ∗ t))2 con fs=500 Hz

# numero 5

fs=
tmax=0.01
t=np.arange(0,tmax, 1/fs)
#cuantos elementos tiene el arreglo????

https://colab.research.google.com/drive/14GmyEZRA4BX5x145piIvxgKRdn2FrLr6?authuser=1#scrollTo=K49aU4NVzBBh&printMode=true 8/10
14/7/2020 Lab_Clase11_part1.ipynb - Colaboratory

N=np.random.randn(len(t))*0.1
xt=np.sin(2*np.pi*1000*t)+N

plt.figure(figsize=(15,5))
plt.plot(t,xt)
plt.xlabel("Tiempo (s)")
plt.grid()
plt.show()

30

Calcule la matriz de transformacion U, y calcule y gra que la transformada de Fourier de la señal


asignada para distintos valores de 𝑁𝐹𝐹𝑇 .

que se puede concluir al respecto? conclusiones.

Por que aparece la DFT para frecuencias positivas y negativas?.

nfft=2048 #valores de NFFT

xt.shape=(len(xt),1) # Convierto en vector columna para poder multiplicar con la matriz

# calculo la matriz de transformacion

Xf=U.H*xt[:] # calculo la fft

freq=np.hstack((np.arange(0, nfft/2-1),np.arange(-nfft/2, 1)))*fs/nfft # vector de frecuen

# genero graficas
plt.figure(figsize=(15,7))
plt.subplot(211)
plt.plot(t, xt)
plt.grid()
plt.xlabel('Tiempo (seg)')
plt.subplot(212)
plt.plot(freq, np.abs(Xf))
plt.xlabel('Frecuencia (Hz)')
https://colab.research.google.com/drive/14GmyEZRA4BX5x145piIvxgKRdn2FrLr6?authuser=1#scrollTo=K49aU4NVzBBh&printMode=true 9/10
14/7/2020 Lab_Clase11_part1.ipynb - Colaboratory
p ( ( ) )
plt.grid()
plt.show()

https://colab.research.google.com/drive/14GmyEZRA4BX5x145piIvxgKRdn2FrLr6?authuser=1#scrollTo=K49aU4NVzBBh&printMode=true 10/10

También podría gustarte