Semana 6: Procesamiento en el Dominio de la Frecuencia I -
Introducción a la Transformada de Fourier
Objetivos de la Semana:
1. Comprender el concepto del dominio de la frecuencia en
imágenes y su diferencia con el dominio espacial.
2. Introducir la Transformada de Fourier (FT) y,
específicamente, la Transformada Discreta de Fourier
(DFT) para imágenes digitales.
3. Aprender a calcular la DFT 2D de una imagen usando NumPy
([Link].fft2, [Link]).
4. Visualizar e interpretar el Espectro de Magnitud de una
imagen (centrado y con escala logarítmica).
5. Observar cómo el contenido de una imagen afecta su espectro
de magnitud (ejemplos con imágenes simples y con una imagen
fuertemente desenfocada).
6. Comprender la importancia de la Transformada Inversa de
Fourier (IDFT) para reconstruir la imagen y la relevancia de la
información de fase (con un ejemplo de reconstrucción con fase
alterada).
7. Introducir conceptualmente el filtrado en el dominio de la
frecuencia (como avance para la próxima semana).
I. Parte Teórica: Una Nueva Perspectiva de las Imágenes
(a) Repaso y Transición: Del Dominio Espacial al Dominio de la
Frecuencia
Dominio Espacial (Semanas 1-5): Hemos trabajado
directamente con los valores de intensidad de los píxeles en sus
coordenadas (x,y). Las operaciones (puntuales, de
vecindad/kernels) se aplicaban sobre estos valores.
Dominio de la Frecuencia: Ahora, vamos a transformar la
imagen a una representación diferente. En lugar de ver la
imagen como una colección de intensidades de píxeles, la
veremos como una superposición de ondas sinusoidales (o
cosenos) de diferentes frecuencias, amplitudes y
orientaciones.
o Analogía Sonora: Piensa en un sonido complejo (como
una pieza musical). Puede descomponerse en una suma
de tonos puros (ondas sinusoidales simples) de diferentes
frecuencias y volúmenes. La Transformada de Fourier
hace algo similar para las imágenes.
(b) ¿Qué son las Frecuencias en una Imagen?
Bajas Frecuencias: Corresponden a cambios lentos y
graduales en la intensidad de la imagen. Representan la
estructura general, las áreas suaves, los fondos, el brillo
promedio.
Altas Frecuencias: Corresponden a cambios rápidos y
abruptos en la intensidad. Representan los bordes, los detalles
finos, las texturas complejas y también, a menudo, el ruido.
Una imagen con muchos detalles finos y bordes nítidos tendrá
componentes de alta frecuencia significativos. Una imagen
borrosa o muy suave estará dominada por bajas frecuencias.
(c) La Transformada de Fourier (FT) y la Transformada
Discreta de Fourier (DFT)
Transformada de Fourier (FT): Es una herramienta
matemática que descompone una señal (en nuestro caso, una
imagen) en sus componentes de frecuencia constituyentes. Nos
dice "cuánto" de cada frecuencia está presente en la señal.
Transformada Discreta de Fourier (DFT): Dado que
nuestras imágenes son digitales (discretas, compuestas por
píxeles), usamos la DFT.
o Para una imagen 2D, la DFT 2D produce una matriz de
números complejos del mismo tamaño que la imagen
de entrada.
o Cada elemento (u,v) en esta matriz de salida de la DFT
representa una frecuencia 2D específica (una onda que
varía en la dirección horizontal u y vertical v).
o El valor complejo en (u,v) nos da dos piezas de
información sobre esa onda de frecuencia específica:
1. Magnitud: La amplitud o "fuerza" de esa
componente de frecuencia en la imagen.
2. Fase: El desplazamiento o "posición inicial" de esa
onda. La fase es crucial para reconstruir la
estructura espacial de la imagen.
(d) El Espectro de Magnitud y Fase
Después de calcular la DFT de una imagen
F(u,v)=textDFT(f(x,y)):
o Espectro de Magnitud: Se calcula como el valor
∣F(u,v)∣. Nos dice la "cantidad" de cada frecuencia. Esto es
absoluto (o módulo) de cada número complejo en F(u,v):
lo que usualmente visualizamos.
o Espectro de Fase: Se calcula como el ángulo (o
argumento) de cada número complejo: textangle(F(u,v)).
Contiene información sobre la localización espacial de las
características. Aunque es vital para la reconstrucción, es
difícil de interpretar visualmente (suele parecer ruido).
Centrado del Espectro ([Link]): Por defecto, la DFT
(como la implementa NumPy) coloca el componente de
frecuencia cero (llamado componente DC, que representa el
brillo promedio de la imagen) en la esquina superior izquierda
del espectro. Para una visualización más intuitiva, usamos
[Link]() para mover este componente DC al centro del
espectro. Así, las bajas frecuencias quedan en el centro y las
altas frecuencias se alejan hacia los bordes.
Escala Logarítmica para Visualización: El componente DC
suele tener una magnitud muchísimo mayor que las otras
frecuencias. Para poder ver las componentes de frecuencia más
débiles, visualizamos el espectro de magnitud en una escala
logarítmica: log(1+∣F(u,v)∣). El +1 es para evitar log(0).
(e) La Transformada Inversa de Fourier (IDFT)
Así como la DFT transforma una imagen del dominio espacial al
frecuencial, la IDFT hace lo contrario: transforma la
representación en frecuencia de nuevo al dominio espacial.
f(x,y)=textIDFT(F(u,v))
Esto es crucial porque cualquier modificación que hagamos en
el dominio de la frecuencia (como filtrar) necesitará ser
transformada de nuevo al dominio espacial para ver el
resultado en la imagen.
(f) Filtrado en el Dominio de la Frecuencia (Introducción
Conceptual)
La idea básica es:
1. Transformar la imagen al dominio de la frecuencia usando
DFT: F(u,v).
2. Crear un filtro H(u,v) en el dominio de la frecuencia. Este
filtro es una matriz del mismo tamaño que F(u,v), y sus
valores (usualmente entre 0 y 1) determinan si se
atenúan o se pasan ciertas frecuencias.
3. Multiplicar la DFT de la imagen por el filtro:
G(u,v)=F(u,v)cdotH(u,v).
4. Aplicar la IDFT al resultado para obtener la imagen filtrada
en el dominio espacial: g(x,y)=textIDFT(G(u,v)).
Ejemplos de filtros (que veremos en detalle la próxima
semana):
o Filtro Paso Bajo (Low-Pass Filter - LPF): H(u,v)
atenúa las altas frecuencias y deja pasar las bajas.
Resultado: suavizado/desenfoque.
o Filtro Paso Alto (High-Pass Filter - HPF): H(u,v)
atenúa las bajas frecuencias y deja pasar las altas.
Resultado: realce de bordes/enfoque.
II. Parte Práctica: Explorando el Espectro de Frecuencia en VS
Code
Prepara tu entorno y una imagen de prueba (ej.
imagen_prueba.jpg)
Ejemplo 1: Cálculo y Visualización del Espectro de Magnitud
DFT
Crea un archivo semana6_ejemplo1_dft_espectro.py
Pega el código:
import cv2
import numpy as np
import [Link] as plt
# Cargar imagen en escala de grises
ruta_imagen = 'imagen_prueba.jpg'
imagen_gris = [Link](ruta_imagen, cv2.IMREAD_GRAYSCALE)
if imagen_gris is None:
print(f"Error al cargar {ruta_imagen}.")
else:
print("Imagen original en escala de grises cargada.")
# --- Paso 1: Calcular la DFT 2D ---
# NumPy fft tiene funciones para esto. La salida es una matriz
de números complejos.
dft = [Link].fft2(imagen_gris)
print("DFT calculada.")
# --- Paso 2: Centrar el componente de frecuencia cero (DC) ---
# Por defecto, el DC está en la esquina (0,0). Lo movemos al
centro para visualización.
dft_shift = [Link](dft)
print("Componente DC centrado.")
# --- Paso 3: Calcular el Espectro de Magnitud ---
# Magnitud = sqrt(real^2 + imag^2). [Link]() lo hace por
nosotros.
magnitud_espectro = [Link](dft_shift)
print("Espectro de magnitud calculado.")
# --- Paso 4: Aplicar escala logarítmica para mejorar la
visualización ---
# El componente DC suele ser mucho más brillante que los demás.
# Sumamos 1 para evitar log(0).
magnitud_espectro_log = [Link](1 + magnitud_espectro)
print("Escala logarítmica aplicada al espectro de magnitud.")
# --- Visualización ---
[Link](figsize=(12, 6))
[Link](1, 2, 1)
[Link](imagen_gris, cmap='gray')
[Link]('Imagen Original (Grayscale)')
[Link]('off')
[Link](1, 2, 2)
[Link](magnitud_espectro_log, cmap='gray')
[Link]('Espectro de Magnitud (Log, Centrado)')
[Link]('off')
[Link]('Transformada Discreta de Fourier y su Espectro de
Magnitud', fontsize=16)
plt.tight_layout()
plt.subplots_adjust(top=0.90)
[Link]()
print("\nObservaciones del Espectro de Magnitud:")
print("- El punto brillante en el centro es el componente DC
(bajas frecuencias, brillo promedio).")
print("- Puntos/líneas más alejados del centro representan
frecuencias más altas (detalles, bordes).")
print("- Patrones en el espectro (ej. líneas) pueden indicar
orientaciones dominantes en la imagen.")
Guarda y ejecuta. Observa el espectro de magnitud. El centro
brillante indica las bajas frecuencias.
Ejemplo 2: Espectro de Imágenes Sintéticas Simples
Crea un archivo semana6_ejemplo2_espectros_sinteticos.py
Pega el código:
import cv2
import numpy as np
import [Link] as plt
def calcular_y_mostrar_espectro(imagen, titulo_imagen):
"""Función auxiliar para calcular y mostrar una imagen y su
espectro."""
dft = [Link].fft2(imagen)
dft_shift = [Link](dft)
magnitud_espectro_log = [Link](1 + [Link](dft_shift))
[Link](1, 2, 1)
[Link](imagen, cmap='gray')
[Link](titulo_imagen)
[Link]('off')
[Link](1, 2, 2)
[Link](magnitud_espectro_log, cmap='gray')
[Link]('Espectro de Magnitud (Log)')
[Link]('off')
[Link]()
# --- Crear imágenes sintéticas ---
img_size = 256
# 1. Imagen con una línea horizontal
img_linea_h = [Link]((img_size, img_size), dtype=np.uint8)
img_linea_h[img_size // 2 - 2 : img_size // 2 + 2, :] = 255 # Línea
más gruesa
# 2. Imagen con una línea vertical
img_linea_v = [Link]((img_size, img_size), dtype=np.uint8)
img_linea_v[:, img_size // 2 - 2 : img_size // 2 + 2] = 255 # Línea
más gruesa
# 3. Imagen con un rectángulo (representa bordes horizontales y
verticales)
img_rect = [Link]((img_size, img_size), dtype=np.uint8)
[Link](img_rect, (img_size//4, img_size//4), (img_size*3//4,
img_size*3//4), 255, -1)
print("Mostrando espectros de imágenes sintéticas...")
[Link](figsize=(10, 5))
calcular_y_mostrar_espectro(img_linea_h, 'Línea Horizontal')
[Link](figsize=(10, 5))
calcular_y_mostrar_espectro(img_linea_v, 'Línea Vertical')
[Link](figsize=(10, 5))
calcular_y_mostrar_espectro(img_rect, 'Rectángulo Sólido')
Guarda y ejecuta. Observa las siguientes relaciones (esto es
clave):
o Línea horizontal en la imagen espacial: Se manifiesta
como una línea vertical brillante en el espectro de
magnitud (pasando por el centro).
o Línea vertical en la imagen espacial: Se manifiesta
como una línea horizontal brillante en el espectro.
o Rectángulo (bordes H y V): Produce líneas horizontales
y verticales en el espectro.
Esto ayuda a entender que las orientaciones en el dominio
espacial se reflejan de manera perpendicular en el dominio de
la frecuencia.
Ejemplo 3: Espectro de Imagen Nítida vs. Imagen Fuertemente
Desenfocada (Efecto Intenso)
Crea un archivo semana6_ejemplo3_nitida_vs_desenfocada.py.
Pega el código:
import cv2
import numpy as np
import [Link] as plt
def obtener_espectro_log(imagen_gris):
dft = [Link].fft2(imagen_gris)
dft_shift = [Link](dft)
magnitud_espectro_log = [Link](1 + [Link](dft_shift))
return magnitud_espectro_log
# Cargar imagen original
ruta_imagen = 'imagen_prueba.jpg' # Una imagen con buenos detalles
imagen_original_gris = [Link](ruta_imagen,
cv2.IMREAD_GRAYSCALE)
if imagen_original_gris is None:
print(f"Error al cargar {ruta_imagen}.")
else:
print("Imagen original cargada.")
# --- Crear una versión MUY desenfocada ---
# Usar un kernel Gaussiano grande y un sigma alto para un
efecto intenso
kernel_size_desenfoque = (31, 31) # Kernel grande
sigma_desenfoque = 15 # Sigma alto
imagen_muy_desenfocada = [Link](imagen_original_gris,
kernel_size_desenfoque, sigma_desenfoque)
print(f"Versión fuertemente desenfocada creada con kernel
{kernel_size_desenfoque}, sigma {sigma_desenfoque}.")
# --- Calcular espectros ---
espectro_original = obtener_espectro_log(imagen_original_gris)
espectro_desenfocado =
obtener_espectro_log(imagen_muy_desenfocada)
print("Espectros calculados.")
# --- Visualización ---
[Link](figsize=(18, 12))
[Link](2, 2, 1)
[Link](imagen_original_gris, cmap='gray')
[Link]('Imagen Original Nítida')
[Link]('off')
[Link](2, 2, 2)
[Link](espectro_original, cmap='gray')
[Link]('Espectro de la Imagen Nítida')
[Link]('off')
[Link](2, 2, 3)
[Link](imagen_muy_desenfocada, cmap='gray')
[Link](f'Imagen Muy Desenfocada (k={kernel_size_desenfoque},
σ={sigma_desenfoque})')
[Link]('off')
[Link](2, 2, 4)
[Link](espectro_desenfocado, cmap='gray')
[Link]('Espectro de la Imagen Desenfocada')
[Link]('off')
[Link]('Comparación de Espectros: Nítida vs. Fuertemente
Desenfocada', fontsize=16)
plt.tight_layout()
plt.subplots_adjust(top=0.93)
[Link]()
print("\nObservaciones Clave:")
print("- El espectro de la imagen nítida tiene más energía en
las altas frecuencias (partes exteriores del espectro).")
print("- El espectro de la imagen MUY desenfocada tiene sus
altas frecuencias significativamente atenuadas.")
print("Esto demuestra que el desenfoque (suavizado) es una
operación de paso bajo en frecuencia.")
Guarda y ejecuta. El efecto será claro: el espectro de la imagen
muy desenfocada tendrá las componentes de alta frecuencia
(las partes exteriores del espectro visualizado) mucho más
oscuras que el de la imagen nítida. Esto ilustra que el
desenfoque elimina las altas frecuencias.
Ejemplo 4: Transformada Inversa de Fourier y la Importancia
de la Fase (Efecto Intenso)
Crea un archivo semana6_ejemplo4_idft_fase.py.
Pega el código:
import cv2
import numpy as np
import [Link] as plt
# Cargar imagen en escala de grises
ruta_imagen = 'imagen_prueba.jpg'
imagen_gris = [Link](ruta_imagen, cv2.IMREAD_GRAYSCALE)
if imagen_gris is None:
print(f"Error al cargar {ruta_imagen}.")
else:
print("Imagen original cargada.")
# --- Calcular DFT y componentes ---
dft = [Link].fft2(imagen_gris)
dft_shift = [Link](dft) # DFT centrada
magnitud = [Link](dft_shift)
fase = [Link](dft_shift)
print("DFT, magnitud y fase calculadas.")
# --- Reconstrucción Perfecta (usando magnitud y fase
originales) ---
# Combinar magnitud y fase para obtener de nuevo los números
complejos
# F = M * e^(j*P) donde M es magnitud, P es fase, j es unidad
imaginaria
dft_reconstruida_desde_componentes = magnitud * [Link](1j *
fase)
# Deshacer el centrado
f_ishift_perfecta =
[Link](dft_reconstruida_desde_componentes)
# Aplicar la Transformada Inversa de Fourier
img_reconstruida_perfecta_complex =
[Link].ifft2(f_ishift_perfecta)
# Tomar la parte real (o magnitud, aunque real suele ser mejor
si no hay errores)
img_reconstruida_perfecta =
[Link](img_reconstruida_perfecta_complex)
# Opcionalmente, [Link](img_reconstruida_perfecta_complex)
print("Imagen reconstruida perfectamente desde magnitud y fase
originales.")
# --- Reconstrucción con Fase Aleatoria (Efecto Intenso) ---
# Usaremos la magnitud original, pero una fase completamente
aleatoria
fase_aleatoria = [Link](-[Link], [Link], [Link]) #
Fase entre -pi y pi
dft_con_fase_aleatoria = magnitud * [Link](1j * fase_aleatoria)
# Deshacer el centrado
f_ishift_fase_aleatoria =
[Link](dft_con_fase_aleatoria)
# Aplicar IDFT
img_fase_aleatoria_complex =
[Link].ifft2(f_ishift_fase_aleatoria)
img_fase_aleatoria = [Link](img_fase_aleatoria_complex)
print("Imagen reconstruida usando magnitud original y FASE
ALEATORIA.")
# --- Visualización ---
[Link](figsize=(18, 12))
[Link](2, 2, 1)
[Link](imagen_gris, cmap='gray')
[Link]('Imagen Original')
[Link]('off')
[Link](2, 2, 2)
[Link]([Link](1 + magnitud), cmap='gray') # Magnitud
original
[Link]('Espectro de Magnitud Original (Log)')
[Link]('off')
[Link](2, 2, 3)
[Link](img_reconstruida_perfecta, cmap='gray')
[Link]('Reconstrucción Perfecta (Mag+Fase Orig.)')
[Link]('off')
[Link](2, 2, 4)
[Link](img_fase_aleatoria, cmap='gray')
[Link]('Reconstrucción (Mag Orig. + FASE ALEATORIA)')
[Link]('off')
[Link]('Importancia de la Fase en la Reconstrucción
IDFT', fontsize=16)
plt.tight_layout()
plt.subplots_adjust(top=0.93)
[Link]()
print("\nConclusión Impactante:")
print("- La reconstrucción perfecta muestra que DFT/IDFT son
procesos reversibles.")
print("- ¡La imagen reconstruida con fase aleatoria (pero
magnitud original) es irreconocible!")
print("Esto demuestra que la FASE contiene la mayor parte de la
información ESTRUCTURAL de la imagen.")
Guarda y ejecuta. La imagen reconstruida perfectamente
debería ser casi idéntica a la original. Sin embargo, la imagen
reconstruida usando la magnitud original pero una fase
completamente aleatoria se verá como ruido ininteligible. Este
es un resultado muy intenso y visualmente claro de la
importancia crítica de la información de fase.
III. Resumen y Próximos Pasos
Hoy dimos nuestros primeros pasos en el dominio de la
frecuencia:
o Entendimos que una imagen puede representarse como
una suma de ondas de diferentes frecuencias.
o Aprendimos a calcular la DFT 2D y a visualizar su
espectro de magnitud (centrado y en escala
logarítmica), que nos muestra la "cantidad" de cada
frecuencia.
o Vimos cómo diferentes contenidos de imagen (líneas,
rectángulos, imágenes nítidas vs. muy borrosas) producen
diferentes espectros.
o Demostramos la IDFT para reconstruir la imagen y,
crucialmente, vimos con un ejemplo muy intenso que la
información de fase es esencial para la estructura
espacial de la imagen, mucho más que la magnitud sola.
o Introdujimos conceptualmente la idea de filtrar en el
dominio de la frecuencia multiplicando la DFT por un
filtro.