{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "uNiyNQitRDDx" }, "source": [ "#**Taller 3 parte I**\n", "\n", "# Representación de las señales en tiempo y frecuencia\n", "\n", "# Introducción\n", "\n", "En este taller comenzaremos a dar los primeros pasos para acercarnos a los temas de comunicaciones inalámbricas y procesamiento de señales. Con esta excusa, empezaremos tratando de entender algunos conceptos importantes, en particular el de *frecuencia*.\n", "\n", "A lo largo de todo el taller (tanto la parte I como la parte II), las preguntas que se plantean se deben entender como guía. Toda exploración por fuera del camino marcado es más que bienvenida. Se espera que cada grupo registre y documente los distintos experimentos realizados y respuestas a las preguntas planteadas.\n", "\n", "En general a lo largo del taller vamos a ir acumulando, es decir los ejemplos o ejercicios de un taller servirán como base para el resto del curso. Por eso es importante que cada grupo vaya guardando y documentando prolijamente los experimentos realizados y el código generado.\n", "\n", "Los ejercicios obligatorios del taller, al igual que en los anteriores, deben ser realizados y entregados individualmente por más que trabajen en grupo en el resto del notebook. La entrega es el miércoles 17 de abril a las 23:59hs.\n", "\n", "\n", "\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "1FOje-q9ikL-" }, "source": [ "#Audio en Python\n", "\n", "Empecemos por ver cómo manejar el sonido y las señales de audio con las que trabajaremos inicialmente desde Python.\n", "\n", "En primer lugar se verá cómo reproducir archivos de audio. Reproduciremos y trabajaremos en este taller con archivos en formato *wav*. Buscar en internet en qué consiste este formato.\n", "\n", "Nota: Para la correcta ejecución de varios de los recuadros de código de este notebook podría ser necesario tener seleccionada la opción \"Aceptar todas las cookies\" en el navegador.\n", "\n", "Para reproducir un archivo de audio debemos importar una biblioteca llamada Audio, de la siguiente forma:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Tx0UlZHbed6n" }, "outputs": [], "source": [ "from IPython.display import Audio" ] }, { "cell_type": "markdown", "metadata": { "id": "pboG7_74jGts" }, "source": [ "Luego tenemos que reproducir el archivo de audio que deseemos. Eso lo podremos hacer de dos formas. La primera implica subir el archivo de nuestra computadora a Colab, ejecutando las siguientes dos intrucciones. Se abrirá una ventana que permitirá elegir el archivo que deseamos subir." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "AF9CdvtYegWV" }, "outputs": [], "source": [ "from google.colab import files\n", "uploaded = files.upload()" ] }, { "cell_type": "markdown", "metadata": { "id": "lw97e33fjyh1" }, "source": [ "En mi caso, por ejemplo, he subido un archivo llamado Jaime_24.wav y podré reproducirlo como se muestra en el recuadro siguiente a este texto (en el eva hay dos ejemplos de archivos .wav).\n", "\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "kMx0ZQNheqNd" }, "outputs": [], "source": [ "a = Audio('Jaime_24.wav')\n", "a" ] }, { "cell_type": "markdown", "source": [ "Una observación importante es que el espacio en disco del notebook de Google Colab no es persistente y se borra cuando se cierra la sesión. Por lo tanto, el archivo se debe subir cada vez que se quiera trabajar con él. Más adelante veremos otra posibilidad que es tener el archivo en la web y acceder a él desde Colab. Otra forma es usar Google Drive como forma de almacenamiento. Pueden ver un tutorial de como hacerlo en:\n", "\n", "https://www.youtube.com/watch?v=Gvwuyx_F-28" ], "metadata": { "id": "KuePvVBX3FG2" } }, { "cell_type": "markdown", "metadata": { "id": "0Hdh2NN8jwhf" }, "source": [ "La última forma de reproducir un archivo wav que veremos es invocarlo directamente desde una página web como por ejemplo:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "background_save": true, "base_uri": "https://localhost:8080/", "height": 75 }, "id": "yAckjPG4fC-6", "outputId": "d44b18c1-ecbc-4b76-a6d5-de6b8fdbfe2d" }, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Audio('https://iie.fing.edu.uy/ense/asign/tallerinte/repo/canciones/Jaime_24.wav')" ] }, { "cell_type": "markdown", "metadata": { "id": "r6gd2XDJgHne" }, "source": [ "# Tasa de muestreo\n", "\n", "El concepto de la **tasa de muestreo** (o **frecuencia de muestreo**) de una señal es muy importante y debe comprenderse bien para poder seguir adelante. Pensemos como ejemplo en la grabación de la voz de una persona. Cuando alguien habla se genera una onda sonora que se corresponde a variaciones de presión del aire. Estas variaciones de presión llegan a un micrófono (el de la computadora, por ejemplo) y son convertidas en una variación de voltaje como el de la siguiente Figura.\n", "\n", "![alt text](https://iie.fing.edu.uy/~belza/tallerinefiguras/sonido.png)\n", "\n", "\n", "Ahora bien, las computadoras, al tener memoria finita, no trabajan con señales que puedan tomar cualquier valor y que sean continuas en el tiempo. Se trabaja tomando muestras (valores de la señal) cada cierto tiempo periódico. Por lo tanto, si trabajo a 44100 muestras por segundo quiere decir que cada un tiempo igual a 1/44100 segundos guardo el valor del voltaje correspondiente a ese momento.\n", "\n", "Además, ese valor muestreado lo voy a guardar con una cantidad de bits fijos. Si trabajara con 1 byte (1 byte= 8 bits), por ejemplo, me daría la posibilidad de tener una escala con 256 valores (8 bits donde cada uno puede valer 0 o 1, entonces tengo 2**8=256 valores/niveles distintos). Entonces lo que se hace es dividir el rango máximo de nuestra señal entre esa cantidad de valores y aproximar el voltaje en un punto al valor de la escala más cercano. Por ejemplo si el micrófono sacara una señal cuyo rango fuera entre 0 y 8 Volts como se muestra en la siguiente Figura\n", "\n", "![alt text](https://iie.fing.edu.uy/~belza/tallerinefiguras/analog_muestreada.png)\n", "\n", "\n", "y tuviera un byte (8 bits) para representar el valor de cada muestra tendría que dividir 8V/256 y eso me daría los escalones posibles a los cuales aproximar el valor de la señal en cada muestra. Es decir por ejemplo 0 Volts corresponde al 0, 8V a 255, 4V al 128, etc. Este proceso se puede ver en la siguiente Figura\n", "\n", "\n", "![alt text](https://iie.fing.edu.uy/~belza/tallerinefiguras/tasasMuestreo.png)" ] }, { "cell_type": "markdown", "metadata": { "id": "6lFY_Lcpps-K" }, "source": [ "Una señal muestreada en Python será para nosotros un vector (típicamente un numpy array) o una lista de Python donde los valores serán las muestras de la señal. La frecuencia de muestreo será un dato externo que no estará en el vector.\n", "\n", "Por ejemplo, imaginemos que se tiene una señal que es una recta que pasa por el origen y crece de a un volt cada segundo. Si la muestreo a una tasa de $5$ muestras por segundo durante el primer segundo obtengo (asumiendo que la primera muestra sea en cero) el vector $[0, 0.2, 0.4, 0.6, 0.8]$; o si la primera muestra no cae en 0 sino en 0.1 V será $[0.1,0.3,0.5,0.7,0.9]$. En cambio si esa misma señal la muestreo durante un segundo a una tasa de $10$ muestras por segundo se obtiene el vector: $[0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9]$.\n", "\n", "A modo de comentario y dado que venimos trabajando con archivos wav, la tasa de muestreo de los archivos wav es habitualmente de 44100 muestras/s (esto se puede ver haciendo click derecho en el archivo del wav y entrando a Propiedades).\n", "\n", "#Ejemplo\n", "\n", "Se denomina señal \"sinusoidal\" a una señal de forma $f(t) = A. \\sin(2 \\pi f_0 t)$, donde \"A\" es la amplitud y $f_0$ la frecuencia (T = período = $1/f_0$).\n", "\n", "\n", "Es importante notar que la función seno puede ser cambiada por un coseno, sin perder la denominación de señal sinusoidal. Podría considerarse un elemento más en la función (la \"fase\") que se suma dentro del seno (o coseno) y desplaza la función en el tiempo. Usualmente se toma fase nula.\n", "\n", "Suponer que se muestrea una señal sinusoidal de amplitud 0.5V y de período 1/50 segundos durante los primeros 5 períodos y a una tasa de muestreo $f_s$, que inicialmente valdrá 200 muestras por segundo.\n", "¿Cómo generaría en Python un vector con las muestras que se obtendrían?\n", "\n", "Idea: Sea la señal a muestrear $F(t) = K \\sin(2 \\pi f_0 t)$ con $f_0$ la frecuencia de la sinusoide. En Python para generar las $N$ muestras de la señal es necesario sustituir el $t$ de las ecuaciones anteriores por un array con los valores de los tiempos de las muestras, es decir $0,1/f_s,2/f_s,...., (N-1)/f_s$ siendo $f_s$ la frecuencia de muestreo. Esto es lo que haremos, como se presenta en el siguiente código.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "-IBvHWkqWNBo" }, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "#Ejemplo\n", "\n", "# Voy a muestrear a 200 muestras por segundo durante 0.1 segundos (5 períodos de una sinusoide de período\n", "# 1/50 segundos). Necesito un vector con los tiempos de muestreo.\n", "T= np.arange(0,0.1,1/200) # esta instrucción crea un vector de 0 a 0.1 con pasos de 1/200 = 0.05\n", "# Por ejemplo, genero una sinusoide de frecuencia 50Hz (1Hz = 1 ciclo o período por segundo,\n", "# es decir de período 1/50 segundos) muestreada en los tiempos correspondientes al vector T,\n", "# y la asigno a un vector f1\n", "f0 = 50\n", "amplitud = 0.5\n", "f1 = amplitud * np.sin(2*np.pi*f0*T)\n", "# Grafico el vector f1 poniendo en cada muestra un \"*\"\n", "# Observar que para graficar le pedimos a la función plot que los puntos de la gráfica los muestre con un '*'.\n", "# Si no ponemos este parámetro, plot unirá los puntos con líneas y podremos no darnos cuenta dónde\n", "# están las muestras. Pruebe hacerlo.\n", "plt.figure(figsize=(14,6))\n", "plt.plot(f1, \"*\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "id": "KZmCfaCFupIM" }, "source": [ "#Ejercicio\n", "\n", "1. Observar la figura anterior. Si bien se \"adivina\" que las muestras son de una sinusoide, no podría afirmarse a simple vista: podría tratarse de otra forma de onda. ¿Cómo podría hacer para que se pareciera más a una sinusoide? Modificar el código anterior para lograrlo y explicar qué es lo que estaría haciendo para ver cada vez mejor la sinusoide.\n", "\n", "2. Generar un programa en Python que calcule el vector correspondiente a una señal lineal (que pasa por el origen y crece de a 5 Volts por segundo) muestreada a una tasa de 10 muestras por segundo durante un segundo. El primer punto de muestreo es un valor aleatorio entre 0.0 y 0.1 segundos.\n", "\n", " Sugerencia: La señal a muestrear ahora es F(t)=5t." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "jkbV3bau1JAw" }, "outputs": [], "source": [ "# Celda para resolver el ejercicio 2 anterior\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "FnN0hLV5yGte" }, "source": [ "# El concepto de frecuencia\n", "\n", "En primer lugar nos enfocaremos en señales más sencillas que la voz humana o la música. En particular, vamos a enfocarnos en notas musicales. Por ejemplo, la nota \"LA\" estándar (cuarta octava) está en 440 Hz. ¿Qué significa eso?\n", "\n", "Para empezar, \"Hz\" es la abreviación de \"Hertz\". El Hertz es una unidad que mide algo periódico (que sucede cada cierto tiempo fijo). En particular, 1Hz indica algo que sucede una vez por segundo. Quizá hayan escuchado hablar de las RPM (revoluciones por minuto), que suelen utilizarse para indicar cuántas vueltas da el eje de un motor en un minuto (muchos autos lo incluyen en su tablero). Pues esto es lo mismo, pero medido cada un segundo en vez de un minuto. En todos los casos se lo denomina frecuencia.\n", "\n", "#Ejemplo\n", "\n", "Escribiremos un programa que genere el vector correspondiente a una sinusoide muestreada a 44100 muestras por segundo de duración 2 segundos y que tenga una frecuencia de 440 Hz. La señal a generar tendrá una amplitud que varíe entre +/- 0.5. Luego escucharemos esta señal utilizando la función Audio ya vista para reproducir archivos wav. Leer, comprender en detalle el siguiente código y luego ejecutarlo y modificarlo como desee.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "fur666xk7uZV" }, "outputs": [], "source": [ "import numpy as np\n", "from IPython.display import Audio\n", "fs = 44100 # Tasa/frecuencia de muestreo.\n", "T = 2.0 # Tiempo de muestreo de la señal.\n", "t = np.arange(0, T, 1/fs) # Vector con los tiempos de muestreo.\n", "f0 = 440 # Frecuencia de la sinusoide.\n", "x = 0.5*np.sin(2*np.pi*f0*t) # Nota La de la cuarta octava, una sinusoide(tono) a 440 Hz.\n", "# Para escuchar el audio en este caso no tenemos un archivo como antes, sino el array con las muestras.\n", "# A la función Audio le podemos pasar el array con las muestras directamente y la tasa de muestreo\n", "# en el parámetro rate.\n", "Audio(x, rate=fs)\n", "# Probar variar la frecuencia de la sinusoide, por ejemplo a 5000 Hz y a 100 Hz, y ver qué se escucha." ] }, { "cell_type": "markdown", "metadata": { "id": "nCi4dzTa1gxp" }, "source": [ "#**Ejercicio 1 obligatorio para entrega individual**\n", "Mostrar en un gráfico utilizando la función plot de la biblioteca matplotlib cómo varían en el tiempo las primeras doscientas muestras de la señal del ejercicio anterior. Verificar que la amplitud y el período de la sinusoide son los correctos. La gráfica debe mostrar con un marcador el valor de cada muestra.\n", "\n", "Posteriormente, haga lo mismo para las notas Do, Re, Mi, Fa, Sol, La, Si de la cuarta octava y de la quinta octava.\n", "\n", "Buscar en Internet una fórmula para calcular la frecuencia de cualquier nota en cualquier octava e impleméntelo en Python. Hacer una función a la que le pase la nota, la octava y el tiempo de ejecución y retorne las muestras.\n", "\n", "Componer una melodía utilizando la función anterior y escucharla con la función Audio.\n", "\n", "Nota: puede ser útil la función *concatenate* de numpy.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "-kliGPDP46uy" }, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from IPython.display import Audio\n" ] }, { "cell_type": "markdown", "metadata": { "id": "5WTV0ZZS2f_z" }, "source": [ "# Representación de la señal en frecuencia\n", "\n", "En la parte anterior se vio cómo variaba la señal en el tiempo. Esta es una posible representación de la señal. También se puede pensar en representar las señales por sus componentes en frecuencia en lugar de por sus valores en el tiempo. Para eso hay funciones que nos permiten dada una señal identificar qué frecuencias tiene. Un algoritmo para calcular los componentes en frecuencia de una señal muy utilizado se denomina Fast Fourier Transform (FFT). La siguiente función permite dada una señal obtener un gráfico de las componentes en frecuencia que tiene la señal. Al diagrama con las componentes en frecuencia de la señal se le llama habitualmente espectro de la señal.\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "dHBADqNc2xsa" }, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "def plot_frec(x,fs,fmax,m): #esta función permite graficar las frecuencias de una señal x muestreada a tasa fs, el rango que grafica va hasta fmax, y m la cantidad de puntos que toma para calcular la FFT .\n", " puntos = int(fmax/fs*m)\n", " lx = len(x)\n", " nt = (lx + m - 1)//m\n", " xp = np.append(x,np.zeros(-lx+nt*m))\n", " xmw = np.reshape( xp, (m,nt), order='F')\n", " xmf = np.fft.fft(xmw,len(xmw),axis=0)/m\n", " xf = np.linspace(0, int(fs/2.0), int(m/2))\n", " plt.figure(figsize=(14,6))\n", " plt.plot(xf[0:puntos],np.abs(xmf[0:int(m/2),0:int(lx/m-1)]).mean(1)[0:puntos])\n", " plt.show()\n", "\n", "\n", "# Ejemplo de como utilizar la función que muestra las componentes en frecuencia de una señal usando el tono con la nota La que generamos en el ejemplo anterior\n", "fs = 44100 # tasa de muestreo\n", "T = 2.0 # tiempo de muestreo de la señal\n", "t = np.arange(0, T, 1/fs) # vector con los tiempos de muestreo\n", "f0 = 440 # frecuencia de la sinusoide\n", "x = 0.5*np.sin(2*np.pi*f0*t) # nota La de la cuarta octava, una sinusoide(tono) a 440 Hz\n", "#llamo a la figura y le pido que muestre los primeros 1000 Hz\n", "plot_frec(x,fs,1000,4096)" ] }, { "cell_type": "markdown", "metadata": { "id": "EvkNhMz46Ji7" }, "source": [ "#Ejercicio\n", "1. Interpretar el gráfico obtenido en el ejemplo anterior.\n", "2. Generar ahora una sinusoide de 4400 Hz. Sumar las dos sinusoides (la de 440 Hz y la de 4400 Hz) y graficar cómo varía la señal suma en el tiempo (primeras doscientas muestras) y cómo son sus componentes en frecuencia (observe que deberá cambiar también fmax). Interpretar el resultado que se obtiene al graficar las componentes en frecuencia.\n", "\n", "3. Generar sinusoides de frecuencias crecientes desde los 4.4 kHz hasta 20 kHz, por ejemplo de 8kHz, 10 kHz, 12 kHz, 14 kHz, 16 kHz, 18 KHz y 20kHz y escuchar estas señales. ¿Por qué parece que a medida que la frecuencia aumenta se escucha más débil? Probar hacer escuchar estas sinusoides de mayor frecuencia a una persona mayor a 30 años. ¿Cuál fue el resultado?\n", "Graficar en el tiempo los primeros 200 puntos de la sinusoide de 18 kHz, por ejemplo. ¿Se parece a una sinusoide? ¿Cómo explicaría lo que se observa?\n", "Sumar ahora las sinusoides de 440Hz, 4400 Hz y 8 kHz escuche el resultado final y ver su respuesta en frecuencia y en el tiempo.\n", "\n", "\n", "\n", "\n" ] }, { "cell_type": "code", "source": [ "# Celda para hacer el ejercicio anterior" ], "metadata": { "id": "qs4AM8311kIq" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "#Ejercicio\n", "Analizar la respuesta en frecuencia de algunos archivos wav y compare lo que escucha y la respuesta en frecuencia ¿Qué se observa? ¿Cómo puede explicar lo que observa?" ], "metadata": { "id": "981sBqj61koQ" } }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "pnGXJvp38VHo" }, "outputs": [], "source": [ "import librosa\n", "# Para hacer este último ejercio será necesario leer archivos wav que haya subido a Colab\n", "# Para leer un archivo wav puede hacerlo de la siguiente forma:\n", "data, fs = librosa.load('Jaime_24.wav')# le devuelve un numpy array con las muestras y la frecuencia de muestreo\n", "\n", "# Por si lo necesita en algún momento la forma de escribir un vector de muestras al disco de Colab se hace de la siguiente forma\n", "#librosa.output.write_wav('nombrearchivo.wav', data, fs)\n", "#data1, fs = librosa.load('nombrearchivo.wav')\n", "\n", "Audio(data1,rate=fs)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "l-JVoXVJVYLU" }, "outputs": [], "source": [ "import librosa\n", "data, fs = librosa.load('Jaime_24.wav')#\n", "plot_frec(data,fs,12000,4096)" ] }, { "cell_type": "markdown", "metadata": { "id": "BRhfZdgNVC7P" }, "source": [ "La respuesta en frecuencia de una sinusoide (o de un conjunto de sinusoides) muestra un espectro con componentes en frecuencia discretas. En el caso de la voz o de la música, que no son una señal periódica, se observa un espectro \"continuo\". Es como si fuera la suma de muchas sinuoides de diferentes amplitudes en \"todas las frecuencias\" (no literalmente en todas las frecuencias, pero se trata de un rango amplio, que se puede visualizar como continuo). Si la canción tiene más peso en los graves, veremos un espectro con mayor peso en las bajas frecuencias, si la canción tiene mayor peso en los agudos veremos un espectro con mayor peso en las frecuncias altas. Todo esto siempre dentro del rango de las frecuencias audibles por el ser humano (entre 20Hz y 19kHz, aproximadamente).\n", "\n", "Como podemos ver en las sinusoides, las frecuencias bajas están asociadas con señales que varían lentamente en el tiempo y las frecuencias altas con variaciones rápidas o bruscas en el tiempo.\n", "\n", "El concepto de frecuencia se aplica también a otras señales que no son sonidos. Las imágenes son un buen ejemplo de otro uso de la frecuencia. En primer lugar veremos como traer una imagen de una página web a nuestro notebbok y luego visualizarla:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "guqnStklySmy" }, "outputs": [], "source": [ "from PIL import Image\n", "import matplotlib.pyplot as plt\n", "#Podemos visualizar una figura trayendola de una web con el comando wget que la salva al disco de Colab\n", "#luego leerla de disco\n", "!wget 'https://iie.fing.edu.uy/~belza/tallerinefiguras/sonido.png'\n", "pil_im = Image.open('sonido.png')\n", "#y mostrarla usando la funación de matplotlib imshow\n", "imgplot = plt.imshow(pil_im)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "kUVBZWWhafHm" }, "outputs": [], "source": [ "#pero para seguir avanzando en el concepto de frecuencia construiremos nosotros una imagen.\n", "#Una imagen es un array de dos dimensiones donde en cada lugar del array tiene el valor del pixel correspondiente\n", "#Comenzaremos creando un array de NxN que tenga 1 en todas las posiciones del array.\n", "N = 5000\n", "data = np.ones((N,N))\n", "#Ahora vamos a recorrer las filas del array\n", "for i in range(0,N,1):\n", " # para las filas superiores (menores a 500) vamos a dibujar en escala de grises una sinusoide\n", " if i < 500:\n", " for j in range(1,N,1):\n", " data[i][j] = np.sin(2*np.pi*20*j/N)\n", " #para la parte inferior del array vamos a dibujar 125 columnas blancas y 125 negras\n", " else:\n", " for j in range(1,N,250):\n", " for k in range(125):\n", " data[i][j+k] = -1\n", "# visualizamos la imagen y le decimos que la queremos ver en escala de grises que se indica diciendo que el color map cmap es binary\n", "imgplot = plt.imshow(data,cmap='binary')\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "nUF9_eYuf-WC" }, "outputs": [], "source": [ "\n", "# a continuación visualizaremos en el \"tiempo\" en este caso en los pixels una fila de la imagen por ejemplo la 400\n", "plt.plot(data[400])\n", "plt.show()\n", "# y luego calcularemos su espectro de frecuencia\n", "plot_frec(data[400],N,80,256)\n", "# ¿En qué frecuencia se encuentra el pico? Explicar por qué da en ese valor mirando la imagen.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "aCjundOd0dct" }, "outputs": [], "source": [ "#también podemos ver una fila de la imagen en la parte inferior, por ejemplo la 600\n", "plt.plot(data[600])\n", "plt.show()\n", "# y luego calcularemos su espectro de frecuencia\n", "plot_frec(data[600],N,200,256)\n", "# ¿En qué frecuencia se encuentra el primer pico? Explicar por qué da en ese valor mirando la imagen\n", "# ¿Porqué tiene más componentes de frecuencia que la fila 400 que vimos antes?\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "1ot-a40wd6kg" }, "source": [ "Para quien esté interesado en trabajar con imágenes en Python le recomendamos el siguiente tutorial:\n", "https://matplotlib.org/3.1.1/tutorials/introductory/images.html\n" ] } ], "metadata": { "colab": { "provenance": [] }, "kernelspec": { "display_name": "Python 3", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 0 }